Skip to content

Commit a685bfb

Browse files
craig[bot]kaustubhbabar5
andcommitted
Merge #130547
130547: sql: allow DB owner to set session var defaults in database r=rafiss a=kaustubhbabar5 Fixes: #123287 Release note (sql change): The owner of a database can now set default session variables per database using the `ALTER ROLE ALL IN DATABASE ... SET` or `ALTER DATABASE ... SET` commands. Co-authored-by: Kaustubh Babar <[email protected]>
2 parents 899c462 + 2b97659 commit a685bfb

File tree

2 files changed

+93
-15
lines changed

2 files changed

+93
-15
lines changed

pkg/sql/alter_role.go

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/cockroachdb/cockroach/pkg/security/username"
1414
"github.com/cockroachdb/cockroach/pkg/settings"
15+
"github.com/cockroachdb/cockroach/pkg/sql/catalog"
1516
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
1617
"github.com/cockroachdb/cockroach/pkg/sql/decodeusername"
1718
"github.com/cockroachdb/cockroach/pkg/sql/paramparse"
@@ -288,8 +289,23 @@ func (*alterRoleNode) Values() tree.Datums { return tree.Datums{} }
288289
func (*alterRoleNode) Close(context.Context) {}
289290

290291
// AlterRoleSet represents a `ALTER ROLE ... SET` statement.
291-
// Privileges: CREATEROLE, MODIFYCLUSTERSETTING, MODIFYSQLCLUSTERSETTING privilege; or admin-only if `ALTER ROLE ALL`.
292+
//
293+
// Privileges:
294+
//
295+
// - CREATEROLE, MODIFYCLUSTERSETTING, MODIFYSQLCLUSTERSETTING privilege;
296+
// - admin-only if `ALTER ROLE ALL`;
297+
// - database owner or admin if `ALTER ROLE ALL IN DATABASE SET ...`
292298
func (p *planner) AlterRoleSet(ctx context.Context, n *tree.AlterRoleSet) (planNode, error) {
299+
dbDescID := descpb.ID(0)
300+
var dbDesc catalog.DatabaseDescriptor
301+
if n.DatabaseName != "" {
302+
var err error
303+
dbDesc, err = p.Descriptors().ByNameWithLeased(p.txn).Get().Database(ctx, string(n.DatabaseName))
304+
if err != nil {
305+
return nil, err
306+
}
307+
dbDescID = dbDesc.GetID()
308+
}
293309
// Note that for Postgres, only superuser can ALTER another superuser.
294310
// CockroachDB does not support the superuser role option right now.
295311
// However we make it so members of the ADMIN role can only be edited
@@ -298,11 +314,25 @@ func (p *planner) AlterRoleSet(ctx context.Context, n *tree.AlterRoleSet) (planN
298314
// modifying their own defaults unless they have CREATEROLE. This is analogous
299315
// to our restriction that prevents a user from modifying their own password.
300316
if n.AllRoles {
301-
if hasAdmin, err := p.HasAdminRole(ctx); err != nil {
317+
hasAdmin, err := p.HasAdminRole(ctx)
318+
if err != nil {
302319
return nil, err
303-
} else if !hasAdmin {
304-
return nil, pgerror.Newf(pgcode.InsufficientPrivilege,
305-
"only users with the admin role are allowed to ALTER ROLE ALL ... SET")
320+
}
321+
if !hasAdmin {
322+
if dbDesc == nil {
323+
return nil, pgerror.Newf(pgcode.InsufficientPrivilege,
324+
"only users with the admin role are allowed to ALTER ROLE ALL ... SET")
325+
}
326+
// If the user is not an admin, they must be the owner of the database if
327+
// ALL IN DATABASE ... is used
328+
isDBOwner, err := p.HasOwnership(ctx, dbDesc)
329+
if err != nil {
330+
return nil, err
331+
}
332+
if !isDBOwner {
333+
return nil, pgerror.Newf(pgcode.InsufficientPrivilege,
334+
"only users with the admin role or the owner of the database is allowed to ALTER ROLE ALL IN DATABASE SET ...")
335+
}
306336
}
307337
} else {
308338
canAlterRoleSet, err := p.HasGlobalPrivilegeOrRoleOption(ctx, privilege.CREATEROLE)
@@ -337,15 +367,6 @@ func (p *planner) AlterRoleSet(ctx context.Context, n *tree.AlterRoleSet) (planN
337367
}
338368
}
339369

340-
dbDescID := descpb.ID(0)
341-
if n.DatabaseName != "" {
342-
dbDesc, err := p.Descriptors().ByNameWithLeased(p.txn).Get().Database(ctx, string(n.DatabaseName))
343-
if err != nil {
344-
return nil, err
345-
}
346-
dbDescID = dbDesc.GetID()
347-
}
348-
349370
setVarKind, varName, sVar, typedValues, err := p.processSetOrResetClause(ctx, n.SetOrReset)
350371
if err != nil {
351372
return nil, err

pkg/sql/logictest/testdata/logic_test/alter_role_set

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ statement ok
214214
ALTER ROLE test_set_role RESET application_name
215215

216216
# However, even with CREATEROLE, testuser cannot do RESET ALL.
217-
statement error only users with the admin role are allowed to ALTER ROLE ALL
217+
statement error only users with the admin role or the owner of the database is allowed to ALTER ROLE ALL IN DATABASE SET ..
218218
ALTER ROLE ALL IN DATABASE test_set_db RESET application_name
219219

220220
# Verify that testuser can't edit an ADMIN, even after getting CREATEROLE.
@@ -374,3 +374,60 @@ use_declarative_schema_changer off NULL true
374374
# We shouldn't be able to leave the role unspecified
375375
statement error pq: at or near "]": syntax error
376376
SELECT * FROM [SHOW DEFAULT SESSION VARIABLES FOR ROLE]
377+
378+
statement ok
379+
CREATE USER testuser2
380+
381+
# Set owner to a user that is not admin.
382+
statement ok
383+
ALTER DATABASE test_db OWNER TO testuser2
384+
385+
user testuser2
386+
387+
# Verify that owner can set default session variables for a database.
388+
statement ok
389+
ALTER ROLE ALL IN DATABASE test_db SET application_name = 'abc'
390+
391+
user root
392+
393+
query TTT
394+
SELECT * FROM [SHOW DEFAULT SESSION VARIABLES FOR ROLE ALL] WHERE database='test_db' ORDER BY 1, 2
395+
----
396+
application_name abc test_db
397+
398+
user testuser2
399+
400+
# Verify that DB owner can reset default session variables for a database.
401+
statement ok
402+
ALTER ROLE ALL IN DATABASE test_db RESET application_name
403+
404+
user root
405+
406+
query TTT colnames
407+
SELECT * FROM [SHOW DEFAULT SESSION VARIABLES FOR ROLE ALL] WHERE database='test_db' ORDER BY 1, 2
408+
----
409+
session_variables default_values database
410+
411+
statement ok
412+
CREATE DATABASE test_db2
413+
414+
user testuser2
415+
416+
# Verify that DB owner cannot set default session variables for a database that they do not own.
417+
statement error only users with the admin role or the owner of the database is allowed to ALTER ROLE ALL IN DATABASE SET
418+
ALTER ROLE ALL IN DATABASE test_db2 SET application_name = 'abc'
419+
420+
user root
421+
422+
statement ok
423+
DROP DATABASE test_db2
424+
425+
user testuser2
426+
427+
# Verify that DB owner cannot alter a specific role.
428+
statement error pq: ALTER ROLE ... SET requires MODIFYCLUSTERSETTING, MODIFYSQLCLUSTERSETTING or CREATEROLE
429+
ALTER ROLE roach IN DATABASE test_db SET application_name = 'abc'
430+
431+
# Verify that DB owner cannot ALTER ROLE ALL.
432+
statement error pq: only users with the admin role are allowed to ALTER ROLE ALL ... SET
433+
ALTER ROLE ALL SET application_name = 'abc'

0 commit comments

Comments
 (0)