From 8d5f7f330c0824c862a3c0d8ce5cd3d578e22d82 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 3 Jan 2022 09:37:12 +0100 Subject: [PATCH v3 1/3] Refactor AlterRole() Get rid of the three-valued logic for the Boolean variables to track whether the value was been specified and what the new value should be. Instead, we can use the "dfoo" variables to determine whether the value was specified and should be applied. This was already done in some cases, so this makes this more uniform and removes one layer of indirection. --- src/backend/commands/user.c | 97 +++++++++++++------------------------ 1 file changed, 35 insertions(+), 62 deletions(-) diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index aa69821be4..0aae87ff4a 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -501,20 +501,12 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) new_tuple; Form_pg_authid authform; ListCell *option; - char *rolename = NULL; + char *rolename; char *password = NULL; /* user password */ - int issuper = -1; /* Make the user a superuser? */ - int inherit = -1; /* Auto inherit privileges? */ - int createrole = -1; /* Can this user create roles? */ - int createdb = -1; /* Can the user create databases? */ - int canlogin = -1; /* Can this user login? */ - int isreplication = -1; /* Is this a replication role? */ int connlimit = -1; /* maximum connections allowed */ - List *rolemembers = NIL; /* roles to be added/removed */ char *validUntil = NULL; /* time the login is valid until */ Datum validUntil_datum; /* same, as timestamptz Datum */ bool validUntil_null; - int bypassrls = -1; DefElem *dpassword = NULL; DefElem *dissuper = NULL; DefElem *dinherit = NULL; @@ -610,18 +602,6 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) if (dpassword && dpassword->arg) password = strVal(dpassword->arg); - if (dissuper) - issuper = intVal(dissuper->arg); - if (dinherit) - inherit = intVal(dinherit->arg); - if (dcreaterole) - createrole = intVal(dcreaterole->arg); - if (dcreatedb) - createdb = intVal(dcreatedb->arg); - if (dcanlogin) - canlogin = intVal(dcanlogin->arg); - if (disreplication) - isreplication = intVal(disreplication->arg); if (dconnlimit) { connlimit = intVal(dconnlimit->arg); @@ -630,12 +610,8 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid connection limit: %d", connlimit))); } - if (drolemembers) - rolemembers = (List *) drolemembers->arg; if (dvalidUntil) validUntil = strVal(dvalidUntil->arg); - if (dbypassRLS) - bypassrls = intVal(dbypassRLS->arg); /* * Scan the pg_authid relation to be certain the user exists. @@ -654,21 +630,21 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) * property. Otherwise, if you don't have createrole, you're only allowed * to change your own password. */ - if (authform->rolsuper || issuper >= 0) + if (authform->rolsuper || dissuper) { if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to alter superuser roles or change superuser attribute"))); } - else if (authform->rolreplication || isreplication >= 0) + else if (authform->rolreplication || disreplication) { if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to alter replication roles or change replication attribute"))); } - else if (bypassrls >= 0) + else if (dbypassRLS) { if (!superuser()) ereport(ERROR, @@ -677,23 +653,16 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) } else if (!have_createrole_privilege()) { - /* We already checked issuper, isreplication, and bypassrls */ - if (!(inherit < 0 && - createrole < 0 && - createdb < 0 && - canlogin < 0 && - !dconnlimit && - !rolemembers && - !validUntil && - dpassword && - roleid == GetUserId())) + /* check the rest */ + if (dinherit || dcreaterole || dcreatedb || dcanlogin || dconnlimit || + drolemembers || dvalidUntil || !dpassword || roleid != GetUserId()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied"))); } /* Convert validuntil to internal form */ - if (validUntil) + if (dvalidUntil) { validUntil_datum = DirectFunctionCall3(timestamptz_in, CStringGetDatum(validUntil), @@ -729,39 +698,39 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) /* * issuper/createrole/etc */ - if (issuper >= 0) + if (dissuper) { - new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0); + new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(intVal(dissuper->arg)); new_record_repl[Anum_pg_authid_rolsuper - 1] = true; } - if (inherit >= 0) + if (dinherit) { - new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit > 0); + new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(intVal(dinherit->arg)); new_record_repl[Anum_pg_authid_rolinherit - 1] = true; } - if (createrole >= 0) + if (dcreaterole) { - new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0); + new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(intVal(dcreaterole->arg)); new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true; } - if (createdb >= 0) + if (dcreatedb) { - new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0); + new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(intVal(dcreatedb->arg)); new_record_repl[Anum_pg_authid_rolcreatedb - 1] = true; } - if (canlogin >= 0) + if (dcanlogin) { - new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0); + new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(intVal(dcanlogin->arg)); new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true; } - if (isreplication >= 0) + if (disreplication) { - new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication > 0); + new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(intVal(disreplication->arg)); new_record_repl[Anum_pg_authid_rolreplication - 1] = true; } @@ -808,9 +777,9 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null; new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = true; - if (bypassrls >= 0) + if (dbypassRLS) { - new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls > 0); + new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(intVal(dbypassRLS->arg)); new_record_repl[Anum_pg_authid_rolbypassrls - 1] = true; } @@ -827,17 +796,21 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt) * Advance command counter so we can see new record; else tests in * AddRoleMems may fail. */ - if (rolemembers) + if (drolemembers) + { + List *rolemembers = (List *) drolemembers->arg; + CommandCounterIncrement(); - if (stmt->action == +1) /* add members to role */ - AddRoleMems(rolename, roleid, - rolemembers, roleSpecsToIds(rolemembers), - GetUserId(), false); - else if (stmt->action == -1) /* drop members from role */ - DelRoleMems(rolename, roleid, - rolemembers, roleSpecsToIds(rolemembers), - false); + if (stmt->action == +1) /* add members to role */ + AddRoleMems(rolename, roleid, + rolemembers, roleSpecsToIds(rolemembers), + GetUserId(), false); + else if (stmt->action == -1) /* drop members from role */ + DelRoleMems(rolename, roleid, + rolemembers, roleSpecsToIds(rolemembers), + false); + } /* * Close pg_authid, but keep lock till commit. base-commit: 69872d0bbe64fcd67c4fb4c61e5c7bf6a3443a47 -- 2.34.1