PostgreSQL Source Code git master
Loading...
Searching...
No Matches
user.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * user.c
4 * Commands for manipulating roles (formerly called users).
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * src/backend/commands/user.c
10 *
11 *-------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "access/genam.h"
16#include "access/htup_details.h"
17#include "access/table.h"
18#include "access/xact.h"
20#include "catalog/catalog.h"
21#include "catalog/dependency.h"
22#include "catalog/indexing.h"
25#include "catalog/pg_authid.h"
26#include "catalog/pg_database.h"
28#include "commands/comment.h"
29#include "commands/dbcommands.h"
30#include "commands/defrem.h"
31#include "commands/seclabel.h"
32#include "commands/user.h"
33#include "libpq/crypt.h"
34#include "miscadmin.h"
35#include "port/pg_bitutils.h"
36#include "storage/lmgr.h"
37#include "utils/acl.h"
38#include "utils/builtins.h"
39#include "utils/catcache.h"
40#include "utils/fmgroids.h"
41#include "utils/syscache.h"
42#include "utils/varlena.h"
43
44/*
45 * Removing a role grant - or the admin option on it - might recurse to
46 * dependent grants. We use these values to reason about what would need to
47 * be done in such cases.
48 *
49 * RRG_NOOP indicates a grant that would not need to be altered by the
50 * operation.
51 *
52 * RRG_REMOVE_ADMIN_OPTION indicates a grant that would need to have
53 * admin_option set to false by the operation.
54 *
55 * Similarly, RRG_REMOVE_INHERIT_OPTION and RRG_REMOVE_SET_OPTION indicate
56 * grants that would need to have the corresponding options set to false.
57 *
58 * RRG_DELETE_GRANT indicates a grant that would need to be removed entirely
59 * by the operation.
60 */
69
70/* Potentially set by pg_upgrade_support functions */
72
73typedef struct
74{
75 unsigned specified;
76 bool admin;
77 bool inherit;
78 bool set;
80
81#define GRANT_ROLE_SPECIFIED_ADMIN 0x0001
82#define GRANT_ROLE_SPECIFIED_INHERIT 0x0002
83#define GRANT_ROLE_SPECIFIED_SET 0x0004
84
85/* GUC parameters */
90
91/* Hook to check passwords in CreateRole() and AlterRole() */
93
94static void AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
97static void DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
100 DropBehavior behavior);
102 bool is_grant);
104 bool is_grant);
107 RevokeRoleGrantAction *actions,
108 Oid member, Oid grantor,
109 GrantRoleOptions *popt,
110 DropBehavior behavior);
112 RevokeRoleGrantAction *actions, Oid member);
114 RevokeRoleGrantAction *actions,
115 int index,
117 DropBehavior behavior);
118static void InitGrantRoleOptions(GrantRoleOptions *popt);
119
120
121/* Check if current user has createrole privileges */
122static bool
127
128
129/*
130 * CREATE ROLE
131 */
132Oid
134{
137 HeapTuple tuple;
141 Oid roleid;
142 ListCell *item;
144 char *password = NULL; /* user password */
145 bool issuper = false; /* Make the user a superuser? */
146 bool inherit = true; /* Auto inherit privileges? */
147 bool createrole = false; /* Can this user create roles? */
148 bool createdb = false; /* Can the user create databases? */
149 bool canlogin = false; /* Can this user login? */
150 bool isreplication = false; /* Is this a replication role? */
151 bool bypassrls = false; /* Is this a row security enabled role? */
152 int connlimit = -1; /* maximum connections allowed */
153 List *addroleto = NIL; /* roles to make this a member of */
154 List *rolemembers = NIL; /* roles to be members of this role */
155 List *adminmembers = NIL; /* roles to be admins of this role */
156 char *validUntil = NULL; /* time the login is valid until */
157 Datum validUntil_datum; /* same, as timestamptz Datum */
158 bool validUntil_null;
172 GrantRoleOptions popt;
173
174 /* Report error if name has \n or \r character. */
175 if (strpbrk(stmt->role, "\n\r"))
178 errmsg("role name \"%s\" contains a newline or carriage return character", stmt->role)));
179
180 /* The defaults can vary depending on the original statement type */
181 switch (stmt->stmt_type)
182 {
183 case ROLESTMT_ROLE:
184 break;
185 case ROLESTMT_USER:
186 canlogin = true;
187 /* may eventually want inherit to default to false here */
188 break;
189 case ROLESTMT_GROUP:
190 break;
191 }
192
193 /* Extract options from the statement node tree */
194 foreach(option, stmt->options)
195 {
197
198 if (strcmp(defel->defname, "password") == 0)
199 {
200 if (dpassword)
203 }
204 else if (strcmp(defel->defname, "sysid") == 0)
205 {
207 (errmsg("SYSID can no longer be specified")));
208 }
209 else if (strcmp(defel->defname, "superuser") == 0)
210 {
211 if (dissuper)
213 dissuper = defel;
214 }
215 else if (strcmp(defel->defname, "inherit") == 0)
216 {
217 if (dinherit)
219 dinherit = defel;
220 }
221 else if (strcmp(defel->defname, "createrole") == 0)
222 {
223 if (dcreaterole)
226 }
227 else if (strcmp(defel->defname, "createdb") == 0)
228 {
229 if (dcreatedb)
232 }
233 else if (strcmp(defel->defname, "canlogin") == 0)
234 {
235 if (dcanlogin)
238 }
239 else if (strcmp(defel->defname, "isreplication") == 0)
240 {
241 if (disreplication)
244 }
245 else if (strcmp(defel->defname, "connectionlimit") == 0)
246 {
247 if (dconnlimit)
250 }
251 else if (strcmp(defel->defname, "addroleto") == 0)
252 {
253 if (daddroleto)
256 }
257 else if (strcmp(defel->defname, "rolemembers") == 0)
258 {
259 if (drolemembers)
262 }
263 else if (strcmp(defel->defname, "adminmembers") == 0)
264 {
265 if (dadminmembers)
268 }
269 else if (strcmp(defel->defname, "validUntil") == 0)
270 {
271 if (dvalidUntil)
274 }
275 else if (strcmp(defel->defname, "bypassrls") == 0)
276 {
277 if (dbypassRLS)
280 }
281 else
282 elog(ERROR, "option \"%s\" not recognized",
283 defel->defname);
284 }
285
286 if (dpassword && dpassword->arg)
287 password = strVal(dpassword->arg);
288 if (dissuper)
289 issuper = boolVal(dissuper->arg);
290 if (dinherit)
291 inherit = boolVal(dinherit->arg);
292 if (dcreaterole)
294 if (dcreatedb)
295 createdb = boolVal(dcreatedb->arg);
296 if (dcanlogin)
297 canlogin = boolVal(dcanlogin->arg);
298 if (disreplication)
300 if (dconnlimit)
301 {
303 if (connlimit < -1)
306 errmsg("invalid connection limit: %d", connlimit)));
307 }
308 if (daddroleto)
309 addroleto = (List *) daddroleto->arg;
310 if (drolemembers)
311 rolemembers = (List *) drolemembers->arg;
312 if (dadminmembers)
314 if (dvalidUntil)
316 if (dbypassRLS)
318
319 /* Check some permissions first */
321 {
325 errmsg("permission denied to create role"),
326 errdetail("Only roles with the %s attribute may create roles.",
327 "CREATEROLE")));
328 if (issuper)
331 errmsg("permission denied to create role"),
332 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
333 "SUPERUSER", "SUPERUSER")));
337 errmsg("permission denied to create role"),
338 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
339 "CREATEDB", "CREATEDB")));
343 errmsg("permission denied to create role"),
344 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
345 "REPLICATION", "REPLICATION")));
349 errmsg("permission denied to create role"),
350 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
351 "BYPASSRLS", "BYPASSRLS")));
352 }
353
354 /*
355 * Check that the user is not trying to create a role in the reserved
356 * "pg_" namespace.
357 */
358 if (IsReservedName(stmt->role))
361 errmsg("role name \"%s\" is reserved",
362 stmt->role),
363 errdetail("Role names starting with \"pg_\" are reserved.")));
364
365 /*
366 * If built with appropriate switch, whine when regression-testing
367 * conventions for role names are violated.
368 */
369#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
370 if (strncmp(stmt->role, "regress_", 8) != 0)
371 elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
372#endif
373
374 /*
375 * Check the pg_authid relation to be certain the role doesn't already
376 * exist.
377 */
380
381 if (OidIsValid(get_role_oid(stmt->role, true)))
384 errmsg("role \"%s\" already exists",
385 stmt->role)));
386
387 /* Convert validuntil to internal form */
388 if (validUntil)
389 {
393 Int32GetDatum(-1));
394 validUntil_null = false;
395 }
396 else
397 {
399 validUntil_null = true;
400 }
401
402 /*
403 * Call the password checking hook if there is one defined
404 */
406 (*check_password_hook) (stmt->role,
407 password,
411
412 /*
413 * Build a tuple to insert
414 */
424
425 if (password)
426 {
427 char *shadow_pass;
428 const char *logdetail = NULL;
429
430 /*
431 * Don't allow an empty password. Libpq treats an empty password the
432 * same as no password at all, and won't even try to authenticate. But
433 * other clients might, so allowing it would be confusing. By clearing
434 * the password when an empty string is specified, the account is
435 * consistently locked for all clients.
436 *
437 * Note that this only covers passwords stored in the database itself.
438 * There are also checks in the authentication code, to forbid an
439 * empty password from being used with authentication methods that
440 * fetch the password from an external system, like LDAP or PAM.
441 */
442 if (password[0] == '\0' ||
443 plain_crypt_verify(stmt->role, password, "", &logdetail) == STATUS_OK)
444 {
446 (errmsg("empty string is not a valid password, clearing password")));
448 }
449 else
450 {
451 /* Encrypt the password to the requested format. */
453 password);
456 }
457 }
458 else
460
463
465
466 /*
467 * pg_largeobject_metadata contains pg_authid.oid's, so we use the
468 * binary-upgrade override.
469 */
470 if (IsBinaryUpgrade)
471 {
475 errmsg("pg_authid OID value not set when in binary upgrade mode")));
476
479 }
480 else
481 {
484 }
485
487
489
490 /*
491 * Insert new record in the pg_authid table
492 */
494
495 /*
496 * Advance command counter so we can see new record; else tests in
497 * AddRoleMems may fail.
498 */
501
502 /* Default grant. */
504
505 /*
506 * Add the new role to the specified existing roles.
507 */
508 if (addroleto)
509 {
513
514 thisrole->roletype = ROLESPEC_CSTRING;
515 thisrole->rolename = stmt->role;
516 thisrole->location = -1;
517
518 foreach(item, addroleto)
519 {
520 RoleSpec *oldrole = lfirst(item);
524 char *oldrolename = NameStr(oldroleform->rolname);
525
526 /* can only add this role to roles for which you have rights */
531 InvalidOid, &popt);
532
534 }
535 }
536
537 /*
538 * If the current user isn't a superuser, make them an admin of the new
539 * role so that they can administer the new object they just created.
540 * Superusers will be able to do that anyway.
541 *
542 * The grantor of record for this implicit grant is the bootstrap
543 * superuser, which means that the CREATEROLE user cannot revoke the
544 * grant. They can however grant the created role back to themselves with
545 * different options, since they enjoy ADMIN OPTION on it.
546 */
547 if (!superuser())
548 {
553
555 current_role->location = -1;
557
561 poptself.admin = true;
562 poptself.inherit = false;
563 poptself.set = false;
564
568
569 /*
570 * We must make the implicit grant visible to the code below, else the
571 * additional grants will fail.
572 */
574
575 /*
576 * Because of the implicit grant above, a CREATEROLE user who creates
577 * a role has the ability to grant that role back to themselves with
578 * the INHERIT or SET options, if they wish to inherit the role's
579 * privileges or be able to SET ROLE to it. The createrole_self_grant
580 * GUC can be used to make this happen automatically. This has no
581 * security implications since the same user is able to make the same
582 * grant using an explicit GRANT statement; it's just convenient.
583 */
585 AddRoleMems(currentUserId, stmt->role, roleid,
588 }
589
590 /*
591 * Add the specified members to this new role. adminmembers get the admin
592 * option, rolemembers don't.
593 *
594 * NB: No permissions check is required here. If you have enough rights to
595 * create a role, you can add any members you like.
596 */
597 AddRoleMems(currentUserId, stmt->role, roleid,
599 InvalidOid, &popt);
601 popt.admin = true;
602 AddRoleMems(currentUserId, stmt->role, roleid,
604 InvalidOid, &popt);
605
606 /* Post creation hook for new role */
608
609 /*
610 * Close pg_authid, but keep lock till commit.
611 */
613
614 return roleid;
615}
616
617
618/*
619 * ALTER ROLE
620 *
621 * Note: the rolemembers option accepted here is intended to support the
622 * backwards-compatible ALTER GROUP syntax. Although it will work to say
623 * "ALTER ROLE role ROLE rolenames", we don't document it.
624 */
625Oid
627{
633 HeapTuple tuple,
634 new_tuple;
637 char *rolename;
638 char *password = NULL; /* user password */
639 int connlimit = -1; /* maximum connections allowed */
640 char *validUntil = NULL; /* time the login is valid until */
641 Datum validUntil_datum; /* same, as timestamptz Datum */
642 bool validUntil_null;
654 Oid roleid;
656 GrantRoleOptions popt;
657
659 _("Cannot alter reserved roles."));
660
661 /* Extract options from the statement node tree */
662 foreach(option, stmt->options)
663 {
665
666 if (strcmp(defel->defname, "password") == 0)
667 {
668 if (dpassword)
671 }
672 else if (strcmp(defel->defname, "superuser") == 0)
673 {
674 if (dissuper)
676 dissuper = defel;
677 }
678 else if (strcmp(defel->defname, "inherit") == 0)
679 {
680 if (dinherit)
682 dinherit = defel;
683 }
684 else if (strcmp(defel->defname, "createrole") == 0)
685 {
686 if (dcreaterole)
689 }
690 else if (strcmp(defel->defname, "createdb") == 0)
691 {
692 if (dcreatedb)
695 }
696 else if (strcmp(defel->defname, "canlogin") == 0)
697 {
698 if (dcanlogin)
701 }
702 else if (strcmp(defel->defname, "isreplication") == 0)
703 {
704 if (disreplication)
707 }
708 else if (strcmp(defel->defname, "connectionlimit") == 0)
709 {
710 if (dconnlimit)
713 }
714 else if (strcmp(defel->defname, "rolemembers") == 0 &&
715 stmt->action != 0)
716 {
717 if (drolemembers)
720 }
721 else if (strcmp(defel->defname, "validUntil") == 0)
722 {
723 if (dvalidUntil)
726 }
727 else if (strcmp(defel->defname, "bypassrls") == 0)
728 {
729 if (dbypassRLS)
732 }
733 else
734 elog(ERROR, "option \"%s\" not recognized",
735 defel->defname);
736 }
737
738 if (dpassword && dpassword->arg)
739 password = strVal(dpassword->arg);
740 if (dconnlimit)
741 {
743 if (connlimit < -1)
746 errmsg("invalid connection limit: %d", connlimit)));
747 }
748 if (dvalidUntil)
750
751 /*
752 * Scan the pg_authid relation to be certain the user exists.
753 */
756
757 tuple = get_rolespec_tuple(stmt->role);
759 rolename = pstrdup(NameStr(authform->rolname));
760 roleid = authform->oid;
761
762 /* To mess with a superuser in any way you gotta be superuser. */
763 if (!superuser() && authform->rolsuper)
766 errmsg("permission denied to alter role"),
767 errdetail("Only roles with the %s attribute may alter roles with the %s attribute.",
768 "SUPERUSER", "SUPERUSER")));
769 if (!superuser() && dissuper)
772 errmsg("permission denied to alter role"),
773 errdetail("Only roles with the %s attribute may change the %s attribute.",
774 "SUPERUSER", "SUPERUSER")));
775
776 /*
777 * Most changes to a role require that you both have CREATEROLE privileges
778 * and also ADMIN OPTION on the role.
779 */
781 !is_admin_of_role(GetUserId(), roleid))
782 {
783 /* things an unprivileged user certainly can't do */
788 errmsg("permission denied to alter role"),
789 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
790 "CREATEROLE", "ADMIN", rolename)));
791
792 /* an unprivileged user can change their own password */
793 if (dpassword && roleid != currentUserId)
796 errmsg("permission denied to alter role"),
797 errdetail("To change another role's password, the current user must have the %s attribute and the %s option on the role.",
798 "CREATEROLE", "ADMIN")));
799 }
800 else if (!superuser())
801 {
802 /*
803 * Even if you have both CREATEROLE and ADMIN OPTION on a role, you
804 * can only change the CREATEDB, REPLICATION, or BYPASSRLS attributes
805 * if they are set for your own role (or you are the superuser).
806 */
810 errmsg("permission denied to alter role"),
811 errdetail("Only roles with the %s attribute may change the %s attribute.",
812 "CREATEDB", "CREATEDB")));
816 errmsg("permission denied to alter role"),
817 errdetail("Only roles with the %s attribute may change the %s attribute.",
818 "REPLICATION", "REPLICATION")));
822 errmsg("permission denied to alter role"),
823 errdetail("Only roles with the %s attribute may change the %s attribute.",
824 "BYPASSRLS", "BYPASSRLS")));
825 }
826
827 /* To add or drop members, you need ADMIN OPTION. */
831 errmsg("permission denied to alter role"),
832 errdetail("Only roles with the %s option on role \"%s\" may add or drop members.",
833 "ADMIN", rolename)));
834
835 /* Convert validuntil to internal form */
836 if (dvalidUntil)
837 {
841 Int32GetDatum(-1));
842 validUntil_null = false;
843 }
844 else
845 {
846 /* fetch existing setting in case hook needs it */
850 }
851
852 /*
853 * Call the password checking hook if there is one defined
854 */
856 (*check_password_hook) (rolename,
857 password,
861
862 /*
863 * Build an updated tuple, perusing the information just obtained
864 */
865
866 /*
867 * issuper/createrole/etc
868 */
869 if (dissuper)
870 {
871 bool should_be_super = boolVal(dissuper->arg);
872
873 if (!should_be_super && roleid == BOOTSTRAP_SUPERUSERID)
876 errmsg("permission denied to alter role"),
877 errdetail("The bootstrap superuser must have the %s attribute.",
878 "SUPERUSER")));
879
882 }
883
884 if (dinherit)
885 {
888 }
889
890 if (dcreaterole)
891 {
894 }
895
896 if (dcreatedb)
897 {
900 }
901
902 if (dcanlogin)
903 {
906 }
907
908 if (disreplication)
909 {
912 }
913
914 if (dconnlimit)
915 {
918 }
919
920 /* password */
921 if (password)
922 {
923 char *shadow_pass;
924 const char *logdetail = NULL;
925
926 /* Like in CREATE USER, don't allow an empty password. */
927 if (password[0] == '\0' ||
928 plain_crypt_verify(rolename, password, "", &logdetail) == STATUS_OK)
929 {
931 (errmsg("empty string is not a valid password, clearing password")));
933 }
934 else
935 {
936 /* Encrypt the password to the requested format. */
938 password);
941 }
943 }
944
945 /* unset password */
946 if (dpassword && dpassword->arg == NULL)
947 {
950 }
951
952 /* valid until */
956
957 if (dbypassRLS)
958 {
961 }
962
966
968
969 ReleaseSysCache(tuple);
971
973
974 /*
975 * Advance command counter so we can see new record; else tests in
976 * AddRoleMems may fail.
977 */
978 if (drolemembers)
979 {
980 List *rolemembers = (List *) drolemembers->arg;
981
983
984 if (stmt->action == +1) /* add members to role */
985 AddRoleMems(currentUserId, rolename, roleid,
987 InvalidOid, &popt);
988 else if (stmt->action == -1) /* drop members from role */
989 DelRoleMems(currentUserId, rolename, roleid,
991 InvalidOid, &popt, DROP_RESTRICT);
992 }
993
994 /*
995 * Close pg_authid, but keep lock till commit.
996 */
998
999 return roleid;
1000}
1001
1002
1003/*
1004 * ALTER ROLE ... SET
1005 */
1006Oid
1008{
1012 Oid roleid = InvalidOid;
1013
1014 if (stmt->role)
1015 {
1017 _("Cannot alter reserved roles."));
1018
1021 roleid = roleform->oid;
1022
1023 /*
1024 * Obtain a lock on the role and make sure it didn't go away in the
1025 * meantime.
1026 */
1028
1029 /*
1030 * To mess with a superuser you gotta be superuser; otherwise you need
1031 * CREATEROLE plus admin option on the target role; unless you're just
1032 * trying to change your own settings
1033 */
1034 if (roleform->rolsuper)
1035 {
1036 if (!superuser())
1037 ereport(ERROR,
1039 errmsg("permission denied to alter role"),
1040 errdetail("Only roles with the %s attribute may alter roles with the %s attribute.",
1041 "SUPERUSER", "SUPERUSER")));
1042 }
1043 else
1044 {
1045 if ((!have_createrole_privilege() ||
1046 !is_admin_of_role(GetUserId(), roleid))
1047 && roleid != GetUserId())
1048 ereport(ERROR,
1050 errmsg("permission denied to alter role"),
1051 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
1052 "CREATEROLE", "ADMIN", NameStr(roleform->rolname))));
1053 }
1054
1056 }
1057
1058 /* look up and lock the database, if specified */
1059 if (stmt->database != NULL)
1060 {
1061 databaseid = get_database_oid(stmt->database, false);
1063
1064 if (!stmt->role)
1065 {
1066 /*
1067 * If no role is specified, then this is effectively the same as
1068 * ALTER DATABASE ... SET, so use the same permission check.
1069 */
1072 stmt->database);
1073 }
1074 }
1075
1076 if (!stmt->role && !stmt->database)
1077 {
1078 /* Must be superuser to alter settings globally. */
1079 if (!superuser())
1080 ereport(ERROR,
1082 errmsg("permission denied to alter setting"),
1083 errdetail("Only roles with the %s attribute may alter settings globally.",
1084 "SUPERUSER")));
1085 }
1086
1087 AlterSetting(databaseid, roleid, stmt->setstmt);
1088
1089 return roleid;
1090}
1091
1092
1093/*
1094 * DROP ROLE
1095 */
1096void
1098{
1101 ListCell *item;
1102 List *role_oids = NIL;
1103
1105 ereport(ERROR,
1107 errmsg("permission denied to drop role"),
1108 errdetail("Only roles with the %s attribute and the %s option on the target roles may drop roles.",
1109 "CREATEROLE", "ADMIN")));
1110
1111 /*
1112 * Scan the pg_authid relation to find the Oid of the role(s) to be
1113 * deleted and perform preliminary permissions and sanity checks.
1114 */
1117
1118 foreach(item, stmt->roles)
1119 {
1120 RoleSpec *rolspec = lfirst(item);
1121 char *role;
1122 HeapTuple tuple,
1123 tmp_tuple;
1127 Oid roleid;
1128
1129 if (rolspec->roletype != ROLESPEC_CSTRING)
1130 ereport(ERROR,
1132 errmsg("cannot use special role specifier in DROP ROLE")));
1133 role = rolspec->rolename;
1134
1136 if (!HeapTupleIsValid(tuple))
1137 {
1138 if (!stmt->missing_ok)
1139 {
1140 ereport(ERROR,
1142 errmsg("role \"%s\" does not exist", role)));
1143 }
1144 else
1145 {
1147 (errmsg("role \"%s\" does not exist, skipping",
1148 role)));
1149 }
1150
1151 continue;
1152 }
1153
1155 roleid = roleform->oid;
1156
1157 if (roleid == GetUserId())
1158 ereport(ERROR,
1160 errmsg("current user cannot be dropped")));
1161 if (roleid == GetOuterUserId())
1162 ereport(ERROR,
1164 errmsg("current user cannot be dropped")));
1165 if (roleid == GetSessionUserId())
1166 ereport(ERROR,
1168 errmsg("session user cannot be dropped")));
1169
1170 /*
1171 * For safety's sake, we allow createrole holders to drop ordinary
1172 * roles but not superuser roles, and only if they also have ADMIN
1173 * OPTION.
1174 */
1175 if (roleform->rolsuper && !superuser())
1176 ereport(ERROR,
1178 errmsg("permission denied to drop role"),
1179 errdetail("Only roles with the %s attribute may drop roles with the %s attribute.",
1180 "SUPERUSER", "SUPERUSER")));
1181 if (!is_admin_of_role(GetUserId(), roleid))
1182 ereport(ERROR,
1184 errmsg("permission denied to drop role"),
1185 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may drop this role.",
1186 "CREATEROLE", "ADMIN", NameStr(roleform->rolname))));
1187
1188 /* DROP hook for the role being removed */
1190
1191 /* Don't leak the syscache tuple */
1192 ReleaseSysCache(tuple);
1193
1194 /*
1195 * Lock the role, so nobody can add dependencies to her while we drop
1196 * her. We keep the lock until the end of transaction.
1197 */
1199
1200 /*
1201 * If there is a pg_auth_members entry that has one of the roles to be
1202 * dropped as the roleid or member, it should be silently removed, but
1203 * if there is a pg_auth_members entry that has one of the roles to be
1204 * dropped as the grantor, the operation should fail.
1205 *
1206 * It's possible, however, that a single pg_auth_members entry could
1207 * fall into multiple categories - e.g. the user could do "GRANT foo
1208 * TO bar GRANTED BY baz" and then "DROP ROLE baz, bar". We want such
1209 * an operation to succeed regardless of the order in which the
1210 * to-be-dropped roles are passed to DROP ROLE.
1211 *
1212 * To make that work, we remove all pg_auth_members entries that can
1213 * be silently removed in this loop, and then below we'll make a
1214 * second pass over the list of roles to be removed and check for any
1215 * remaining dependencies.
1216 */
1220 ObjectIdGetDatum(roleid));
1221
1223 true, NULL, 1, &scankey);
1224
1226 {
1228
1231 authmem_form->oid, 0);
1233 }
1234
1236
1240 ObjectIdGetDatum(roleid));
1241
1243 true, NULL, 1, &scankey);
1244
1246 {
1248
1251 authmem_form->oid, 0);
1253 }
1254
1256
1257 /*
1258 * Advance command counter so that later iterations of this loop will
1259 * see the changes already made. This is essential if, for example,
1260 * we are trying to drop both a role and one of its direct members ---
1261 * we'll get an error if we try to delete the linking pg_auth_members
1262 * tuple twice. (We do not need a CCI between the two delete loops
1263 * above, because it's not allowed for a role to directly contain
1264 * itself.)
1265 */
1267
1268 /* Looks tentatively OK, add it to the list if not there yet. */
1270 }
1271
1272 /*
1273 * Second pass over the roles to be removed.
1274 */
1275 foreach(item, role_oids)
1276 {
1277 Oid roleid = lfirst_oid(item);
1278 HeapTuple tuple;
1280 char *detail;
1281 char *detail_log;
1282
1283 /*
1284 * Re-find the pg_authid tuple.
1285 *
1286 * Since we've taken a lock on the role OID, it shouldn't be possible
1287 * for the tuple to have been deleted -- or for that matter updated --
1288 * unless the user is manually modifying the system catalogs.
1289 */
1290 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
1291 if (!HeapTupleIsValid(tuple))
1292 elog(ERROR, "could not find tuple for role %u", roleid);
1294
1295 /*
1296 * Check for pg_shdepend entries depending on this role.
1297 *
1298 * This needs to happen after we've completed removing any
1299 * pg_auth_members entries that can be removed silently, in order to
1300 * avoid spurious failures. See notes above for more details.
1301 */
1303 &detail, &detail_log))
1304 ereport(ERROR,
1306 errmsg("role \"%s\" cannot be dropped because some objects depend on it",
1307 NameStr(roleform->rolname)),
1308 errdetail_internal("%s", detail),
1309 errdetail_log("%s", detail_log)));
1310
1311 /*
1312 * Remove the role from the pg_authid table
1313 */
1315
1316 ReleaseSysCache(tuple);
1317
1318 /*
1319 * Remove any comments or security labels on this role.
1320 */
1323
1324 /*
1325 * Remove settings for this role.
1326 */
1327 DropSetting(InvalidOid, roleid);
1328 }
1329
1330 /*
1331 * Now we can clean up; but keep locks until commit.
1332 */
1335}
1336
1337/*
1338 * Rename role
1339 */
1341RenameRole(const char *oldname, const char *newname)
1342{
1343 HeapTuple oldtuple,
1344 newtuple;
1345 TupleDesc dsc;
1346 Relation rel;
1347 Datum datum;
1348 bool isnull;
1352 int i;
1353 Oid roleid;
1354 ObjectAddress address;
1356
1357 /* Report error if name has \n or \r character. */
1358 if (strpbrk(newname, "\n\r"))
1359 ereport(ERROR,
1361 errmsg("role name \"%s\" contains a newline or carriage return character", newname)));
1362
1364 dsc = RelationGetDescr(rel);
1365
1367 if (!HeapTupleIsValid(oldtuple))
1368 ereport(ERROR,
1370 errmsg("role \"%s\" does not exist", oldname)));
1371
1372 /*
1373 * XXX Client applications probably store the session user somewhere, so
1374 * renaming it could cause confusion. On the other hand, there may not be
1375 * an actual problem besides a little confusion, so think about this and
1376 * decide. Same for SET ROLE ... we don't restrict renaming the current
1377 * effective userid, though.
1378 */
1379
1380 authform = (Form_pg_authid) GETSTRUCT(oldtuple);
1381 roleid = authform->oid;
1382
1383 if (roleid == GetSessionUserId())
1384 ereport(ERROR,
1386 errmsg("session user cannot be renamed")));
1387 if (roleid == GetOuterUserId())
1388 ereport(ERROR,
1390 errmsg("current user cannot be renamed")));
1391
1392 /*
1393 * Check that the user is not trying to rename a system role and not
1394 * trying to rename a role into the reserved "pg_" namespace.
1395 */
1396 if (IsReservedName(NameStr(authform->rolname)))
1397 ereport(ERROR,
1399 errmsg("role name \"%s\" is reserved",
1400 NameStr(authform->rolname)),
1401 errdetail("Role names starting with \"pg_\" are reserved.")));
1402
1403 if (IsReservedName(newname))
1404 ereport(ERROR,
1406 errmsg("role name \"%s\" is reserved",
1407 newname),
1408 errdetail("Role names starting with \"pg_\" are reserved.")));
1409
1410 /*
1411 * If built with appropriate switch, whine when regression-testing
1412 * conventions for role names are violated.
1413 */
1414#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1415 if (strncmp(newname, "regress_", 8) != 0)
1416 elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
1417#endif
1418
1419 /* make sure the new name doesn't exist */
1421 ereport(ERROR,
1423 errmsg("role \"%s\" already exists", newname)));
1424
1425 /*
1426 * Only superusers can mess with superusers. Otherwise, a user with
1427 * CREATEROLE can rename a role for which they have ADMIN OPTION.
1428 */
1429 if (authform->rolsuper)
1430 {
1431 if (!superuser())
1432 ereport(ERROR,
1434 errmsg("permission denied to rename role"),
1435 errdetail("Only roles with the %s attribute may rename roles with the %s attribute.",
1436 "SUPERUSER", "SUPERUSER")));
1437 }
1438 else
1439 {
1441 !is_admin_of_role(GetUserId(), roleid))
1442 ereport(ERROR,
1444 errmsg("permission denied to rename role"),
1445 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may rename this role.",
1446 "CREATEROLE", "ADMIN", NameStr(authform->rolname))));
1447 }
1448
1449 /* OK, construct the modified tuple */
1450 for (i = 0; i < Natts_pg_authid; i++)
1451 repl_repl[i] = false;
1452
1455 CStringGetDatum(newname));
1456 repl_null[Anum_pg_authid_rolname - 1] = false;
1457
1458 datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1459
1461 {
1462 /* MD5 uses the username as salt, so just clear it on a rename */
1465
1467 (errmsg("MD5 password cleared because of role rename")));
1468 }
1469
1470 newtuple = heap_modify_tuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
1471 CatalogTupleUpdate(rel, &oldtuple->t_self, newtuple);
1472
1474
1475 ObjectAddressSet(address, AuthIdRelationId, roleid);
1476
1477 ReleaseSysCache(oldtuple);
1478
1479 /*
1480 * Close pg_authid, but keep lock till commit.
1481 */
1482 table_close(rel, NoLock);
1483
1484 return address;
1485}
1486
1487/*
1488 * GrantRoleStmt
1489 *
1490 * Grant/Revoke roles to/from roles
1491 */
1492void
1494{
1496 Oid grantor;
1498 ListCell *item;
1499 GrantRoleOptions popt;
1501
1502 /* Parse options list. */
1503 InitGrantRoleOptions(&popt);
1504 foreach(item, stmt->opt)
1505 {
1506 DefElem *opt = (DefElem *) lfirst(item);
1507 char *optval = defGetString(opt);
1508
1509 if (strcmp(opt->defname, "admin") == 0)
1510 {
1512
1513 if (parse_bool(optval, &popt.admin))
1514 continue;
1515 }
1516 else if (strcmp(opt->defname, "inherit") == 0)
1517 {
1519 if (parse_bool(optval, &popt.inherit))
1520 continue;
1521 }
1522 else if (strcmp(opt->defname, "set") == 0)
1523 {
1525 if (parse_bool(optval, &popt.set))
1526 continue;
1527 }
1528 else
1529 ereport(ERROR,
1531 errmsg("unrecognized role option \"%s\"", opt->defname),
1532 parser_errposition(pstate, opt->location));
1533
1534 ereport(ERROR,
1536 errmsg("unrecognized value for role option \"%s\": \"%s\"",
1537 opt->defname, optval),
1538 parser_errposition(pstate, opt->location)));
1539 }
1540
1541 /* Lookup OID of grantor, if specified. */
1542 if (stmt->grantor)
1543 grantor = get_rolespec_oid(stmt->grantor, false);
1544 else
1545 grantor = InvalidOid;
1546
1547 grantee_ids = roleSpecsToIds(stmt->grantee_roles);
1548
1549 /* AccessShareLock is enough since we aren't modifying pg_authid */
1551
1552 /*
1553 * Step through all of the granted roles and add, update, or remove
1554 * entries in pg_auth_members as appropriate. If stmt->is_grant is true,
1555 * we are adding new grants or, if they already exist, updating options on
1556 * those grants. If stmt->is_grant is false, we are revoking grants or
1557 * removing options from them.
1558 */
1559 foreach(item, stmt->granted_roles)
1560 {
1561 AccessPriv *priv = (AccessPriv *) lfirst(item);
1562 char *rolename = priv->priv_name;
1563 Oid roleid;
1564
1565 /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1566 if (rolename == NULL || priv->cols != NIL)
1567 ereport(ERROR,
1569 errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
1570
1571 roleid = get_role_oid(rolename, false);
1573 roleid, stmt->is_grant);
1574 if (stmt->is_grant)
1575 AddRoleMems(currentUserId, rolename, roleid,
1576 stmt->grantee_roles, grantee_ids,
1577 grantor, &popt);
1578 else
1579 DelRoleMems(currentUserId, rolename, roleid,
1580 stmt->grantee_roles, grantee_ids,
1581 grantor, &popt, stmt->behavior);
1582 }
1583
1584 /*
1585 * Close pg_authid, but keep lock till commit.
1586 */
1588}
1589
1590/*
1591 * DropOwnedObjects
1592 *
1593 * Drop the objects owned by a given list of roles.
1594 */
1595void
1597{
1598 List *role_ids = roleSpecsToIds(stmt->roles);
1599 ListCell *cell;
1600
1601 /* Check privileges */
1602 foreach(cell, role_ids)
1603 {
1604 Oid roleid = lfirst_oid(cell);
1605
1606 if (!has_privs_of_role(GetUserId(), roleid))
1607 ereport(ERROR,
1609 errmsg("permission denied to drop objects"),
1610 errdetail("Only roles with privileges of role \"%s\" may drop objects owned by it.",
1611 GetUserNameFromId(roleid, false))));
1612 }
1613
1614 /* Ok, do it */
1615 shdepDropOwned(role_ids, stmt->behavior);
1616}
1617
1618/*
1619 * ReassignOwnedObjects
1620 *
1621 * Give the objects owned by a given list of roles away to another user.
1622 */
1623void
1625{
1626 List *role_ids = roleSpecsToIds(stmt->roles);
1627 ListCell *cell;
1628 Oid newrole;
1629
1630 /* Check privileges */
1631 foreach(cell, role_ids)
1632 {
1633 Oid roleid = lfirst_oid(cell);
1634
1635 if (!has_privs_of_role(GetUserId(), roleid))
1636 ereport(ERROR,
1638 errmsg("permission denied to reassign objects"),
1639 errdetail("Only roles with privileges of role \"%s\" may reassign objects owned by it.",
1640 GetUserNameFromId(roleid, false))));
1641 }
1642
1643 /* Must have privileges on the receiving side too */
1644 newrole = get_rolespec_oid(stmt->newrole, false);
1645
1646 if (!has_privs_of_role(GetUserId(), newrole))
1647 ereport(ERROR,
1649 errmsg("permission denied to reassign objects"),
1650 errdetail("Only roles with privileges of role \"%s\" may reassign objects to it.",
1651 GetUserNameFromId(newrole, false))));
1652
1653 /* Ok, do it */
1654 shdepReassignOwned(role_ids, newrole);
1655}
1656
1657/*
1658 * roleSpecsToIds
1659 *
1660 * Given a list of RoleSpecs, generate a list of role OIDs in the same order.
1661 *
1662 * ROLESPEC_PUBLIC is not allowed.
1663 */
1664List *
1666{
1667 List *result = NIL;
1668 ListCell *l;
1669
1670 foreach(l, memberNames)
1671 {
1673 Oid roleid;
1674
1675 roleid = get_rolespec_oid(rolespec, false);
1676 result = lappend_oid(result, roleid);
1677 }
1678 return result;
1679}
1680
1681/*
1682 * AddRoleMems -- Add given members to the specified role
1683 *
1684 * currentUserId: OID of role performing the operation
1685 * rolename: name of role to add to (used only for error messages)
1686 * roleid: OID of role to add to
1687 * memberSpecs: list of RoleSpec of roles to add (used only for error messages)
1688 * memberIds: OIDs of roles to add
1689 * grantorId: OID that should be recorded as having granted the membership
1690 * (InvalidOid if not set explicitly)
1691 * popt: information about grant options
1692 */
1693static void
1694AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
1697{
1702
1704
1705 /* Validate grantor (and resolve implicit grantor if not specified). */
1707
1710
1711 /*
1712 * Only allow changes to this role by one backend at a time, so that we
1713 * can check integrity constraints like the lack of circular ADMIN OPTION
1714 * grants without fear of race conditions.
1715 */
1718
1719 /* Preliminary sanity checks. */
1721 {
1724
1725 /*
1726 * pg_database_owner is never a role member. Lifting this restriction
1727 * would require a policy decision about membership loops. One could
1728 * prevent loops, which would include making "ALTER DATABASE x OWNER
1729 * TO proposed_datdba" fail if is_member_of_role(pg_database_owner,
1730 * proposed_datdba). Hence, gaining a membership could reduce what a
1731 * role could do. Alternately, one could allow these memberships to
1732 * complete loops. A role could then have actual WITH ADMIN OPTION on
1733 * itself, prompting a decision about is_admin_of_role() treatment of
1734 * the case.
1735 *
1736 * Lifting this restriction also has policy implications for ownership
1737 * of shared objects (databases and tablespaces). We allow such
1738 * ownership, but we might find cause to ban it in the future.
1739 * Designing such a ban would more troublesome if the design had to
1740 * address pg_database_owner being a member of role FOO that owns a
1741 * shared object. (The effect of such ownership is that any owner of
1742 * another database can act as the owner of affected shared objects.)
1743 */
1745 ereport(ERROR,
1747 errmsg("role \"%s\" cannot be a member of any role",
1749
1750 /*
1751 * Refuse creation of membership loops, including the trivial case
1752 * where a role is made a member of itself. We do this by checking to
1753 * see if the target role is already a member of the proposed member
1754 * role. We have to ignore possible superuserness, however, else we
1755 * could never grant membership in a superuser-privileged role.
1756 */
1758 ereport(ERROR,
1760 errmsg("role \"%s\" is a member of role \"%s\"",
1761 rolename, get_rolespec_name(memberRole))));
1762 }
1763
1764 /*
1765 * Disallow attempts to grant ADMIN OPTION back to a user who granted it
1766 * to you, similar to what check_circularity does for ACLs. We want the
1767 * chains of grants to remain acyclic, so that it's always possible to use
1768 * REVOKE .. CASCADE to clean up all grants that depend on the one being
1769 * revoked.
1770 *
1771 * NB: This check might look redundant with the check for membership loops
1772 * above, but it isn't. That's checking for role-member loop (e.g. A is a
1773 * member of B and B is a member of A) while this is checking for a
1774 * member-grantor loop (e.g. A gave ADMIN OPTION on X to B and now B, who
1775 * has no other source of ADMIN OPTION on X, tries to give ADMIN OPTION on
1776 * X back to A).
1777 */
1778 if (popt->admin && grantorId != BOOTSTRAP_SUPERUSERID)
1779 {
1781 RevokeRoleGrantAction *actions;
1782 int i;
1783
1784 /* Get the list of members for this role. */
1786 ObjectIdGetDatum(roleid));
1787
1788 /*
1789 * Figure out what would happen if we removed all existing grants to
1790 * every role to which we've been asked to make a new grant.
1791 */
1793 foreach(iditem, memberIds)
1794 {
1796
1798 ereport(ERROR,
1800 errmsg("%s option cannot be granted back to your own grantor",
1801 "ADMIN")));
1803 }
1804
1805 /*
1806 * If the result would be that the grantor role would no longer have
1807 * the ability to perform the grant, then the proposed grant would
1808 * create a circularity.
1809 */
1810 for (i = 0; i < memlist->n_members; ++i)
1811 {
1814
1815 authmem_tuple = &memlist->members[i]->tuple;
1817
1818 if (actions[i] == RRG_NOOP &&
1819 authmem_form->member == grantorId &&
1820 authmem_form->admin_option)
1821 break;
1822 }
1823 if (i >= memlist->n_members)
1824 ereport(ERROR,
1826 errmsg("%s option cannot be granted back to your own grantor",
1827 "ADMIN")));
1828
1830 }
1831
1832 /* Now perform the catalog updates. */
1834 {
1838 HeapTuple tuple;
1842
1843 /* Common initialization for possible insert or update */
1845 ObjectIdGetDatum(roleid);
1850
1851 /* Find any existing tuple */
1853 ObjectIdGetDatum(roleid),
1856
1857 /*
1858 * If we found a tuple, update it with new option values, unless there
1859 * are no changes, in which case issue a WARNING.
1860 *
1861 * If we didn't find a tuple, just insert one.
1862 */
1864 {
1866 bool at_least_one_change = false;
1867
1869
1870 if ((popt->specified & GRANT_ROLE_SPECIFIED_ADMIN) != 0
1871 && authmem_form->admin_option != popt->admin)
1872 {
1874 BoolGetDatum(popt->admin);
1876 true;
1877 at_least_one_change = true;
1878 }
1879
1880 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0
1881 && authmem_form->inherit_option != popt->inherit)
1882 {
1884 BoolGetDatum(popt->inherit);
1886 true;
1887 at_least_one_change = true;
1888 }
1889
1890 if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0
1891 && authmem_form->set_option != popt->set)
1892 {
1894 BoolGetDatum(popt->set);
1896 true;
1897 at_least_one_change = true;
1898 }
1899
1901 {
1903 (errmsg("role \"%s\" has already been granted membership in role \"%s\" by role \"%s\"",
1904 get_rolespec_name(memberRole), rolename,
1905 GetUserNameFromId(grantorId, false))));
1907 continue;
1908 }
1909
1911 new_record,
1913 CatalogTupleUpdate(pg_authmem_rel, &tuple->t_self, tuple);
1914
1916 }
1917 else
1918 {
1919 Oid objectId;
1921
1922 /*
1923 * The values for these options can be taken directly from 'popt'.
1924 * Either they were specified, or the defaults as set by
1925 * InitGrantRoleOptions are correct.
1926 */
1928 BoolGetDatum(popt->admin);
1930 BoolGetDatum(popt->set);
1931
1932 /*
1933 * If the user specified a value for the inherit option, use
1934 * whatever was specified. Otherwise, set the default value based
1935 * on the role-level property.
1936 */
1937 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0)
1939 BoolGetDatum(popt->inherit);
1940 else
1941 {
1944
1946 if (!HeapTupleIsValid(mrtup))
1947 elog(ERROR, "cache lookup failed for role %u", memberid);
1950 BoolGetDatum(mrform->rolinherit);
1952 }
1953
1954 /* get an OID for the new row and insert it */
1961
1962 /* updateAclDependencies wants to pfree array inputs */
1963 newmembers[0] = grantorId;
1965 0, InvalidOid,
1966 0, NULL,
1967 1, newmembers);
1968 }
1969
1970 /* CCI after each change, in case there are duplicates in list */
1972 }
1973
1974 /*
1975 * Close pg_authmem, but keep lock till commit.
1976 */
1978}
1979
1980/*
1981 * DelRoleMems -- Remove given members from the specified role
1982 *
1983 * rolename: name of role to del from (used only for error messages)
1984 * roleid: OID of role to del from
1985 * memberSpecs: list of RoleSpec of roles to del (used only for error messages)
1986 * memberIds: OIDs of roles to del
1987 * grantorId: who is revoking the membership
1988 * popt: information about grant options
1989 * behavior: RESTRICT or CASCADE behavior for recursive removal
1990 */
1991static void
1992DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
1994 Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
1995{
2001 RevokeRoleGrantAction *actions;
2002 int i;
2003
2005
2006 /* Validate grantor (and resolve implicit grantor if not specified). */
2008
2011
2012 /*
2013 * Only allow changes to this role by one backend at a time, so that we
2014 * can check for things like dependent privileges without fear of race
2015 * conditions.
2016 */
2019
2022
2023 /*
2024 * We may need to recurse to dependent privileges if DROP_CASCADE was
2025 * specified, or refuse to perform the operation if dependent privileges
2026 * exist and DROP_RESTRICT was specified. plan_single_revoke() will figure
2027 * out what to do with each catalog tuple.
2028 */
2030 {
2033
2035 popt, behavior))
2036 {
2038 (errmsg("role \"%s\" has not been granted membership in role \"%s\" by role \"%s\"",
2039 get_rolespec_name(memberRole), rolename,
2040 GetUserNameFromId(grantorId, false))));
2041 continue;
2042 }
2043 }
2044
2045 /*
2046 * We now know what to do with each catalog tuple: it should either be
2047 * left alone, deleted, or just have the admin_option flag cleared.
2048 * Perform the appropriate action in each case.
2049 */
2050 for (i = 0; i < memlist->n_members; ++i)
2051 {
2054
2055 if (actions[i] == RRG_NOOP)
2056 continue;
2057
2058 authmem_tuple = &memlist->members[i]->tuple;
2060
2061 if (actions[i] == RRG_DELETE_GRANT)
2062 {
2063 /*
2064 * Remove the entry altogether, after first removing its
2065 * dependencies
2066 */
2068 authmem_form->oid, 0);
2070 }
2071 else
2072 {
2073 /* Just turn off the specified option */
2074 HeapTuple tuple;
2078
2079 /* Build a tuple to update with */
2080 if (actions[i] == RRG_REMOVE_ADMIN_OPTION)
2081 {
2083 BoolGetDatum(false);
2085 true;
2086 }
2087 else if (actions[i] == RRG_REMOVE_INHERIT_OPTION)
2088 {
2090 BoolGetDatum(false);
2092 true;
2093 }
2094 else if (actions[i] == RRG_REMOVE_SET_OPTION)
2095 {
2097 BoolGetDatum(false);
2099 true;
2100 }
2101 else
2102 elog(ERROR, "unknown role revoke action");
2103
2105 new_record,
2107 CatalogTupleUpdate(pg_authmem_rel, &tuple->t_self, tuple);
2108 }
2109 }
2110
2112
2113 /*
2114 * Close pg_authmem, but keep lock till commit.
2115 */
2117}
2118
2119/*
2120 * Check that currentUserId has permission to modify the membership list for
2121 * roleid. Throw an error if not.
2122 */
2123static void
2125 bool is_grant)
2126{
2127 /*
2128 * The charter of pg_database_owner is to have exactly one, implicit,
2129 * situation-dependent member. There's no technical need for this
2130 * restriction. (One could lift it and take the further step of making
2131 * object_ownercheck(DatabaseRelationId, ...) equivalent to
2132 * has_privs_of_role(roleid, ROLE_PG_DATABASE_OWNER), in which case
2133 * explicit, situation-independent members could act as the owner of any
2134 * database.)
2135 */
2136 if (is_grant && roleid == ROLE_PG_DATABASE_OWNER)
2137 ereport(ERROR,
2139 errmsg("role \"%s\" cannot have explicit members",
2140 GetUserNameFromId(roleid, false)));
2141
2142 /* To mess with a superuser role, you gotta be superuser. */
2143 if (superuser_arg(roleid))
2144 {
2146 {
2147 if (is_grant)
2148 ereport(ERROR,
2150 errmsg("permission denied to grant role \"%s\"",
2151 GetUserNameFromId(roleid, false)),
2152 errdetail("Only roles with the %s attribute may grant roles with the %s attribute.",
2153 "SUPERUSER", "SUPERUSER")));
2154 else
2155 ereport(ERROR,
2157 errmsg("permission denied to revoke role \"%s\"",
2158 GetUserNameFromId(roleid, false)),
2159 errdetail("Only roles with the %s attribute may revoke roles with the %s attribute.",
2160 "SUPERUSER", "SUPERUSER")));
2161 }
2162 }
2163 else
2164 {
2165 /*
2166 * Otherwise, must have admin option on the role to be changed.
2167 */
2168 if (!is_admin_of_role(currentUserId, roleid))
2169 {
2170 if (is_grant)
2171 ereport(ERROR,
2173 errmsg("permission denied to grant role \"%s\"",
2174 GetUserNameFromId(roleid, false)),
2175 errdetail("Only roles with the %s option on role \"%s\" may grant this role.",
2176 "ADMIN", GetUserNameFromId(roleid, false))));
2177 else
2178 ereport(ERROR,
2180 errmsg("permission denied to revoke role \"%s\"",
2181 GetUserNameFromId(roleid, false)),
2182 errdetail("Only roles with the %s option on role \"%s\" may revoke this role.",
2183 "ADMIN", GetUserNameFromId(roleid, false))));
2184 }
2185 }
2186}
2187
2188/*
2189 * Sanity-check, or infer, the grantor for a GRANT or REVOKE statement
2190 * targeting a role.
2191 *
2192 * The grantor must always be either a role with ADMIN OPTION on the role in
2193 * which membership is being granted, or the bootstrap superuser. This is
2194 * similar to the restriction enforced by select_best_grantor, except that
2195 * roles don't have owners, so we regard the bootstrap superuser as the
2196 * implicit owner.
2197 *
2198 * If the grantor was not explicitly specified by the user, grantorId should
2199 * be passed as InvalidOid, and this function will infer the user to be
2200 * recorded as the grantor. In many cases, this will be the current user, but
2201 * things get more complicated when the current user doesn't possess ADMIN
2202 * OPTION on the role but rather relies on having SUPERUSER privileges, or
2203 * on inheriting the privileges of a role which does have ADMIN OPTION. See
2204 * below for details.
2205 *
2206 * If the grantor was specified by the user, then it must be a user that
2207 * can legally be recorded as the grantor, as per the rule stated above.
2208 * This is an integrity constraint, not a permissions check, and thus even
2209 * superusers are subject to this restriction. However, there is also a
2210 * permissions check: to specify a role as the grantor, the current user
2211 * must possess the privileges of that role. Superusers will always pass
2212 * this check, but for non-superusers it may lead to an error.
2213 *
2214 * The return value is the OID to be regarded as the grantor when executing
2215 * the operation.
2216 */
2217static Oid
2219{
2220 /* If the grantor ID was not specified, pick one to use. */
2221 if (!OidIsValid(grantorId))
2222 {
2223 /*
2224 * Grants where the grantor is recorded as the bootstrap superuser do
2225 * not depend on any other existing grants, so always default to this
2226 * interpretation when possible.
2227 */
2229 return BOOTSTRAP_SUPERUSERID;
2230
2231 /*
2232 * Otherwise, the grantor must either have ADMIN OPTION on the role or
2233 * inherit the privileges of a role which does. In the former case,
2234 * record the grantor as the current user; in the latter, pick one of
2235 * the roles that is "most directly" inherited by the current role
2236 * (i.e. fewest "hops").
2237 *
2238 * (We shouldn't fail to find a best grantor, because we've already
2239 * established that the current user has permission to perform the
2240 * operation.)
2241 */
2243 if (!OidIsValid(grantorId))
2244 elog(ERROR, "no possible grantors");
2245 return grantorId;
2246 }
2247
2248 /*
2249 * If an explicit grantor is specified, it must be a role whose privileges
2250 * the current user possesses.
2251 *
2252 * It should also be a role that has ADMIN OPTION on the target role, but
2253 * we check this condition only in case of GRANT. For REVOKE, no matching
2254 * grant should exist anyway, but if it somehow does, let the user get rid
2255 * of it.
2256 */
2257 if (is_grant)
2258 {
2260 ereport(ERROR,
2262 errmsg("permission denied to grant privileges as role \"%s\"",
2264 errdetail("Only roles with privileges of role \"%s\" may grant privileges as this role.",
2265 GetUserNameFromId(grantorId, false))));
2266
2269 ereport(ERROR,
2271 errmsg("permission denied to grant privileges as role \"%s\"",
2273 errdetail("The grantor must have the %s option on role \"%s\".",
2274 "ADMIN", GetUserNameFromId(roleid, false))));
2275 }
2276 else
2277 {
2279 ereport(ERROR,
2281 errmsg("permission denied to revoke privileges granted by role \"%s\"",
2283 errdetail("Only roles with privileges of role \"%s\" may revoke privileges granted by this role.",
2284 GetUserNameFromId(grantorId, false))));
2285 }
2286
2287 /*
2288 * If a grantor was specified explicitly, always attribute the grant to
2289 * that role (unless we error out above).
2290 */
2291 return grantorId;
2292}
2293
2294/*
2295 * Initialize an array of RevokeRoleGrantAction objects.
2296 *
2297 * 'memlist' should be a list of all grants for the target role.
2298 *
2299 * This constructs an array indicating that no actions are to be performed;
2300 * that is, every element is initially RRG_NOOP.
2301 */
2302static RevokeRoleGrantAction *
2304{
2305 RevokeRoleGrantAction *result;
2306 int i;
2307
2308 if (memlist->n_members == 0)
2309 return NULL;
2310
2311 result = palloc_array(RevokeRoleGrantAction, memlist->n_members);
2312 for (i = 0; i < memlist->n_members; i++)
2313 result[i] = RRG_NOOP;
2314 return result;
2315}
2316
2317/*
2318 * Figure out what we would need to do in order to revoke a grant, or just the
2319 * admin option on a grant, given that there might be dependent privileges.
2320 *
2321 * 'memlist' should be a list of all grants for the target role.
2322 *
2323 * Whatever actions prove to be necessary will be signalled by updating
2324 * 'actions'.
2325 *
2326 * If behavior is DROP_RESTRICT, an error will occur if there are dependent
2327 * role membership grants; if DROP_CASCADE, those grants will be scheduled
2328 * for deletion.
2329 *
2330 * The return value is true if the matching grant was found in the list,
2331 * and false if not.
2332 */
2333static bool
2335 Oid member, Oid grantor, GrantRoleOptions *popt,
2336 DropBehavior behavior)
2337{
2338 int i;
2339
2340 /*
2341 * If popt.specified == 0, we're revoking the grant entirely; otherwise,
2342 * we expect just one bit to be set, and we're revoking the corresponding
2343 * option. As of this writing, there's no syntax that would allow for an
2344 * attempt to revoke multiple options at once, and the logic below
2345 * wouldn't work properly if such syntax were added, so assert that our
2346 * caller isn't trying to do that.
2347 */
2348 Assert(pg_popcount32(popt->specified) <= 1);
2349
2350 for (i = 0; i < memlist->n_members; ++i)
2351 {
2354
2355 authmem_tuple = &memlist->members[i]->tuple;
2357
2358 if (authmem_form->member == member &&
2359 authmem_form->grantor == grantor)
2360 {
2361 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0)
2362 {
2363 /*
2364 * Revoking the INHERIT option doesn't change anything for
2365 * dependent privileges, so we don't need to recurse.
2366 */
2367 actions[i] = RRG_REMOVE_INHERIT_OPTION;
2368 }
2369 else if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0)
2370 {
2371 /* Here too, no need to recurse. */
2372 actions[i] = RRG_REMOVE_SET_OPTION;
2373 }
2374 else
2375 {
2377
2378 /*
2379 * Revoking the grant entirely, or ADMIN option on a grant,
2380 * implicates dependent privileges, so we may need to recurse.
2381 */
2385 revoke_admin_option_only, behavior);
2386 }
2387 return true;
2388 }
2389 }
2390
2391 return false;
2392}
2393
2394/*
2395 * Figure out what we would need to do in order to revoke all grants to
2396 * a given member, given that there might be dependent privileges.
2397 *
2398 * 'memlist' should be a list of all grants for the target role.
2399 *
2400 * Whatever actions prove to be necessary will be signalled by updating
2401 * 'actions'.
2402 */
2403static void
2405 Oid member)
2406{
2407 int i;
2408
2409 for (i = 0; i < memlist->n_members; ++i)
2410 {
2413
2414 authmem_tuple = &memlist->members[i]->tuple;
2416
2417 if (authmem_form->member == member)
2418 plan_recursive_revoke(memlist, actions, i, false, DROP_CASCADE);
2419 }
2420}
2421
2422/*
2423 * Workhorse for figuring out recursive revocation of role grants.
2424 *
2425 * This is similar to what recursive_revoke() does for ACLs.
2426 */
2427static void
2429 int index,
2431{
2432 bool would_still_have_admin_option = false;
2435 int i;
2436
2437 /* If it's already been done, we can just return. */
2438 if (actions[index] == RRG_DELETE_GRANT)
2439 return;
2440 if (actions[index] == RRG_REMOVE_ADMIN_OPTION &&
2442 return;
2443
2444 /* Locate tuple data. */
2445 authmem_tuple = &memlist->members[index]->tuple;
2447
2448 /*
2449 * If the existing tuple does not have admin_option set, then we do not
2450 * need to recurse. If we're just supposed to clear that bit we don't need
2451 * to do anything at all; if we're supposed to remove the grant, we need
2452 * to do something, but only to the tuple, and not any others.
2453 */
2455 {
2456 actions[index] = RRG_DELETE_GRANT;
2457 if (!authmem_form->admin_option)
2458 return;
2459 }
2460 else
2461 {
2462 if (!authmem_form->admin_option)
2463 return;
2464 actions[index] = RRG_REMOVE_ADMIN_OPTION;
2465 }
2466
2467 /* Determine whether the member would still have ADMIN OPTION. */
2468 for (i = 0; i < memlist->n_members; ++i)
2469 {
2472
2473 am_cascade_tuple = &memlist->members[i]->tuple;
2475
2476 if (am_cascade_form->member == authmem_form->member &&
2477 am_cascade_form->admin_option && actions[i] == RRG_NOOP)
2478 {
2480 break;
2481 }
2482 }
2483
2484 /* If the member would still have ADMIN OPTION, we need not recurse. */
2486 return;
2487
2488 /*
2489 * Recurse to grants that are not yet slated for deletion which have this
2490 * member as the grantor.
2491 */
2492 for (i = 0; i < memlist->n_members; ++i)
2493 {
2496
2497 am_cascade_tuple = &memlist->members[i]->tuple;
2499
2500 if (am_cascade_form->grantor == authmem_form->member &&
2501 actions[i] != RRG_DELETE_GRANT)
2502 {
2503 if (behavior == DROP_RESTRICT)
2504 ereport(ERROR,
2506 errmsg("dependent privileges exist"),
2507 errhint("Use CASCADE to revoke them too.")));
2508
2509 plan_recursive_revoke(memlist, actions, i, false, behavior);
2510 }
2511 }
2512}
2513
2514/*
2515 * Initialize a GrantRoleOptions object with default values.
2516 */
2517static void
2519{
2520 popt->specified = 0;
2521 popt->admin = false;
2522 popt->inherit = false;
2523 popt->set = true;
2524}
2525
2526/*
2527 * GUC check_hook for createrole_self_grant
2528 */
2529bool
2531{
2532 char *rawstring;
2533 List *elemlist;
2534 ListCell *l;
2535 unsigned options = 0;
2536 unsigned *result;
2537
2538 /* Need a modifiable copy of string */
2540
2542 {
2543 /* syntax error in list */
2544 GUC_check_errdetail("List syntax is invalid.");
2547 return false;
2548 }
2549
2550 foreach(l, elemlist)
2551 {
2552 char *tok = (char *) lfirst(l);
2553
2554 if (pg_strcasecmp(tok, "SET") == 0)
2556 else if (pg_strcasecmp(tok, "INHERIT") == 0)
2558 else
2559 {
2560 GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
2563 return false;
2564 }
2565 }
2566
2569
2570 result = (unsigned *) guc_malloc(LOG, sizeof(unsigned));
2571 if (!result)
2572 return false;
2573 *result = options;
2574 *extra = result;
2575
2576 return true;
2577}
2578
2579/*
2580 * GUC assign_hook for createrole_self_grant
2581 */
2582void
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5416
Oid select_best_admin(Oid member, Oid role)
Definition acl.c:5441
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition acl.c:5394
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5286
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5554
char * get_rolespec_name(const RoleSpec *role)
Definition acl.c:5673
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5695
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5588
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5627
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
bool has_bypassrls_privilege(Oid roleid)
Definition aclchk.c:4206
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4108
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4187
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition timestamp.c:418
bool parse_bool(const char *value, bool *result)
Definition bool.c:31
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:777
#define STATUS_OK
Definition c.h:1186
#define Assert(condition)
Definition c.h:885
#define OidIsValid(objectId)
Definition c.h:800
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:448
bool IsReservedName(const char *name)
Definition catalog.c:278
void DeleteSharedComments(Oid oid, Oid classoid)
Definition comment.c:384
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
Definition crypt.c:336
PasswordType get_password_type(const char *shadow_pass)
Definition crypt.c:153
char * encrypt_password(PasswordType target_type, const char *role, const char *password)
Definition crypt.c:180
@ PASSWORD_TYPE_SCRAM_SHA_256
Definition crypt.h:47
@ PASSWORD_TYPE_MD5
Definition crypt.h:46
bool have_createdb_privilege(void)
Oid get_database_oid(const char *dbname, bool missing_ok)
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition dbcommands.c:686
char * defGetString(DefElem *def)
Definition define.c:34
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define _(x)
Definition elog.c:95
#define LOG
Definition elog.h:31
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
int int int errdetail_log(const char *fmt,...) pg_attribute_printf(1
#define elog(elevel,...)
Definition elog.h:226
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
bool IsBinaryUpgrade
Definition globals.c:121
void * guc_malloc(int elevel, size_t size)
Definition guc.c:636
#define newval
#define GUC_check_errdetail
Definition guc.h:506
GucSource
Definition guc.h:112
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define stmt
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
int i
Definition isn.c:77
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
List * list_append_unique_oid(List *list, Oid datum)
Definition list.c:1380
void list_free(List *list)
Definition list.c:1546
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1088
#define NoLock
Definition lockdefs.h:34
#define AccessExclusiveLock
Definition lockdefs.h:43
#define AccessShareLock
Definition lockdefs.h:36
#define ShareUpdateExclusiveLock
Definition lockdefs.h:39
#define RowExclusiveLock
Definition lockdefs.h:38
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
Oid GetOuterUserId(void)
Definition miscinit.c:480
Oid GetUserId(void)
Definition miscinit.c:469
Oid GetSessionUserId(void)
Definition miscinit.c:508
bool has_rolreplication(Oid roleid)
Definition miscinit.c:688
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:988
Datum namein(PG_FUNCTION_ARGS)
Definition name.c:48
#define makeNode(_type_)
Definition nodes.h:161
#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)
Definition parse_node.c:106
@ ROLESPEC_CSTRING
Definition parsenodes.h:419
@ ROLESPEC_CURRENT_ROLE
Definition parsenodes.h:420
DropBehavior
@ DROP_CASCADE
@ DROP_RESTRICT
@ OBJECT_DATABASE
@ ROLESTMT_ROLE
@ ROLESTMT_USER
@ ROLESTMT_GROUP
END_CATALOG_STRUCT typedef FormData_pg_auth_members * Form_pg_auth_members
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
static int pg_popcount32(uint32 word)
void DropSetting(Oid databaseid, Oid roleid)
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
#define lfirst(lc)
Definition pg_list.h:172
#define lfirst_node(type, lc)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:518
#define list_make1_oid(x1)
Definition pg_list.h:242
#define list_make1(x1)
Definition pg_list.h:212
#define lfirst_oid(lc)
Definition pg_list.h:174
static rewind_source * source
Definition pg_rewind.c:89
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)
Definition postgres.h:352
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define RelationGetDescr(relation)
Definition rel.h:540
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition seclabel.c:501
#define BTEqualStrategyNumber
Definition stratnum.h:31
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
static char * password
Definition streamutil.c:51
char * priv_name
List * cols
char * defname
Definition parsenodes.h:844
ParseLoc location
Definition parsenodes.h:848
unsigned specified
Definition user.c:75
bool inherit
Definition user.c:77
ItemPointerData t_self
Definition htup.h:65
Definition pg_list.h:54
Definition type.h:96
bool superuser_arg(Oid roleid)
Definition superuser.c:57
bool superuser(void)
Definition superuser.c:47
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:240
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
#define ReleaseSysCacheList(x)
Definition syscache.h:134
#define SearchSysCacheList1(cacheId, key1)
Definition syscache.h:127
#define SearchSysCacheExists1(cacheId, key1)
Definition syscache.h:100
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
static bool have_createrole_privilege(void)
Definition user.c:123
ObjectAddress RenameRole(const char *oldname, const char *newname)
Definition user.c:1341
#define GRANT_ROLE_SPECIFIED_ADMIN
Definition user.c:81
static bool plan_single_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, Oid member, Oid grantor, GrantRoleOptions *popt, DropBehavior behavior)
Definition user.c:2334
static GrantRoleOptions createrole_self_grant_options
Definition user.c:89
static void InitGrantRoleOptions(GrantRoleOptions *popt)
Definition user.c:2518
static void plan_member_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, Oid member)
Definition user.c:2404
static void AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt)
Definition user.c:1694
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
Definition user.c:1624
Oid AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
Definition user.c:626
static bool createrole_self_grant_enabled
Definition user.c:88
#define GRANT_ROLE_SPECIFIED_SET
Definition user.c:83
Oid AlterRoleSet(AlterRoleSetStmt *stmt)
Definition user.c:1007
static Oid check_role_grantor(Oid currentUserId, Oid roleid, Oid grantorId, bool is_grant)
Definition user.c:2218
int Password_encryption
Definition user.c:86
bool check_createrole_self_grant(char **newval, void **extra, GucSource source)
Definition user.c:2530
void assign_createrole_self_grant(const char *newval, void *extra)
Definition user.c:2583
static void check_role_membership_authorization(Oid currentUserId, Oid roleid, bool is_grant)
Definition user.c:2124
Oid binary_upgrade_next_pg_authid_oid
Definition user.c:71
#define GRANT_ROLE_SPECIFIED_INHERIT
Definition user.c:82
void DropRole(DropRoleStmt *stmt)
Definition user.c:1097
Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
Definition user.c:133
void GrantRole(ParseState *pstate, GrantRoleStmt *stmt)
Definition user.c:1493
List * roleSpecsToIds(List *memberNames)
Definition user.c:1665
static void plan_recursive_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, int index, bool revoke_admin_option_only, DropBehavior behavior)
Definition user.c:2428
char * createrole_self_grant
Definition user.c:87
check_password_hook_type check_password_hook
Definition user.c:92
RevokeRoleGrantAction
Definition user.c:62
@ RRG_REMOVE_SET_OPTION
Definition user.c:66
@ RRG_NOOP
Definition user.c:63
@ RRG_DELETE_GRANT
Definition user.c:67
@ RRG_REMOVE_INHERIT_OPTION
Definition user.c:65
@ RRG_REMOVE_ADMIN_OPTION
Definition user.c:64
static RevokeRoleGrantAction * initialize_revoke_actions(CatCList *memlist)
Definition user.c:2303
void DropOwnedObjects(DropOwnedStmt *stmt)
Definition user.c:1596
static void DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
Definition user.c:1992
void(* check_password_hook_type)(const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null)
Definition user.h:25
#define boolVal(v)
Definition value.h:81
#define intVal(v)
Definition value.h:79
#define strVal(v)
Definition value.h:82
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition varlena.c:2775
void CommandCounterIncrement(void)
Definition xact.c:1101