v1-0004-Add-role-attributes-INHERITCREATEDROLES-and-SETCR.patch
application/octet-stream
Filename: v1-0004-Add-role-attributes-INHERITCREATEDROLES-and-SETCR.patch
Type: application/octet-stream
Part: 0
Message:
fixing CREATEROLE
Patch
Format: format-patch
Series: patch v1-0004
Subject: Add role attributes INHERITCREATEDROLES and SETCREATEDROLES.
| File | + | − |
|---|---|---|
| src/backend/commands/user.c | 63 | 3 |
| src/backend/parser/gram.y | 8 | 0 |
| src/include/catalog/pg_authid.dat | 26 | 13 |
| src/include/catalog/pg_authid.h | 2 | 0 |
From 8e12d14ee01ef00ebb1b044449809ff593bfd580 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Fri, 18 Nov 2022 16:03:06 -0500
Subject: [PATCH v1 4/4] Add role attributes INHERITCREATEDROLES and
SETCREATEDROLES.
These control whether the implicit grants created when a
CREATEROLE user creates a new role are marked with the
inherit and set options respectively.
FIXME: Add some regression tests.
FIXME: Add documentation.
FIXME: REMEMBER TO BUMP THE CATALOG VERSION
---
src/backend/commands/user.c | 66 +++++++++++++++++++++++++++++--
src/backend/parser/gram.y | 8 ++++
src/include/catalog/pg_authid.dat | 39 ++++++++++++------
src/include/catalog/pg_authid.h | 2 +
4 files changed, 99 insertions(+), 16 deletions(-)
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 1bfc42a157..599d545363 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -141,6 +141,8 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
bool issuper = false; /* Make the user a superuser? */
bool inherit = true; /* Auto inherit privileges? */
bool createrole = false; /* Can this user create roles? */
+ bool inheritcreatedroles = false; /* inherit any created roles? */
+ bool setcreatedroles = false; /* set role to any created roles? */
bool createdb = false; /* Can the user create databases? */
bool canlogin = false; /* Can this user login? */
bool isreplication = false; /* Is this a replication role? */
@@ -156,6 +158,8 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
DefElem *dissuper = NULL;
DefElem *dinherit = NULL;
DefElem *dcreaterole = NULL;
+ DefElem *dinheritcreatedroles = NULL;
+ DefElem *dsetcreatedroles = NULL;
DefElem *dcreatedb = NULL;
DefElem *dcanlogin = NULL;
DefElem *disreplication = NULL;
@@ -214,6 +218,18 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
errorConflictingDefElem(defel, pstate);
dcreaterole = defel;
}
+ else if (strcmp(defel->defname, "inheritcreatedroles") == 0)
+ {
+ if (dinheritcreatedroles)
+ errorConflictingDefElem(defel, pstate);
+ dinheritcreatedroles = defel;
+ }
+ else if (strcmp(defel->defname, "setcreatedroles") == 0)
+ {
+ if (dsetcreatedroles)
+ errorConflictingDefElem(defel, pstate);
+ dsetcreatedroles = defel;
+ }
else if (strcmp(defel->defname, "createdb") == 0)
{
if (dcreatedb)
@@ -281,6 +297,10 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
inherit = boolVal(dinherit->arg);
if (dcreaterole)
createrole = boolVal(dcreaterole->arg);
+ if (dinheritcreatedroles)
+ inheritcreatedroles = boolVal(dinheritcreatedroles->arg);
+ if (dsetcreatedroles)
+ setcreatedroles = boolVal(dsetcreatedroles->arg);
if (dcreatedb)
createdb = boolVal(dcreatedb->arg);
if (dcanlogin)
@@ -402,6 +422,10 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);
new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
+ new_record[Anum_pg_authid_rolinheritcreatedroles - 1] =
+ BoolGetDatum(inheritcreatedroles);
+ new_record[Anum_pg_authid_rolsetcreatedroles - 1] =
+ BoolGetDatum(setcreatedroles);
new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication);
@@ -531,18 +555,28 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
*/
if (!superuser())
{
- RoleSpec *current_role = makeNode(RoleSpec);
+ RoleSpec *current_role;
+ HeapTuple utup;
+ Form_pg_authid uform;
GrantRoleOptions poptself;
+ current_role = makeNode(RoleSpec);
current_role->roletype = ROLESPEC_CURRENT_ROLE;
current_role->location = -1;
+ utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
+ if (!HeapTupleIsValid(utup))
+ elog(LOG, "cache lookup failed for role %u", GetUserId());
+ uform = (Form_pg_authid) GETSTRUCT(utup);
+
poptself.specified = GRANT_ROLE_SPECIFIED_ADMIN
| GRANT_ROLE_SPECIFIED_INHERIT
| GRANT_ROLE_SPECIFIED_SET;
poptself.admin = true;
- poptself.inherit = false;
- poptself.set = false;
+ poptself.inherit = uform->rolinheritcreatedroles;
+ poptself.set = uform->rolsetcreatedroles;
+
+ ReleaseSysCache(utup);
AddRoleMems(BOOTSTRAP_SUPERUSERID, stmt->role, roleid,
list_make1(current_role), list_make1_oid(GetUserId()),
@@ -612,6 +646,8 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
DefElem *dissuper = NULL;
DefElem *dinherit = NULL;
DefElem *dcreaterole = NULL;
+ DefElem *dinheritcreatedroles = NULL;
+ DefElem *dsetcreatedroles = NULL;
DefElem *dcreatedb = NULL;
DefElem *dcanlogin = NULL;
DefElem *disreplication = NULL;
@@ -655,6 +691,18 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
errorConflictingDefElem(defel, pstate);
dcreaterole = defel;
}
+ else if (strcmp(defel->defname, "inheritcreatedroles") == 0)
+ {
+ if (dinheritcreatedroles)
+ errorConflictingDefElem(defel, pstate);
+ dinheritcreatedroles = defel;
+ }
+ else if (strcmp(defel->defname, "setcreatedroles") == 0)
+ {
+ if (dsetcreatedroles)
+ errorConflictingDefElem(defel, pstate);
+ dsetcreatedroles = defel;
+ }
else if (strcmp(defel->defname, "createdb") == 0)
{
if (dcreatedb)
@@ -841,6 +889,18 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
}
+ if (dinheritcreatedroles)
+ {
+ new_record[Anum_pg_authid_rolinheritcreatedroles - 1] = BoolGetDatum(boolVal(dinheritcreatedroles->arg));
+ new_record_repl[Anum_pg_authid_rolinheritcreatedroles - 1] = true;
+ }
+
+ if (dsetcreatedroles)
+ {
+ new_record[Anum_pg_authid_rolsetcreatedroles - 1] = BoolGetDatum(boolVal(dsetcreatedroles->arg));
+ new_record_repl[Anum_pg_authid_rolsetcreatedroles - 1] = true;
+ }
+
if (dcreatedb)
{
new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(boolVal(dcreatedb->arg));
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9384214942..0d6bdf1531 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1206,6 +1206,14 @@ AlterOptRoleElem:
$$ = makeDefElem("createrole", (Node *) makeBoolean(true), @1);
else if (strcmp($1, "nocreaterole") == 0)
$$ = makeDefElem("createrole", (Node *) makeBoolean(false), @1);
+ else if (strcmp($1, "inheritcreatedroles") == 0)
+ $$ = makeDefElem("inheritcreatedroles", (Node *) makeBoolean(true), @1);
+ else if (strcmp($1, "noinheritcreatedroles") == 0)
+ $$ = makeDefElem("inheritcreatedroles", (Node *) makeBoolean(false), @1);
+ else if (strcmp($1, "setcreatedroles") == 0)
+ $$ = makeDefElem("setcreatedroles", (Node *) makeBoolean(true), @1);
+ else if (strcmp($1, "nosetcreatedroles") == 0)
+ $$ = makeDefElem("setcreatedroles", (Node *) makeBoolean(false), @1);
else if (strcmp($1, "replication") == 0)
$$ = makeDefElem("isreplication", (Node *) makeBoolean(true), @1);
else if (strcmp($1, "noreplication") == 0)
diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat
index 3343a69ddb..79390240ca 100644
--- a/src/include/catalog/pg_authid.dat
+++ b/src/include/catalog/pg_authid.dat
@@ -21,67 +21,80 @@
{ oid => '10', oid_symbol => 'BOOTSTRAP_SUPERUSERID',
rolname => 'POSTGRES', rolsuper => 't', rolinherit => 't',
- rolcreaterole => 't', rolcreatedb => 't', rolcanlogin => 't',
+ rolcreaterole => 't', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 't', rolcanlogin => 't',
rolreplication => 't', rolbypassrls => 't', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '6171', oid_symbol => 'ROLE_PG_DATABASE_OWNER',
rolname => 'pg_database_owner', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '6181', oid_symbol => 'ROLE_PG_READ_ALL_DATA',
rolname => 'pg_read_all_data', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '6182', oid_symbol => 'ROLE_PG_WRITE_ALL_DATA',
rolname => 'pg_write_all_data', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '3373', oid_symbol => 'ROLE_PG_MONITOR',
rolname => 'pg_monitor', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '3374', oid_symbol => 'ROLE_PG_READ_ALL_SETTINGS',
rolname => 'pg_read_all_settings', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '3375', oid_symbol => 'ROLE_PG_READ_ALL_STATS',
rolname => 'pg_read_all_stats', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '3377', oid_symbol => 'ROLE_PG_STAT_SCAN_TABLES',
rolname => 'pg_stat_scan_tables', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4569', oid_symbol => 'ROLE_PG_READ_SERVER_FILES',
rolname => 'pg_read_server_files', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4570', oid_symbol => 'ROLE_PG_WRITE_SERVER_FILES',
rolname => 'pg_write_server_files', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4571', oid_symbol => 'ROLE_PG_EXECUTE_SERVER_PROGRAM',
rolname => 'pg_execute_server_program', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4200', oid_symbol => 'ROLE_PG_SIGNAL_BACKEND',
rolname => 'pg_signal_backend', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4544', oid_symbol => 'ROLE_PG_CHECKPOINT',
rolname => 'pg_checkpoint', rolsuper => 'f', rolinherit => 't',
- rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolcreaterole => 'f', rolinheritcreatedroles => 't',
+ rolsetcreatedroles => 't', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
index 3512601c80..83fca311ed 100644
--- a/src/include/catalog/pg_authid.h
+++ b/src/include/catalog/pg_authid.h
@@ -35,6 +35,8 @@ CATALOG(pg_authid,1260,AuthIdRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(284
bool rolsuper; /* read this field via superuser() only! */
bool rolinherit; /* inherit privileges from other roles? */
bool rolcreaterole; /* allowed to create more roles? */
+ bool rolinheritcreatedroles; /* if creates role, inherit it? */
+ bool rolsetcreatedroles; /* if creates role, set role to it? */
bool rolcreatedb; /* allowed to create databases? */
bool rolcanlogin; /* allowed to log in as session user? */
bool rolreplication; /* role used for streaming replication */
--
2.24.3 (Apple Git-128)