mirror of
https://github.com/hashicorp/vault.git
synced 2025-11-28 14:11:10 +01:00
Fix bug preventing multiline statemtents in rotation_statements for database static roles (#31442)
* added multiline unit test to replicate error & eventual fix * create changelog * move multiline statement test above the bad statements test for consistency. * Add support for multiline statements in changeUserPassword * Update expiration multi-line statements * pr fixes
This commit is contained in:
parent
c88b3136a6
commit
a0f8dab6a9
3
changelog/31442.txt
Normal file
3
changelog/31442.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
```release-note:bug
|
||||||
|
secrets/database/postgresql: Support for multiline statements in the `rotation_statements` field.
|
||||||
|
```
|
||||||
@ -270,6 +270,28 @@ func (p *PostgreSQL) changeUserPassword(ctx context.Context, username string, ch
|
|||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
for _, stmt := range stmts {
|
for _, stmt := range stmts {
|
||||||
|
if containsMultilineStatement(stmt) {
|
||||||
|
// Execute it as-is.
|
||||||
|
m := map[string]string{
|
||||||
|
"name": username,
|
||||||
|
"username": username,
|
||||||
|
"password": password,
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.passwordAuthentication == passwordAuthenticationSCRAMSHA256 {
|
||||||
|
hashedPassword, err := scram.Hash(password)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to scram-sha256 password: %w", err)
|
||||||
|
}
|
||||||
|
m["password"] = hashedPassword
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbtxn.ExecuteTxQueryDirect(ctx, tx, m, stmt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Otherwise, it's fine to split the statements on the semicolon.
|
||||||
for _, query := range strutil.ParseArbitraryStringSlice(stmt, ";") {
|
for _, query := range strutil.ParseArbitraryStringSlice(stmt, ";") {
|
||||||
query = strings.TrimSpace(query)
|
query = strings.TrimSpace(query)
|
||||||
if len(query) == 0 {
|
if len(query) == 0 {
|
||||||
@ -337,6 +359,19 @@ func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string,
|
|||||||
expirationStr := changeExp.NewExpiration.Format(expirationFormat)
|
expirationStr := changeExp.NewExpiration.Format(expirationFormat)
|
||||||
|
|
||||||
for _, stmt := range renewStmts {
|
for _, stmt := range renewStmts {
|
||||||
|
if containsMultilineStatement(stmt) {
|
||||||
|
// Execute it as-is.
|
||||||
|
m := map[string]string{
|
||||||
|
"name": username,
|
||||||
|
"username": username,
|
||||||
|
"expiration": expirationStr,
|
||||||
|
}
|
||||||
|
if err := dbtxn.ExecuteTxQueryDirect(ctx, tx, m, stmt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Otherwise, it's fine to split the statements on the semicolon.
|
||||||
for _, query := range strutil.ParseArbitraryStringSlice(stmt, ";") {
|
for _, query := range strutil.ParseArbitraryStringSlice(stmt, ";") {
|
||||||
query = strings.TrimSpace(query)
|
query = strings.TrimSpace(query)
|
||||||
if len(query) == 0 {
|
if len(query) == 0 {
|
||||||
|
|||||||
@ -1063,6 +1063,17 @@ func TestUpdateUser_Password(t *testing.T) {
|
|||||||
expectErr: false,
|
expectErr: false,
|
||||||
credsAssertion: assertCredsExist,
|
credsAssertion: assertCredsExist,
|
||||||
},
|
},
|
||||||
|
"multi-line statements": {
|
||||||
|
statements: []string{
|
||||||
|
`DO $$ BEGIN
|
||||||
|
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname='{{name}}')
|
||||||
|
THEN CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}';
|
||||||
|
ELSE ALTER ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}';
|
||||||
|
END IF; END $$`,
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
|
credsAssertion: assertCredsExist,
|
||||||
|
},
|
||||||
"bad statements": {
|
"bad statements": {
|
||||||
statements: []string{`asdofyas8uf77asoiajv`},
|
statements: []string{`asdofyas8uf77asoiajv`},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
@ -1205,6 +1216,17 @@ func TestUpdateUser_Expiration(t *testing.T) {
|
|||||||
statements: []string{`ALTER ROLE "{{username}}" VALID UNTIL '{{expiration}}';`},
|
statements: []string{`ALTER ROLE "{{username}}" VALID UNTIL '{{expiration}}';`},
|
||||||
expectErr: false,
|
expectErr: false,
|
||||||
},
|
},
|
||||||
|
"multi-line statements": {
|
||||||
|
initialExpiration: now.Add(1 * time.Minute),
|
||||||
|
newExpiration: now.Add(5 * time.Minute),
|
||||||
|
expectedExpiration: now.Add(5 * time.Minute),
|
||||||
|
statements: []string{
|
||||||
|
`DO $$ BEGIN
|
||||||
|
ALTER ROLE "{{name}}" VALID UNTIL '{{expiration}}';
|
||||||
|
END $$`,
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
"bad statements": {
|
"bad statements": {
|
||||||
initialExpiration: now.Add(1 * time.Minute),
|
initialExpiration: now.Add(1 * time.Minute),
|
||||||
newExpiration: now.Add(5 * time.Minute),
|
newExpiration: now.Add(5 * time.Minute),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user