1/*-------------------------------------------------------------------------
4 * Commands for manipulating roles (formerly called users).
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * src/backend/commands/user.c
11 *-------------------------------------------------------------------------
39#include "utils/fmgroids.h"
44 * Removing a role grant - or the admin option on it - might recurse to
45 * dependent grants. We use these values to reason about what would need to
46 * be done in such cases.
48 * RRG_NOOP indicates a grant that would not need to be altered by the
51 * RRG_REMOVE_ADMIN_OPTION indicates a grant that would need to have
52 * admin_option set to false by the operation.
54 * Similarly, RRG_REMOVE_INHERIT_OPTION and RRG_REMOVE_SET_OPTION indicate
55 * grants that would need to have the corresponding options set to false.
57 * RRG_DELETE_GRANT indicates a grant that would need to be removed entirely
69/* Potentially set by pg_upgrade_support functions */
80 #define GRANT_ROLE_SPECIFIED_ADMIN 0x0001
81 #define GRANT_ROLE_SPECIFIED_INHERIT 0x0002
82 #define GRANT_ROLE_SPECIFIED_SET 0x0004
90/* Hook to check passwords in CreateRole() and AlterRole() */
115 bool revoke_admin_option_only,
120/* Check if current user has createrole privileges */
137 Datum new_record[Natts_pg_authid] = {0};
138 bool new_record_nulls[Natts_pg_authid] = {0};
143 char *
password = NULL;
/* user password */
144 bool issuper =
false;
/* Make the user a superuser? */
145 bool inherit =
true;
/* Auto inherit privileges? */
146 bool createrole =
false;
/* Can this user create roles? */
147 bool createdb =
false;
/* Can the user create databases? */
148 bool canlogin =
false;
/* Can this user login? */
149 bool isreplication =
false;
/* Is this a replication role? */
150 bool bypassrls =
false;
/* Is this a row security enabled role? */
151 int connlimit = -1;
/* maximum connections allowed */
152 List *addroleto =
NIL;
/* roles to make this a member of */
153 List *rolemembers =
NIL;
/* roles to be members of this role */
154 List *adminmembers =
NIL;
/* roles to be admins of this role */
155 char *validUntil = NULL;
/* time the login is valid until */
156 Datum validUntil_datum;
/* same, as timestamptz Datum */
157 bool validUntil_null;
164 DefElem *disreplication = NULL;
173 /* The defaults can vary depending on the original statement type */
174 switch (
stmt->stmt_type)
180 /* may eventually want inherit to default to false here */
186 /* Extract options from the statement node tree */
191 if (strcmp(defel->
defname,
"password") == 0)
197 else if (strcmp(defel->
defname,
"sysid") == 0)
200 (
errmsg(
"SYSID can no longer be specified")));
202 else if (strcmp(defel->
defname,
"superuser") == 0)
208 else if (strcmp(defel->
defname,
"inherit") == 0)
214 else if (strcmp(defel->
defname,
"createrole") == 0)
220 else if (strcmp(defel->
defname,
"createdb") == 0)
226 else if (strcmp(defel->
defname,
"canlogin") == 0)
232 else if (strcmp(defel->
defname,
"isreplication") == 0)
236 disreplication = defel;
238 else if (strcmp(defel->
defname,
"connectionlimit") == 0)
244 else if (strcmp(defel->
defname,
"addroleto") == 0)
250 else if (strcmp(defel->
defname,
"rolemembers") == 0)
254 drolemembers = defel;
256 else if (strcmp(defel->
defname,
"adminmembers") == 0)
260 dadminmembers = defel;
262 else if (strcmp(defel->
defname,
"validUntil") == 0)
268 else if (strcmp(defel->
defname,
"bypassrls") == 0)
275 elog(
ERROR,
"option \"%s\" not recognized",
279 if (dpassword && dpassword->
arg)
298 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
299 errmsg(
"invalid connection limit: %d", connlimit)));
302 addroleto = (
List *) daddroleto->
arg;
304 rolemembers = (
List *) drolemembers->
arg;
306 adminmembers = (
List *) dadminmembers->
arg;
312 /* Check some permissions first */
317 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
318 errmsg(
"permission denied to create role"),
319 errdetail(
"Only roles with the %s attribute may create roles.",
323 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
324 errmsg(
"permission denied to create role"),
325 errdetail(
"Only roles with the %s attribute may create roles with the %s attribute.",
326 "SUPERUSER",
"SUPERUSER")));
329 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
330 errmsg(
"permission denied to create role"),
331 errdetail(
"Only roles with the %s attribute may create roles with the %s attribute.",
332 "CREATEDB",
"CREATEDB")));
335 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
336 errmsg(
"permission denied to create role"),
337 errdetail(
"Only roles with the %s attribute may create roles with the %s attribute.",
338 "REPLICATION",
"REPLICATION")));
341 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
342 errmsg(
"permission denied to create role"),
343 errdetail(
"Only roles with the %s attribute may create roles with the %s attribute.",
344 "BYPASSRLS",
"BYPASSRLS")));
348 * Check that the user is not trying to create a role in the reserved
353 (
errcode(ERRCODE_RESERVED_NAME),
354 errmsg(
"role name \"%s\" is reserved",
356 errdetail(
"Role names starting with \"pg_\" are reserved.")));
359 * If built with appropriate switch, whine when regression-testing
360 * conventions for role names are violated.
362#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
363 if (strncmp(
stmt->role,
"regress_", 8) != 0)
364 elog(
WARNING,
"roles created by regression test cases should have names starting with \"regress_\"");
368 * Check the pg_authid relation to be certain the role doesn't already
377 errmsg(
"role \"%s\" already exists",
380 /* Convert validuntil to internal form */
387 validUntil_null =
false;
391 validUntil_datum = (
Datum) 0;
392 validUntil_null =
true;
396 * Call the password checking hook if there is one defined
399 (*check_password_hook) (
stmt->role,
406 * Build a tuple to insert
408 new_record[Anum_pg_authid_rolname - 1] =
410 new_record[Anum_pg_authid_rolsuper - 1] =
BoolGetDatum(issuper);
411 new_record[Anum_pg_authid_rolinherit - 1] =
BoolGetDatum(inherit);
412 new_record[Anum_pg_authid_rolcreaterole - 1] =
BoolGetDatum(createrole);
414 new_record[Anum_pg_authid_rolcanlogin - 1] =
BoolGetDatum(canlogin);
415 new_record[Anum_pg_authid_rolreplication - 1] =
BoolGetDatum(isreplication);
416 new_record[Anum_pg_authid_rolconnlimit - 1] =
Int32GetDatum(connlimit);
421 const char *logdetail = NULL;
424 * Don't allow an empty password. Libpq treats an empty password the
425 * same as no password at all, and won't even try to authenticate. But
426 * other clients might, so allowing it would be confusing. By clearing
427 * the password when an empty string is specified, the account is
428 * consistently locked for all clients.
430 * Note that this only covers passwords stored in the database itself.
431 * There are also checks in the authentication code, to forbid an
432 * empty password from being used with authentication methods that
433 * fetch the password from an external system, like LDAP or PAM.
439 (
errmsg(
"empty string is not a valid password, clearing password")));
440 new_record_nulls[Anum_pg_authid_rolpassword - 1] =
true;
444 /* Encrypt the password to the requested format. */
447 new_record[Anum_pg_authid_rolpassword - 1] =
452 new_record_nulls[Anum_pg_authid_rolpassword - 1] =
true;
454 new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
455 new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
457 new_record[Anum_pg_authid_rolbypassrls - 1] =
BoolGetDatum(bypassrls);
460 * pg_largeobject_metadata contains pg_authid.oid's, so we use the
461 * binary-upgrade override.
467 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
468 errmsg(
"pg_authid OID value not set when in binary upgrade mode")));
484 * Insert new record in the pg_authid table
489 * Advance command counter so we can see new record; else tests in
490 * AddRoleMems may fail.
492 if (addroleto || adminmembers || rolemembers)
499 * Add the new role to the specified existing roles.
511 foreach(item, addroleto)
516 Oid oldroleid = oldroleform->oid;
517 char *oldrolename =
NameStr(oldroleform->rolname);
519 /* can only add this role to roles for which you have rights */
531 * If the current user isn't a superuser, make them an admin of the new
532 * role so that they can administer the new object they just created.
533 * Superusers will be able to do that anyway.
535 * The grantor of record for this implicit grant is the bootstrap
536 * superuser, which means that the CREATEROLE user cannot revoke the
537 * grant. They can however grant the created role back to themselves with
538 * different options, since they enjoy ADMIN OPTION on it.
554 poptself.
admin =
true;
556 poptself.
set =
false;
559 memberSpecs, memberIds,
560 BOOTSTRAP_SUPERUSERID, &poptself);
563 * We must make the implicit grant visible to the code below, else the
564 * additional grants will fail.
569 * Because of the implicit grant above, a CREATEROLE user who creates
570 * a role has the ability to grant that role back to themselves with
571 * the INHERIT or SET options, if they wish to inherit the role's
572 * privileges or be able to SET ROLE to it. The createrole_self_grant
573 * GUC can be used to make this happen automatically. This has no
574 * security implications since the same user is able to make the same
575 * grant using an explicit GRANT statement; it's just convenient.
579 memberSpecs, memberIds,
584 * Add the specified members to this new role. adminmembers get the admin
585 * option, rolemembers don't.
587 * NB: No permissions check is required here. If you have enough rights to
588 * create a role, you can add any members you like.
599 /* Post creation hook for new role */
603 * Close pg_authid, but keep lock till commit.
614 * Note: the rolemembers option accepted here is intended to support the
615 * backwards-compatible ALTER GROUP syntax. Although it will work to say
616 * "ALTER ROLE role ROLE rolenames", we don't document it.
621 Datum new_record[Natts_pg_authid] = {0};
622 bool new_record_nulls[Natts_pg_authid] = {0};
623 bool new_record_repl[Natts_pg_authid] = {0};
631 char *
password = NULL;
/* user password */
632 int connlimit = -1;
/* maximum connections allowed */
633 char *validUntil = NULL;
/* time the login is valid until */
634 Datum validUntil_datum;
/* same, as timestamptz Datum */
635 bool validUntil_null;
642 DefElem *disreplication = NULL;
652 _(
"Cannot alter reserved roles."));
654 /* Extract options from the statement node tree */
659 if (strcmp(defel->
defname,
"password") == 0)
665 else if (strcmp(defel->
defname,
"superuser") == 0)
671 else if (strcmp(defel->
defname,
"inherit") == 0)
677 else if (strcmp(defel->
defname,
"createrole") == 0)
683 else if (strcmp(defel->
defname,
"createdb") == 0)
689 else if (strcmp(defel->
defname,
"canlogin") == 0)
695 else if (strcmp(defel->
defname,
"isreplication") == 0)
699 disreplication = defel;
701 else if (strcmp(defel->
defname,
"connectionlimit") == 0)
707 else if (strcmp(defel->
defname,
"rolemembers") == 0 &&
712 drolemembers = defel;
714 else if (strcmp(defel->
defname,
"validUntil") == 0)
720 else if (strcmp(defel->
defname,
"bypassrls") == 0)
727 elog(
ERROR,
"option \"%s\" not recognized",
731 if (dpassword && dpassword->
arg)
738 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
739 errmsg(
"invalid connection limit: %d", connlimit)));
745 * Scan the pg_authid relation to be certain the user exists.
753 roleid = authform->oid;
755 /* To mess with a superuser in any way you gotta be superuser. */
758 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
759 errmsg(
"permission denied to alter role"),
760 errdetail(
"Only roles with the %s attribute may alter roles with the %s attribute.",
761 "SUPERUSER",
"SUPERUSER")));
764 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
765 errmsg(
"permission denied to alter role"),
766 errdetail(
"Only roles with the %s attribute may change the %s attribute.",
767 "SUPERUSER",
"SUPERUSER")));
770 * Most changes to a role require that you both have CREATEROLE privileges
771 * and also ADMIN OPTION on the role.
776 /* things an unprivileged user certainly can't do */
777 if (dinherit || dcreaterole || dcreatedb || dcanlogin || dconnlimit ||
778 dvalidUntil || disreplication || dbypassRLS)
780 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
781 errmsg(
"permission denied to alter role"),
782 errdetail(
"Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
783 "CREATEROLE",
"ADMIN", rolename)));
785 /* an unprivileged user can change their own password */
786 if (dpassword && roleid != currentUserId)
788 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
789 errmsg(
"permission denied to alter role"),
790 errdetail(
"To change another role's password, the current user must have the %s attribute and the %s option on the role.",
791 "CREATEROLE",
"ADMIN")));
796 * Even if you have both CREATEROLE and ADMIN OPTION on a role, you
797 * can only change the CREATEDB, REPLICATION, or BYPASSRLS attributes
798 * if they are set for your own role (or you are the superuser).
802 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
803 errmsg(
"permission denied to alter role"),
804 errdetail(
"Only roles with the %s attribute may change the %s attribute.",
805 "CREATEDB",
"CREATEDB")));
808 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
809 errmsg(
"permission denied to alter role"),
810 errdetail(
"Only roles with the %s attribute may change the %s attribute.",
811 "REPLICATION",
"REPLICATION")));
814 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
815 errmsg(
"permission denied to alter role"),
816 errdetail(
"Only roles with the %s attribute may change the %s attribute.",
817 "BYPASSRLS",
"BYPASSRLS")));
820 /* To add or drop members, you need ADMIN OPTION. */
823 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
824 errmsg(
"permission denied to alter role"),
825 errdetail(
"Only roles with the %s option on role \"%s\" may add or drop members.",
826 "ADMIN", rolename)));
828 /* Convert validuntil to internal form */
835 validUntil_null =
false;
839 /* fetch existing setting in case hook needs it */
841 Anum_pg_authid_rolvaliduntil,
846 * Call the password checking hook if there is one defined
849 (*check_password_hook) (rolename,
856 * Build an updated tuple, perusing the information just obtained
860 * issuper/createrole/etc
864 bool should_be_super =
boolVal(dissuper->
arg);
866 if (!should_be_super && roleid == BOOTSTRAP_SUPERUSERID)
868 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
869 errmsg(
"permission denied to alter role"),
870 errdetail(
"The bootstrap superuser must have the %s attribute.",
873 new_record[Anum_pg_authid_rolsuper - 1] =
BoolGetDatum(should_be_super);
874 new_record_repl[Anum_pg_authid_rolsuper - 1] =
true;
880 new_record_repl[Anum_pg_authid_rolinherit - 1] =
true;
886 new_record_repl[Anum_pg_authid_rolcreaterole - 1] =
true;
892 new_record_repl[Anum_pg_authid_rolcreatedb - 1] =
true;
898 new_record_repl[Anum_pg_authid_rolcanlogin - 1] =
true;
904 new_record_repl[Anum_pg_authid_rolreplication - 1] =
true;
909 new_record[Anum_pg_authid_rolconnlimit - 1] =
Int32GetDatum(connlimit);
910 new_record_repl[Anum_pg_authid_rolconnlimit - 1] =
true;
917 const char *logdetail = NULL;
919 /* Like in CREATE USER, don't allow an empty password. */
924 (
errmsg(
"empty string is not a valid password, clearing password")));
925 new_record_nulls[Anum_pg_authid_rolpassword - 1] =
true;
929 /* Encrypt the password to the requested format. */
932 new_record[Anum_pg_authid_rolpassword - 1] =
935 new_record_repl[Anum_pg_authid_rolpassword - 1] =
true;
939 if (dpassword && dpassword->
arg == NULL)
941 new_record_repl[Anum_pg_authid_rolpassword - 1] =
true;
942 new_record_nulls[Anum_pg_authid_rolpassword - 1] =
true;
946 new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
947 new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
948 new_record_repl[Anum_pg_authid_rolvaliduntil - 1] =
true;
953 new_record_repl[Anum_pg_authid_rolbypassrls - 1] =
true;
957 new_record_nulls, new_record_repl);
968 * Advance command counter so we can see new record; else tests in
969 * AddRoleMems may fail.
977 if (
stmt->action == +1)
/* add members to role */
981 else if (
stmt->action == -1)
/* drop members from role */
988 * Close pg_authid, but keep lock till commit.
1010 _(
"Cannot alter reserved roles."));
1014 roleid = roleform->oid;
1017 * Obtain a lock on the role and make sure it didn't go away in the
1023 * To mess with a superuser you gotta be superuser; otherwise you need
1024 * CREATEROLE plus admin option on the target role; unless you're just
1025 * trying to change your own settings
1027 if (roleform->rolsuper)
1031 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1032 errmsg(
"permission denied to alter role"),
1033 errdetail(
"Only roles with the %s attribute may alter roles with the %s attribute.",
1034 "SUPERUSER",
"SUPERUSER")));
1042 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1043 errmsg(
"permission denied to alter role"),
1044 errdetail(
"Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
1045 "CREATEROLE",
"ADMIN",
NameStr(roleform->rolname))));
1051 /* look up and lock the database, if specified */
1052 if (
stmt->database != NULL)
1060 * If no role is specified, then this is effectively the same as
1061 * ALTER DATABASE ... SET, so use the same permission check.
1069 if (!
stmt->role && !
stmt->database)
1071 /* Must be superuser to alter settings globally. */
1074 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1075 errmsg(
"permission denied to alter setting"),
1076 errdetail(
"Only roles with the %s attribute may alter settings globally.",
1093 pg_auth_members_rel;
1099 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1100 errmsg(
"permission denied to drop role"),
1101 errdetail(
"Only roles with the %s attribute and the %s option on the target roles may drop roles.",
1102 "CREATEROLE",
"ADMIN")));
1105 * Scan the pg_authid relation to find the Oid of the role(s) to be
1106 * deleted and perform preliminary permissions and sanity checks.
1111 foreach(item,
stmt->roles)
1124 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1125 errmsg(
"cannot use special role specifier in DROP ROLE")));
1131 if (!
stmt->missing_ok)
1134 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1135 errmsg(
"role \"%s\" does not exist", role)));
1140 (
errmsg(
"role \"%s\" does not exist, skipping",
1148 roleid = roleform->oid;
1152 (
errcode(ERRCODE_OBJECT_IN_USE),
1153 errmsg(
"current user cannot be dropped")));
1156 (
errcode(ERRCODE_OBJECT_IN_USE),
1157 errmsg(
"current user cannot be dropped")));
1160 (
errcode(ERRCODE_OBJECT_IN_USE),
1161 errmsg(
"session user cannot be dropped")));
1164 * For safety's sake, we allow createrole holders to drop ordinary
1165 * roles but not superuser roles, and only if they also have ADMIN
1170 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1171 errmsg(
"permission denied to drop role"),
1172 errdetail(
"Only roles with the %s attribute may drop roles with the %s attribute.",
1173 "SUPERUSER",
"SUPERUSER")));
1176 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1177 errmsg(
"permission denied to drop role"),
1178 errdetail(
"Only roles with the %s attribute and the %s option on role \"%s\" may drop this role.",
1179 "CREATEROLE",
"ADMIN",
NameStr(roleform->rolname))));
1181 /* DROP hook for the role being removed */
1184 /* Don't leak the syscache tuple */
1188 * Lock the role, so nobody can add dependencies to her while we drop
1189 * her. We keep the lock until the end of transaction.
1194 * If there is a pg_auth_members entry that has one of the roles to be
1195 * dropped as the roleid or member, it should be silently removed, but
1196 * if there is a pg_auth_members entry that has one of the roles to be
1197 * dropped as the grantor, the operation should fail.
1199 * It's possible, however, that a single pg_auth_members entry could
1200 * fall into multiple categories - e.g. the user could do "GRANT foo
1201 * TO bar GRANTED BY baz" and then "DROP ROLE baz, bar". We want such
1202 * an operation to succeed regardless of the order in which the
1203 * to-be-dropped roles are passed to DROP ROLE.
1205 * To make that work, we remove all pg_auth_members entries that can
1206 * be silently removed in this loop, and then below we'll make a
1207 * second pass over the list of roles to be removed and check for any
1208 * remaining dependencies.
1211 Anum_pg_auth_members_roleid,
1216 true, NULL, 1, &scankey);
1224 authmem_form->oid, 0);
1231 Anum_pg_auth_members_member,
1236 true, NULL, 1, &scankey);
1244 authmem_form->oid, 0);
1251 * Advance command counter so that later iterations of this loop will
1252 * see the changes already made. This is essential if, for example,
1253 * we are trying to drop both a role and one of its direct members ---
1254 * we'll get an error if we try to delete the linking pg_auth_members
1255 * tuple twice. (We do not need a CCI between the two delete loops
1256 * above, because it's not allowed for a role to directly contain
1261 /* Looks tentatively OK, add it to the list if not there yet. */
1266 * Second pass over the roles to be removed.
1268 foreach(item, role_oids)
1277 * Re-find the pg_authid tuple.
1279 * Since we've taken a lock on the role OID, it shouldn't be possible
1280 * for the tuple to have been deleted -- or for that matter updated --
1281 * unless the user is manually modifying the system catalogs.
1285 elog(
ERROR,
"could not find tuple for role %u", roleid);
1289 * Check for pg_shdepend entries depending on this role.
1291 * This needs to happen after we've completed removing any
1292 * pg_auth_members entries that can be removed silently, in order to
1293 * avoid spurious failures. See notes above for more details.
1296 &detail, &detail_log))
1298 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1299 errmsg(
"role \"%s\" cannot be dropped because some objects depend on it",
1305 * Remove the role from the pg_authid table
1312 * Remove any comments or security labels on this role.
1318 * Remove settings for this role.
1324 * Now we can clean up; but keep locks until commit.
1342 Datum repl_val[Natts_pg_authid];
1343 bool repl_null[Natts_pg_authid];
1344 bool repl_repl[Natts_pg_authid];
1356 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1357 errmsg(
"role \"%s\" does not exist", oldname)));
1360 * XXX Client applications probably store the session user somewhere, so
1361 * renaming it could cause confusion. On the other hand, there may not be
1362 * an actual problem besides a little confusion, so think about this and
1363 * decide. Same for SET ROLE ... we don't restrict renaming the current
1364 * effective userid, though.
1368 roleid = authform->oid;
1372 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1373 errmsg(
"session user cannot be renamed")));
1376 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1377 errmsg(
"current user cannot be renamed")));
1380 * Check that the user is not trying to rename a system role and not
1381 * trying to rename a role into the reserved "pg_" namespace.
1385 (
errcode(ERRCODE_RESERVED_NAME),
1386 errmsg(
"role name \"%s\" is reserved",
1388 errdetail(
"Role names starting with \"pg_\" are reserved.")));
1392 (
errcode(ERRCODE_RESERVED_NAME),
1393 errmsg(
"role name \"%s\" is reserved",
1395 errdetail(
"Role names starting with \"pg_\" are reserved.")));
1398 * If built with appropriate switch, whine when regression-testing
1399 * conventions for role names are violated.
1401#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1402 if (strncmp(newname,
"regress_", 8) != 0)
1403 elog(
WARNING,
"roles created by regression test cases should have names starting with \"regress_\"");
1406 /* make sure the new name doesn't exist */
1410 errmsg(
"role \"%s\" already exists", newname)));
1413 * Only superusers can mess with superusers. Otherwise, a user with
1414 * CREATEROLE can rename a role for which they have ADMIN OPTION.
1416 if (authform->rolsuper)
1420 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1421 errmsg(
"permission denied to rename role"),
1422 errdetail(
"Only roles with the %s attribute may rename roles with the %s attribute.",
1423 "SUPERUSER",
"SUPERUSER")));
1430 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1431 errmsg(
"permission denied to rename role"),
1432 errdetail(
"Only roles with the %s attribute and the %s option on role \"%s\" may rename this role.",
1433 "CREATEROLE",
"ADMIN",
NameStr(authform->rolname))));
1436 /* OK, construct the modified tuple */
1437 for (
i = 0;
i < Natts_pg_authid;
i++)
1438 repl_repl[
i] =
false;
1440 repl_repl[Anum_pg_authid_rolname - 1] =
true;
1443 repl_null[Anum_pg_authid_rolname - 1] =
false;
1445 datum =
heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1449 /* MD5 uses the username as salt, so just clear it on a rename */
1450 repl_repl[Anum_pg_authid_rolpassword - 1] =
true;
1451 repl_null[Anum_pg_authid_rolpassword - 1] =
true;
1454 (
errmsg(
"MD5 password cleared because of role rename")));
1467 * Close pg_authid, but keep lock till commit.
1477 * Grant/Revoke roles to/from roles
1489 /* Parse options list. */
1491 foreach(item,
stmt->opt)
1496 if (strcmp(opt->
defname,
"admin") == 0)
1503 else if (strcmp(opt->
defname,
"inherit") == 0)
1509 else if (strcmp(opt->
defname,
"set") == 0)
1517 errcode(ERRCODE_SYNTAX_ERROR),
1522 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1523 errmsg(
"unrecognized value for role option \"%s\": \"%s\"",
1528 /* Lookup OID of grantor, if specified. */
1536 /* AccessShareLock is enough since we aren't modifying pg_authid */
1540 * Step through all of the granted roles and add, update, or remove
1541 * entries in pg_auth_members as appropriate. If stmt->is_grant is true,
1542 * we are adding new grants or, if they already exist, updating options on
1543 * those grants. If stmt->is_grant is false, we are revoking grants or
1544 * removing options from them.
1546 foreach(item,
stmt->granted_roles)
1552 /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1553 if (rolename == NULL || priv->
cols !=
NIL)
1555 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1556 errmsg(
"column names cannot be included in GRANT/REVOKE ROLE")));
1560 roleid,
stmt->is_grant);
1563 stmt->grantee_roles, grantee_ids,
1567 stmt->grantee_roles, grantee_ids,
1568 grantor, &popt,
stmt->behavior);
1572 * Close pg_authid, but keep lock till commit.
1580 * Drop the objects owned by a given list of roles.
1588 /* Check privileges */
1589 foreach(cell, role_ids)
1595 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1596 errmsg(
"permission denied to drop objects"),
1597 errdetail(
"Only roles with privileges of role \"%s\" may drop objects owned by it.",
1606 * ReassignOwnedObjects
1608 * Give the objects owned by a given list of roles away to another user.
1617 /* Check privileges */
1618 foreach(cell, role_ids)
1624 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1625 errmsg(
"permission denied to reassign objects"),
1626 errdetail(
"Only roles with privileges of role \"%s\" may reassign objects owned by it.",
1630 /* Must have privileges on the receiving side too */
1635 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1636 errmsg(
"permission denied to reassign objects"),
1637 errdetail(
"Only roles with privileges of role \"%s\" may reassign objects to it.",
1647 * Given a list of RoleSpecs, generate a list of role OIDs in the same order.
1649 * ROLESPEC_PUBLIC is not allowed.
1657 foreach(l, memberNames)
1669 * AddRoleMems -- Add given members to the specified role
1671 * currentUserId: OID of role performing the operation
1672 * rolename: name of role to add to (used only for error messages)
1673 * roleid: OID of role to add to
1674 * memberSpecs: list of RoleSpec of roles to add (used only for error messages)
1675 * memberIds: OIDs of roles to add
1676 * grantorId: OID that should be recorded as having granted the membership
1677 * (InvalidOid if not set explicitly)
1678 * popt: information about grant options
1682 List *memberSpecs,
List *memberIds,
1692 /* Validate grantor (and resolve implicit grantor if not specified). */
1699 * Only allow changes to this role by one backend at a time, so that we
1700 * can check integrity constraints like the lack of circular ADMIN OPTION
1701 * grants without fear of race conditions.
1706 /* Preliminary sanity checks. */
1707 forboth(specitem, memberSpecs, iditem, memberIds)
1713 * pg_database_owner is never a role member. Lifting this restriction
1714 * would require a policy decision about membership loops. One could
1715 * prevent loops, which would include making "ALTER DATABASE x OWNER
1716 * TO proposed_datdba" fail if is_member_of_role(pg_database_owner,
1717 * proposed_datdba). Hence, gaining a membership could reduce what a
1718 * role could do. Alternately, one could allow these memberships to
1719 * complete loops. A role could then have actual WITH ADMIN OPTION on
1720 * itself, prompting a decision about is_admin_of_role() treatment of
1723 * Lifting this restriction also has policy implications for ownership
1724 * of shared objects (databases and tablespaces). We allow such
1725 * ownership, but we might find cause to ban it in the future.
1726 * Designing such a ban would more troublesome if the design had to
1727 * address pg_database_owner being a member of role FOO that owns a
1728 * shared object. (The effect of such ownership is that any owner of
1729 * another database can act as the owner of affected shared objects.)
1731 if (memberid == ROLE_PG_DATABASE_OWNER)
1733 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1734 errmsg(
"role \"%s\" cannot be a member of any role",
1738 * Refuse creation of membership loops, including the trivial case
1739 * where a role is made a member of itself. We do this by checking to
1740 * see if the target role is already a member of the proposed member
1741 * role. We have to ignore possible superuserness, however, else we
1742 * could never grant membership in a superuser-privileged role.
1746 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1747 errmsg(
"role \"%s\" is a member of role \"%s\"",
1752 * Disallow attempts to grant ADMIN OPTION back to a user who granted it
1753 * to you, similar to what check_circularity does for ACLs. We want the
1754 * chains of grants to remain acyclic, so that it's always possible to use
1755 * REVOKE .. CASCADE to clean up all grants that depend on the one being
1758 * NB: This check might look redundant with the check for membership loops
1759 * above, but it isn't. That's checking for role-member loop (e.g. A is a
1760 * member of B and B is a member of A) while this is checking for a
1761 * member-grantor loop (e.g. A gave ADMIN OPTION on X to B and now B, who
1762 * has no other source of ADMIN OPTION on X, tries to give ADMIN OPTION on
1765 if (popt->
admin && grantorId != BOOTSTRAP_SUPERUSERID)
1771 /* Get the list of members for this role. */
1776 * Figure out what would happen if we removed all existing grants to
1777 * every role to which we've been asked to make a new grant.
1780 foreach(iditem, memberIds)
1784 if (memberid == BOOTSTRAP_SUPERUSERID)
1786 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1787 errmsg(
"%s option cannot be granted back to your own grantor",
1793 * If the result would be that the grantor role would no longer have
1794 * the ability to perform the grant, then the proposed grant would
1795 * create a circularity.
1806 authmem_form->member == grantorId &&
1807 authmem_form->admin_option)
1812 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1813 errmsg(
"%s option cannot be granted back to your own grantor",
1819 /* Now perform the catalog updates. */
1820 forboth(specitem, memberSpecs, iditem, memberIds)
1826 Datum new_record[Natts_pg_auth_members] = {0};
1827 bool new_record_nulls[Natts_pg_auth_members] = {0};
1828 bool new_record_repl[Natts_pg_auth_members] = {0};
1830 /* Common initialization for possible insert or update */
1831 new_record[Anum_pg_auth_members_roleid - 1] =
1833 new_record[Anum_pg_auth_members_member - 1] =
1835 new_record[Anum_pg_auth_members_grantor - 1] =
1838 /* Find any existing tuple */
1845 * If we found a tuple, update it with new option values, unless there
1846 * are no changes, in which case issue a WARNING.
1848 * If we didn't find a tuple, just insert one.
1853 bool at_least_one_change =
false;
1858 && authmem_form->admin_option != popt->
admin)
1860 new_record[Anum_pg_auth_members_admin_option - 1] =
1862 new_record_repl[Anum_pg_auth_members_admin_option - 1] =
1864 at_least_one_change =
true;
1868 && authmem_form->inherit_option != popt->
inherit)
1870 new_record[Anum_pg_auth_members_inherit_option - 1] =
1872 new_record_repl[Anum_pg_auth_members_inherit_option - 1] =
1874 at_least_one_change =
true;
1878 && authmem_form->set_option != popt->
set)
1880 new_record[Anum_pg_auth_members_set_option - 1] =
1882 new_record_repl[Anum_pg_auth_members_set_option - 1] =
1884 at_least_one_change =
true;
1887 if (!at_least_one_change)
1890 (
errmsg(
"role \"%s\" has already been granted membership in role \"%s\" by role \"%s\"",
1899 new_record_nulls, new_record_repl);
1910 * The values for these options can be taken directly from 'popt'.
1911 * Either they were specified, or the defaults as set by
1912 * InitGrantRoleOptions are correct.
1914 new_record[Anum_pg_auth_members_admin_option - 1] =
1916 new_record[Anum_pg_auth_members_set_option - 1] =
1920 * If the user specified a value for the inherit option, use
1921 * whatever was specified. Otherwise, set the default value based
1922 * on the role-level property.
1925 new_record[Anum_pg_auth_members_inherit_option - 1] =
1934 elog(
ERROR,
"cache lookup failed for role %u", memberid);
1936 new_record[Anum_pg_auth_members_inherit_option - 1] =
1941 /* get an OID for the new row and insert it */
1943 Anum_pg_auth_members_oid);
1946 new_record, new_record_nulls);
1949 /* updateAclDependencies wants to pfree array inputs */
1950 newmembers[0] = grantorId;
1957 /* CCI after each change, in case there are duplicates in list */
1962 * Close pg_authmem, but keep lock till commit.
1968 * DelRoleMems -- Remove given members from the specified role
1970 * rolename: name of role to del from (used only for error messages)
1971 * roleid: OID of role to del from
1972 * memberSpecs: list of RoleSpec of roles to del (used only for error messages)
1973 * memberIds: OIDs of roles to del
1974 * grantorId: who is revoking the membership
1975 * popt: information about grant options
1976 * behavior: RESTRICT or CASCADE behavior for recursive removal
1980 List *memberSpecs,
List *memberIds,
1993 /* Validate grantor (and resolve implicit grantor if not specified). */
2000 * Only allow changes to this role by one backend at a time, so that we
2001 * can check for things like dependent privileges without fear of race
2011 * We may need to recurse to dependent privileges if DROP_CASCADE was
2012 * specified, or refuse to perform the operation if dependent privileges
2013 * exist and DROP_RESTRICT was specified. plan_single_revoke() will figure
2014 * out what to do with each catalog tuple.
2016 forboth(specitem, memberSpecs, iditem, memberIds)
2025 (
errmsg(
"role \"%s\" has not been granted membership in role \"%s\" by role \"%s\"",
2033 * We now know what to do with each catalog tuple: it should either be
2034 * left alone, deleted, or just have the admin_option flag cleared.
2035 * Perform the appropriate action in each case.
2051 * Remove the entry altogether, after first removing its
2055 authmem_form->oid, 0);
2060 /* Just turn off the specified option */
2062 Datum new_record[Natts_pg_auth_members] = {0};
2063 bool new_record_nulls[Natts_pg_auth_members] = {0};
2064 bool new_record_repl[Natts_pg_auth_members] = {0};
2066 /* Build a tuple to update with */
2069 new_record[Anum_pg_auth_members_admin_option - 1] =
2071 new_record_repl[Anum_pg_auth_members_admin_option - 1] =
2076 new_record[Anum_pg_auth_members_inherit_option - 1] =
2078 new_record_repl[Anum_pg_auth_members_inherit_option - 1] =
2083 new_record[Anum_pg_auth_members_set_option - 1] =
2085 new_record_repl[Anum_pg_auth_members_set_option - 1] =
2089 elog(
ERROR,
"unknown role revoke action");
2093 new_record_nulls, new_record_repl);
2101 * Close pg_authmem, but keep lock till commit.
2107 * Check that currentUserId has permission to modify the membership list for
2108 * roleid. Throw an error if not.
2115 * The charter of pg_database_owner is to have exactly one, implicit,
2116 * situation-dependent member. There's no technical need for this
2117 * restriction. (One could lift it and take the further step of making
2118 * object_ownercheck(DatabaseRelationId, ...) equivalent to
2119 * has_privs_of_role(roleid, ROLE_PG_DATABASE_OWNER), in which case
2120 * explicit, situation-independent members could act as the owner of any
2123 if (is_grant && roleid == ROLE_PG_DATABASE_OWNER)
2125 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2126 errmsg(
"role \"%s\" cannot have explicit members",
2129 /* To mess with a superuser role, you gotta be superuser. */
2136 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2137 errmsg(
"permission denied to grant role \"%s\"",
2139 errdetail(
"Only roles with the %s attribute may grant roles with the %s attribute.",
2140 "SUPERUSER",
"SUPERUSER")));
2143 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2144 errmsg(
"permission denied to revoke role \"%s\"",
2146 errdetail(
"Only roles with the %s attribute may revoke roles with the %s attribute.",
2147 "SUPERUSER",
"SUPERUSER")));
2153 * Otherwise, must have admin option on the role to be changed.
2159 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2160 errmsg(
"permission denied to grant role \"%s\"",
2162 errdetail(
"Only roles with the %s option on role \"%s\" may grant this role.",
2166 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2167 errmsg(
"permission denied to revoke role \"%s\"",
2169 errdetail(
"Only roles with the %s option on role \"%s\" may revoke this role.",
2176 * Sanity-check, or infer, the grantor for a GRANT or REVOKE statement
2179 * The grantor must always be either a role with ADMIN OPTION on the role in
2180 * which membership is being granted, or the bootstrap superuser. This is
2181 * similar to the restriction enforced by select_best_grantor, except that
2182 * roles don't have owners, so we regard the bootstrap superuser as the
2185 * If the grantor was not explicitly specified by the user, grantorId should
2186 * be passed as InvalidOid, and this function will infer the user to be
2187 * recorded as the grantor. In many cases, this will be the current user, but
2188 * things get more complicated when the current user doesn't possess ADMIN
2189 * OPTION on the role but rather relies on having SUPERUSER privileges, or
2190 * on inheriting the privileges of a role which does have ADMIN OPTION. See
2191 * below for details.
2193 * If the grantor was specified by the user, then it must be a user that
2194 * can legally be recorded as the grantor, as per the rule stated above.
2195 * This is an integrity constraint, not a permissions check, and thus even
2196 * superusers are subject to this restriction. However, there is also a
2197 * permissions check: to specify a role as the grantor, the current user
2198 * must possess the privileges of that role. Superusers will always pass
2199 * this check, but for non-superusers it may lead to an error.
2201 * The return value is the OID to be regarded as the grantor when executing
2207 /* If the grantor ID was not specified, pick one to use. */
2211 * Grants where the grantor is recorded as the bootstrap superuser do
2212 * not depend on any other existing grants, so always default to this
2213 * interpretation when possible.
2216 return BOOTSTRAP_SUPERUSERID;
2219 * Otherwise, the grantor must either have ADMIN OPTION on the role or
2220 * inherit the privileges of a role which does. In the former case,
2221 * record the grantor as the current user; in the latter, pick one of
2222 * the roles that is "most directly" inherited by the current role
2223 * (i.e. fewest "hops").
2225 * (We shouldn't fail to find a best grantor, because we've already
2226 * established that the current user has permission to perform the
2236 * If an explicit grantor is specified, it must be a role whose privileges
2237 * the current user possesses.
2239 * It should also be a role that has ADMIN OPTION on the target role, but
2240 * we check this condition only in case of GRANT. For REVOKE, no matching
2241 * grant should exist anyway, but if it somehow does, let the user get rid
2248 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2249 errmsg(
"permission denied to grant privileges as role \"%s\"",
2251 errdetail(
"Only roles with privileges of role \"%s\" may grant privileges as this role.",
2254 if (grantorId != BOOTSTRAP_SUPERUSERID &&
2257 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2258 errmsg(
"permission denied to grant privileges as role \"%s\"",
2260 errdetail(
"The grantor must have the %s option on role \"%s\".",
2267 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2268 errmsg(
"permission denied to revoke privileges granted by role \"%s\"",
2270 errdetail(
"Only roles with privileges of role \"%s\" may revoke privileges granted by this role.",
2275 * If a grantor was specified explicitly, always attribute the grant to
2276 * that role (unless we error out above).
2282 * Initialize an array of RevokeRoleGrantAction objects.
2284 * 'memlist' should be a list of all grants for the target role.
2286 * This constructs an array indicating that no actions are to be performed;
2287 * that is, every element is initially RRG_NOOP.
2305 * Figure out what we would need to do in order to revoke a grant, or just the
2306 * admin option on a grant, given that there might be dependent privileges.
2308 * 'memlist' should be a list of all grants for the target role.
2310 * Whatever actions prove to be necessary will be signalled by updating
2313 * If behavior is DROP_RESTRICT, an error will occur if there are dependent
2314 * role membership grants; if DROP_CASCADE, those grants will be scheduled
2317 * The return value is true if the matching grant was found in the list,
2328 * If popt.specified == 0, we're revoking the grant entirely; otherwise,
2329 * we expect just one bit to be set, and we're revoking the corresponding
2330 * option. As of this writing, there's no syntax that would allow for an
2331 * attempt to revoke multiple options at once, and the logic below
2332 * wouldn't work properly if such syntax were added, so assert that our
2333 * caller isn't trying to do that.
2345 if (authmem_form->member == member &&
2346 authmem_form->grantor == grantor)
2351 * Revoking the INHERIT option doesn't change anything for
2352 * dependent privileges, so we don't need to recurse.
2358 /* Here too, no need to recurse. */
2363 bool revoke_admin_option_only;
2366 * Revoking the grant entirely, or ADMIN option on a grant,
2367 * implicates dependent privileges, so we may need to recurse.
2369 revoke_admin_option_only =
2372 revoke_admin_option_only, behavior);
2382 * Figure out what we would need to do in order to revoke all grants to
2383 * a given member, given that there might be dependent privileges.
2385 * 'memlist' should be a list of all grants for the target role.
2387 * Whatever actions prove to be necessary will be signalled by updating
2404 if (authmem_form->member == member)
2410 * Workhorse for figuring out recursive revocation of role grants.
2412 * This is similar to what recursive_revoke() does for ACLs.
2419 bool would_still_have_admin_option =
false;
2424 /* If it's already been done, we can just return. */
2428 revoke_admin_option_only)
2431 /* Locate tuple data. */
2436 * If the existing tuple does not have admin_option set, then we do not
2437 * need to recurse. If we're just supposed to clear that bit we don't need
2438 * to do anything at all; if we're supposed to remove the grant, we need
2439 * to do something, but only to the tuple, and not any others.
2441 if (!revoke_admin_option_only)
2444 if (!authmem_form->admin_option)
2449 if (!authmem_form->admin_option)
2454 /* Determine whether the member would still have ADMIN OPTION. */
2463 if (am_cascade_form->member == authmem_form->member &&
2464 am_cascade_form->admin_option && actions[
i] ==
RRG_NOOP)
2466 would_still_have_admin_option =
true;
2471 /* If the member would still have ADMIN OPTION, we need not recurse. */
2472 if (would_still_have_admin_option)
2476 * Recurse to grants that are not yet slated for deletion which have this
2477 * member as the grantor.
2487 if (am_cascade_form->grantor == authmem_form->member &&
2492 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
2493 errmsg(
"dependent privileges exist"),
2494 errhint(
"Use CASCADE to revoke them too.")));
2502 * Initialize a GrantRoleOptions object with default values.
2508 popt->
admin =
false;
2514 * GUC check_hook for createrole_self_grant
2525 /* Need a modifiable copy of string */
2530 /* syntax error in list */
2537 foreach(l, elemlist)
2539 char *tok = (
char *)
lfirst(l);
2567 * GUC assign_hook for createrole_self_grant
2572 unsigned options = *(
unsigned *) extra;
bool is_admin_of_role(Oid member, Oid role)
Oid select_best_admin(Oid member, Oid role)
bool is_member_of_role_nosuper(Oid member, Oid role)
bool has_privs_of_role(Oid member, Oid role)
Oid get_role_oid(const char *rolname, bool missing_ok)
char * get_rolespec_name(const RoleSpec *role)
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
HeapTuple get_rolespec_tuple(const RoleSpec *role)
bool has_bypassrls_privilege(Oid roleid)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
bool has_createrole_privilege(Oid roleid)
Datum timestamptz_in(PG_FUNCTION_ARGS)
bool parse_bool(const char *value, bool *result)
#define CStringGetTextDatum(s)
#define TextDatumGetCString(d)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
bool IsReservedName(const char *name)
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
PasswordType get_password_type(const char *shadow_pass)
char * encrypt_password(PasswordType target_type, const char *role, const char *password)
@ PASSWORD_TYPE_SCRAM_SHA_256
bool have_createdb_privilege(void)
Oid get_database_oid(const char *dbname, bool missing_ok)
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
char * defGetString(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errdetail_log(const char *fmt,...)
#define ereport(elevel,...)
#define DirectFunctionCall1(func, arg1)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
void * guc_malloc(int elevel, size_t size)
#define GUC_check_errdetail
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
if(TABLE==NULL||TABLE_index==NULL)
List * lappend_oid(List *list, Oid datum)
List * list_append_unique_oid(List *list, Oid datum)
void list_free(List *list)
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
#define AccessExclusiveLock
#define ShareUpdateExclusiveLock
char * pstrdup(const char *in)
void pfree(void *pointer)
Oid GetSessionUserId(void)
bool has_rolreplication(Oid roleid)
char * GetUserNameFromId(Oid roleid, bool noerr)
Datum namein(PG_FUNCTION_ARGS)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define InvokeObjectDropHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
int parser_errposition(ParseState *pstate, int location)
FormData_pg_auth_members * Form_pg_auth_members
FormData_pg_authid * Form_pg_authid
int pg_popcount32(uint32 word)
void DropSetting(Oid databaseid, Oid roleid)
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define list_make1_oid(x1)
static rewind_source * source
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
bool checkSharedDependencies(Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
void shdepDropOwned(List *roleids, DropBehavior behavior)
void shdepLockAndCheckObject(Oid classId, Oid objectId)
void shdepReassignOwned(List *roleids, Oid newrole)
int pg_strcasecmp(const char *s1, const char *s2)
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
static Datum Int32GetDatum(int32 X)
#define RelationGetDescr(relation)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
bool superuser_arg(Oid roleid)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
#define ReleaseSysCacheList(x)
#define SearchSysCacheList1(cacheId, key1)
#define SearchSysCacheExists1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
static bool have_createrole_privilege(void)
ObjectAddress RenameRole(const char *oldname, const char *newname)
#define GRANT_ROLE_SPECIFIED_ADMIN
static bool plan_single_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, Oid member, Oid grantor, GrantRoleOptions *popt, DropBehavior behavior)
static GrantRoleOptions createrole_self_grant_options
static void InitGrantRoleOptions(GrantRoleOptions *popt)
static void plan_member_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, Oid member)
static void AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt)
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
Oid AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
static bool createrole_self_grant_enabled
#define GRANT_ROLE_SPECIFIED_SET
Oid AlterRoleSet(AlterRoleSetStmt *stmt)
static Oid check_role_grantor(Oid currentUserId, Oid roleid, Oid grantorId, bool is_grant)
bool check_createrole_self_grant(char **newval, void **extra, GucSource source)
void assign_createrole_self_grant(const char *newval, void *extra)
static void check_role_membership_authorization(Oid currentUserId, Oid roleid, bool is_grant)
Oid binary_upgrade_next_pg_authid_oid
#define GRANT_ROLE_SPECIFIED_INHERIT
void DropRole(DropRoleStmt *stmt)
Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
void GrantRole(ParseState *pstate, GrantRoleStmt *stmt)
List * roleSpecsToIds(List *memberNames)
static void plan_recursive_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, int index, bool revoke_admin_option_only, DropBehavior behavior)
char * createrole_self_grant
check_password_hook_type check_password_hook
@ RRG_REMOVE_INHERIT_OPTION
@ RRG_REMOVE_ADMIN_OPTION
static RevokeRoleGrantAction * initialize_revoke_actions(CatCList *memlist)
void DropOwnedObjects(DropOwnedStmt *stmt)
static void DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
void(* check_password_hook_type)(const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
void CommandCounterIncrement(void)