Skip to content

Commit

Permalink
database/mysql: Allow the creation statement to use commands that are… (
Browse files Browse the repository at this point in the history
#3619)

* database/mysql: Allow the creation statement to use commands that are not yet supported by the prepare statement protocol

* Remove unnecessary else block
  • Loading branch information
briankassouf committed Nov 28, 2017
1 parent d3a2844 commit 98a644c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
23 changes: 19 additions & 4 deletions plugins/database/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
"time"

_ "github.com/go-sql-driver/mysql"
stdmysql "github.com/go-sql-driver/mysql"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
"github.com/hashicorp/vault/helper/strutil"
Expand Down Expand Up @@ -140,13 +140,28 @@ func (m *MySQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplug
if len(query) == 0 {
continue
}

stmt, err := tx.Prepare(dbutil.QueryHelper(query, map[string]string{
query = dbutil.QueryHelper(query, map[string]string{
"name": username,
"password": password,
"expiration": expirationStr,
}))
})

stmt, err := tx.Prepare(query)
if err != nil {
// If the error code we get back is Error 1295: This command is not
// supported in the prepared statement protocol yet, we will execute
// the statement without preparing it. This allows the caller to
// manually prepare statements, as well as run other not yet
// prepare supported commands. If there is no error when running we
// will continue to the next statement.
if e, ok := err.(*stdmysql.MySQLError); ok && e.Number == 1295 {
_, err = tx.Exec(query)
if err != nil {
return "", "", err
}
continue
}

return "", "", err
}
defer stmt.Close()
Expand Down
20 changes: 20 additions & 0 deletions plugins/database/mysql/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,19 @@ func TestMySQL_CreateUser(t *testing.T) {
if err := testCredsExist(t, connURL, username, password); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}

// Test with a manualy prepare statement
statements.CreationStatements = testMySQLRolePreparedStmt

username, password, err = db.CreateUser(statements, usernameConfig, time.Now().Add(time.Minute))
if err != nil {
t.Fatalf("err: %s", err)
}

if err := testCredsExist(t, connURL, username, password); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}

}

func TestMySQL_CreateUser_Legacy(t *testing.T) {
Expand Down Expand Up @@ -316,6 +329,13 @@ func testCredsExist(t testing.TB, connURL, username, password string) error {
return db.Ping()
}

const testMySQLRolePreparedStmt = `
CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';
set @grants=CONCAT("GRANT SELECT ON ", "*", ".* TO '{{name}}'@'%'");
PREPARE grantStmt from @grants;
EXECUTE grantStmt;
DEALLOCATE PREPARE grantStmt;
`
const testMySQLRoleWildCard = `
CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';
GRANT SELECT ON *.* TO '{{name}}'@'%';
Expand Down

0 comments on commit 98a644c

Please sign in to comment.