mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 02:57:59 +00:00
database/mysql: Allow the creation statement to use commands that are… (#3619)
* database/mysql: Allow the creation statement to use commands that are not yet supported by the prepare statement protocol * Remove unnecessary else block
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
stdmysql "github.com/go-sql-driver/mysql"
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
|
"github.com/hashicorp/vault/builtin/logical/database/dbplugin"
|
||||||
"github.com/hashicorp/vault/helper/strutil"
|
"github.com/hashicorp/vault/helper/strutil"
|
||||||
@@ -140,13 +140,28 @@ func (m *MySQL) CreateUser(statements dbplugin.Statements, usernameConfig dbplug
|
|||||||
if len(query) == 0 {
|
if len(query) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
query = dbutil.QueryHelper(query, map[string]string{
|
||||||
stmt, err := tx.Prepare(dbutil.QueryHelper(query, map[string]string{
|
|
||||||
"name": username,
|
"name": username,
|
||||||
"password": password,
|
"password": password,
|
||||||
"expiration": expirationStr,
|
"expiration": expirationStr,
|
||||||
}))
|
})
|
||||||
|
|
||||||
|
stmt, err := tx.Prepare(query)
|
||||||
if err != nil {
|
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
|
return "", "", err
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|||||||
@@ -184,6 +184,19 @@ func TestMySQL_CreateUser(t *testing.T) {
|
|||||||
if err := testCredsExist(t, connURL, username, password); err != nil {
|
if err := testCredsExist(t, connURL, username, password); err != nil {
|
||||||
t.Fatalf("Could not connect with new credentials: %s", err)
|
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) {
|
func TestMySQL_CreateUser_Legacy(t *testing.T) {
|
||||||
@@ -316,6 +329,13 @@ func testCredsExist(t testing.TB, connURL, username, password string) error {
|
|||||||
return db.Ping()
|
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 = `
|
const testMySQLRoleWildCard = `
|
||||||
CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';
|
CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';
|
||||||
GRANT SELECT ON *.* TO '{{name}}'@'%';
|
GRANT SELECT ON *.* TO '{{name}}'@'%';
|
||||||
|
|||||||
Reference in New Issue
Block a user