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()
|
||||
|
||||
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, ";") {
|
||||
query = strings.TrimSpace(query)
|
||||
if len(query) == 0 {
|
||||
@ -337,6 +359,19 @@ func (p *PostgreSQL) changeUserExpiration(ctx context.Context, username string,
|
||||
expirationStr := changeExp.NewExpiration.Format(expirationFormat)
|
||||
|
||||
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, ";") {
|
||||
query = strings.TrimSpace(query)
|
||||
if len(query) == 0 {
|
||||
|
||||
@ -1063,6 +1063,17 @@ func TestUpdateUser_Password(t *testing.T) {
|
||||
expectErr: false,
|
||||
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": {
|
||||
statements: []string{`asdofyas8uf77asoiajv`},
|
||||
expectErr: true,
|
||||
@ -1205,6 +1216,17 @@ func TestUpdateUser_Expiration(t *testing.T) {
|
||||
statements: []string{`ALTER ROLE "{{username}}" VALID UNTIL '{{expiration}}';`},
|
||||
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": {
|
||||
initialExpiration: now.Add(1 * time.Minute),
|
||||
newExpiration: now.Add(5 * time.Minute),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user