saving role name to the Secret Internal data. Default revoke query added

The rolename is now saved to the secret internal data for fetching
later during the user revocation process. No longer deriving the role
name from request path

Added support for default revoke SQL statements that will provide the
same functionality as before. If not revoke SQL statements are provided
the default statements are used.

Cleaned up personal ignores from the .gitignore file
This commit is contained in:
Jim Weber 2016-10-02 18:53:16 -04:00
parent e0ea497cfe
commit dbb00534d9
4 changed files with 32 additions and 8 deletions

2
.gitignore vendored
View file

@ -60,5 +60,3 @@ tags
*.ipr *.ipr
*.iml *.iml
testsetup.sh

View file

@ -127,6 +127,7 @@ func (b *backend) pathRoleCreateRead(
"password": password, "password": password,
}, map[string]interface{}{ }, map[string]interface{}{
"username": username, "username": username,
"rolename": name,
}) })
resp.Secret.TTL = lease.Lease resp.Secret.TTL = lease.Lease
return resp, nil return resp, nil

View file

@ -2,6 +2,7 @@ package mysql
import ( import (
"fmt" "fmt"
"log"
"strings" "strings"
"github.com/hashicorp/vault/helper/strutil" "github.com/hashicorp/vault/helper/strutil"
@ -24,6 +25,11 @@ func secretCreds(b *backend) *framework.Secret {
Type: framework.TypeString, Type: framework.TypeString,
Description: "Password", Description: "Password",
}, },
"rolename": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Rolename",
},
}, },
Renew: b.secretCredsRenew, Renew: b.secretCredsRenew,
@ -63,17 +69,21 @@ func (b *backend) secretCredsRevoke(
} }
// Get the role // Get the role
pathParts := strings.Split(req.Path, "/") // pathParts := strings.Split(req.Path, "/")
if len(pathParts) < 1 { log.Println("InternalData")
return nil, fmt.Errorf("Role name could not be determined") log.Printf("%+v", req.Secret.InternalData)
rolenameRaw, ok := req.Secret.InternalData["rolename"]
if !ok {
return nil, fmt.Errorf("secret is missing rollname internal data")
} }
name := pathParts[len(pathParts)-1] rolename, ok := rolenameRaw.(string)
role, err := b.Role(req.Storage, name)
role, err := b.Role(req.Storage, rolename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if role == nil { if role == nil {
return logical.ErrorResponse(fmt.Sprintf("unknown role: %s", name)), nil return logical.ErrorResponse(fmt.Sprintf("unknown role: %s", rolename)), nil
} }
// Start a transaction // Start a transaction
@ -83,6 +93,12 @@ func (b *backend) secretCredsRevoke(
} }
defer tx.Rollback() defer tx.Rollback()
// Check for an empty revokeSQL string
// set it to a default query if the string is empty
if role.RevokeSQL == "" {
role.RevokeSQL = "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '" + username + "'@'%'; DROP USER '" + username + "'@'%'"
}
for _, query := range strutil.ParseArbitraryStringSlice(role.RevokeSQL, ";") { for _, query := range strutil.ParseArbitraryStringSlice(role.RevokeSQL, ";") {
query = strings.TrimSpace(query) query = strings.TrimSpace(query)
if len(query) == 0 { if len(query) == 0 {

9
testsetup.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
vault mount -description="RDS DEV" -path=rds.dev mysql
vault write rds.dev/config/connection connection_url="root:lco9Cwuoh64b97FW4nUL@tcp(rds.dev.crosschx.com:3306)/"
vault write rds.dev/config/lease lease=10s lease_max=24h
#vault write rds.dev/roles/identity-api-dev revoke_sql="REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'10.0.0.1'; DROP USER '{{name}}'@'10.0.0.1';" sql="CREATE USER '{{name}}'@'10.0.0.1' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'10.0.0.1';"
vault write rds.dev/roles/identity-api-dev sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';"
vault read rds.dev/roles/identity-api-dev
date ; vault read rds.dev/creds/identity-api-dev