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 /* The defaults can vary depending on the original statement type */
175 switch (stmt->stmt_type)
176 {
177 case ROLESTMT_ROLE:
178 break;
179 case ROLESTMT_USER:
180 canlogin = true;
181 /* may eventually want inherit to default to false here */
182 break;
183 case ROLESTMT_GROUP:
184 break;
185 }
186
187 /* Extract options from the statement node tree */
188 foreach(option, stmt->options)
189 {
191
192 if (strcmp(defel->defname, "password") == 0)
193 {
194 if (dpassword)
197 }
198 else if (strcmp(defel->defname, "sysid") == 0)
199 {
201 (errmsg("SYSID can no longer be specified")));
202 }
203 else if (strcmp(defel->defname, "superuser") == 0)
204 {
205 if (dissuper)
207 dissuper = defel;
208 }
209 else if (strcmp(defel->defname, "inherit") == 0)
210 {
211 if (dinherit)
213 dinherit = defel;
214 }
215 else if (strcmp(defel->defname, "createrole") == 0)
216 {
217 if (dcreaterole)
220 }
221 else if (strcmp(defel->defname, "createdb") == 0)
222 {
223 if (dcreatedb)
226 }
227 else if (strcmp(defel->defname, "canlogin") == 0)
228 {
229 if (dcanlogin)
232 }
233 else if (strcmp(defel->defname, "isreplication") == 0)
234 {
235 if (disreplication)
238 }
239 else if (strcmp(defel->defname, "connectionlimit") == 0)
240 {
241 if (dconnlimit)
244 }
245 else if (strcmp(defel->defname, "addroleto") == 0)
246 {
247 if (daddroleto)
250 }
251 else if (strcmp(defel->defname, "rolemembers") == 0)
252 {
253 if (drolemembers)
256 }
257 else if (strcmp(defel->defname, "adminmembers") == 0)
258 {
259 if (dadminmembers)
262 }
263 else if (strcmp(defel->defname, "validUntil") == 0)
264 {
265 if (dvalidUntil)
268 }
269 else if (strcmp(defel->defname, "bypassrls") == 0)
270 {
271 if (dbypassRLS)
274 }
275 else
276 elog(ERROR, "option \"%s\" not recognized",
277 defel->defname);
278 }
279
280 if (dpassword && dpassword->arg)
281 password = strVal(dpassword->arg);
282 if (dissuper)
283 issuper = boolVal(dissuper->arg);
284 if (dinherit)
285 inherit = boolVal(dinherit->arg);
286 if (dcreaterole)
288 if (dcreatedb)
289 createdb = boolVal(dcreatedb->arg);
290 if (dcanlogin)
291 canlogin = boolVal(dcanlogin->arg);
292 if (disreplication)
294 if (dconnlimit)
295 {
297 if (connlimit < -1)
300 errmsg("invalid connection limit: %d", connlimit)));
301 }
302 if (daddroleto)
303 addroleto = (List *) daddroleto->arg;
304 if (drolemembers)
305 rolemembers = (List *) drolemembers->arg;
306 if (dadminmembers)
308 if (dvalidUntil)
310 if (dbypassRLS)
312
313 /* Check some permissions first */
315 {
319 errmsg("permission denied to create role"),
320 errdetail("Only roles with the %s attribute may create roles.",
321 "CREATEROLE")));
322 if (issuper)
325 errmsg("permission denied to create role"),
326 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
327 "SUPERUSER", "SUPERUSER")));
331 errmsg("permission denied to create role"),
332 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
333 "CREATEDB", "CREATEDB")));
337 errmsg("permission denied to create role"),
338 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
339 "REPLICATION", "REPLICATION")));
343 errmsg("permission denied to create role"),
344 errdetail("Only roles with the %s attribute may create roles with the %s attribute.",
345 "BYPASSRLS", "BYPASSRLS")));
346 }
347
348 /*
349 * Check that the user is not trying to create a role in the reserved
350 * "pg_" namespace.
351 */
352 if (IsReservedName(stmt->role))
355 errmsg("role name \"%s\" is reserved",
356 stmt->role),
357 errdetail("Role names starting with \"pg_\" are reserved.")));
358
359 /*
360 * If built with appropriate switch, whine when regression-testing
361 * conventions for role names are violated.
362 */
363#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
364 if (strncmp(stmt->role, "regress_", 8) != 0)
365 elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
366#endif
367
368 /*
369 * Check the pg_authid relation to be certain the role doesn't already
370 * exist.
371 */
374
375 if (OidIsValid(get_role_oid(stmt->role, true)))
378 errmsg("role \"%s\" already exists",
379 stmt->role)));
380
381 /* Convert validuntil to internal form */
382 if (validUntil)
383 {
387 Int32GetDatum(-1));
388 validUntil_null = false;
389 }
390 else
391 {
393 validUntil_null = true;
394 }
395
396 /*
397 * Call the password checking hook if there is one defined
398 */
400 (*check_password_hook) (stmt->role,
401 password,
405
406 /*
407 * Build a tuple to insert
408 */
418
419 if (password)
420 {
421 char *shadow_pass;
422 const char *logdetail = NULL;
423
424 /*
425 * Don't allow an empty password. Libpq treats an empty password the
426 * same as no password at all, and won't even try to authenticate. But
427 * other clients might, so allowing it would be confusing. By clearing
428 * the password when an empty string is specified, the account is
429 * consistently locked for all clients.
430 *
431 * Note that this only covers passwords stored in the database itself.
432 * There are also checks in the authentication code, to forbid an
433 * empty password from being used with authentication methods that
434 * fetch the password from an external system, like LDAP or PAM.
435 */
436 if (password[0] == '\0' ||
437 plain_crypt_verify(stmt->role, password, "", &logdetail) == STATUS_OK)
438 {
440 (errmsg("empty string is not a valid password, clearing password")));
442 }
443 else
444 {
445 /* Encrypt the password to the requested format. */
447 password);
450 }
451 }
452 else
454
457
459
460 /*
461 * pg_largeobject_metadata contains pg_authid.oid's, so we use the
462 * binary-upgrade override.
463 */
464 if (IsBinaryUpgrade)
465 {
469 errmsg("pg_authid OID value not set when in binary upgrade mode")));
470
473 }
474 else
475 {
478 }
479
481
483
484 /*
485 * Insert new record in the pg_authid table
486 */
488
489 /*
490 * Advance command counter so we can see new record; else tests in
491 * AddRoleMems may fail.
492 */
495
496 /* Default grant. */
498
499 /*
500 * Add the new role to the specified existing roles.
501 */
502 if (addroleto)
503 {
507
508 thisrole->roletype = ROLESPEC_CSTRING;
509 thisrole->rolename = stmt->role;
510 thisrole->location = -1;
511
512 foreach(item, addroleto)
513 {
514 RoleSpec *oldrole = lfirst(item);
518 char *oldrolename = NameStr(oldroleform->rolname);
519
520 /* can only add this role to roles for which you have rights */
525 InvalidOid, &popt);
526
528 }
529 }
530
531 /*
532 * If the current user isn't a superuser, make them an admin of the new
533 * role so that they can administer the new object they just created.
534 * Superusers will be able to do that anyway.
535 *
536 * The grantor of record for this implicit grant is the bootstrap
537 * superuser, which means that the CREATEROLE user cannot revoke the
538 * grant. They can however grant the created role back to themselves with
539 * different options, since they enjoy ADMIN OPTION on it.
540 */
541 if (!superuser())
542 {
547
549 current_role->location = -1;
551
555 poptself.admin = true;
556 poptself.inherit = false;
557 poptself.set = false;
558
562
563 /*
564 * We must make the implicit grant visible to the code below, else the
565 * additional grants will fail.
566 */
568
569 /*
570 * Because of the implicit grant above, a CREATEROLE user who creates
571 * a role has the ability to grant that role back to themselves with
572 * the INHERIT or SET options, if they wish to inherit the role's
573 * privileges or be able to SET ROLE to it. The createrole_self_grant
574 * GUC can be used to make this happen automatically. This has no
575 * security implications since the same user is able to make the same
576 * grant using an explicit GRANT statement; it's just convenient.
577 */
579 AddRoleMems(currentUserId, stmt->role, roleid,
582 }
583
584 /*
585 * Add the specified members to this new role. adminmembers get the admin
586 * option, rolemembers don't.
587 *
588 * NB: No permissions check is required here. If you have enough rights to
589 * create a role, you can add any members you like.
590 */
591 AddRoleMems(currentUserId, stmt->role, roleid,
593 InvalidOid, &popt);
595 popt.admin = true;
596 AddRoleMems(currentUserId, stmt->role, roleid,
598 InvalidOid, &popt);
599
600 /* Post creation hook for new role */
602
603 /*
604 * Close pg_authid, but keep lock till commit.
605 */
607
608 return roleid;
609}
610
611
612/*
613 * ALTER ROLE
614 *
615 * Note: the rolemembers option accepted here is intended to support the
616 * backwards-compatible ALTER GROUP syntax. Although it will work to say
617 * "ALTER ROLE role ROLE rolenames", we don't document it.
618 */
619Oid
621{
627 HeapTuple tuple,
628 new_tuple;
631 char *rolename;
632 char *password = NULL; /* user password */
633 int connlimit = -1; /* maximum connections allowed */
634 char *validUntil = NULL; /* time the login is valid until */
635 Datum validUntil_datum; /* same, as timestamptz Datum */
636 bool validUntil_null;
648 Oid roleid;
650 GrantRoleOptions popt;
651
653 _("Cannot alter reserved roles."));
654
655 /* Extract options from the statement node tree */
656 foreach(option, stmt->options)
657 {
659
660 if (strcmp(defel->defname, "password") == 0)
661 {
662 if (dpassword)
665 }
666 else if (strcmp(defel->defname, "superuser") == 0)
667 {
668 if (dissuper)
670 dissuper = defel;
671 }
672 else if (strcmp(defel->defname, "inherit") == 0)
673 {
674 if (dinherit)
676 dinherit = defel;
677 }
678 else if (strcmp(defel->defname, "createrole") == 0)
679 {
680 if (dcreaterole)
683 }
684 else if (strcmp(defel->defname, "createdb") == 0)
685 {
686 if (dcreatedb)
689 }
690 else if (strcmp(defel->defname, "canlogin") == 0)
691 {
692 if (dcanlogin)
695 }
696 else if (strcmp(defel->defname, "isreplication") == 0)
697 {
698 if (disreplication)
701 }
702 else if (strcmp(defel->defname, "connectionlimit") == 0)
703 {
704 if (dconnlimit)
707 }
708 else if (strcmp(defel->defname, "rolemembers") == 0 &&
709 stmt->action != 0)
710 {
711 if (drolemembers)
714 }
715 else if (strcmp(defel->defname, "validUntil") == 0)
716 {
717 if (dvalidUntil)
720 }
721 else if (strcmp(defel->defname, "bypassrls") == 0)
722 {
723 if (dbypassRLS)
726 }
727 else
728 elog(ERROR, "option \"%s\" not recognized",
729 defel->defname);
730 }
731
732 if (dpassword && dpassword->arg)
733 password = strVal(dpassword->arg);
734 if (dconnlimit)
735 {
737 if (connlimit < -1)
740 errmsg("invalid connection limit: %d", connlimit)));
741 }
742 if (dvalidUntil)
744
745 /*
746 * Scan the pg_authid relation to be certain the user exists.
747 */
750
751 tuple = get_rolespec_tuple(stmt->role);
753 rolename = pstrdup(NameStr(authform->rolname));
754 roleid = authform->oid;
755
756 /* To mess with a superuser in any way you gotta be superuser. */
757 if (!superuser() && authform->rolsuper)
760 errmsg("permission denied to alter role"),
761 errdetail("Only roles with the %s attribute may alter roles with the %s attribute.",
762 "SUPERUSER", "SUPERUSER")));
763 if (!superuser() && dissuper)
766 errmsg("permission denied to alter role"),
767 errdetail("Only roles with the %s attribute may change the %s attribute.",
768 "SUPERUSER", "SUPERUSER")));
769
770 /*
771 * Most changes to a role require that you both have CREATEROLE privileges
772 * and also ADMIN OPTION on the role.
773 */
775 !is_admin_of_role(GetUserId(), roleid))
776 {
777 /* things an unprivileged user certainly can't do */
782 errmsg("permission denied to alter role"),
783 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
784 "CREATEROLE", "ADMIN", rolename)));
785
786 /* an unprivileged user can change their own password */
787 if (dpassword && roleid != currentUserId)
790 errmsg("permission denied to alter role"),
791 errdetail("To change another role's password, the current user must have the %s attribute and the %s option on the role.",
792 "CREATEROLE", "ADMIN")));
793 }
794 else if (!superuser())
795 {
796 /*
797 * Even if you have both CREATEROLE and ADMIN OPTION on a role, you
798 * can only change the CREATEDB, REPLICATION, or BYPASSRLS attributes
799 * if they are set for your own role (or you are the superuser).
800 */
804 errmsg("permission denied to alter role"),
805 errdetail("Only roles with the %s attribute may change the %s attribute.",
806 "CREATEDB", "CREATEDB")));
810 errmsg("permission denied to alter role"),
811 errdetail("Only roles with the %s attribute may change the %s attribute.",
812 "REPLICATION", "REPLICATION")));
816 errmsg("permission denied to alter role"),
817 errdetail("Only roles with the %s attribute may change the %s attribute.",
818 "BYPASSRLS", "BYPASSRLS")));
819 }
820
821 /* To add or drop members, you need ADMIN OPTION. */
825 errmsg("permission denied to alter role"),
826 errdetail("Only roles with the %s option on role \"%s\" may add or drop members.",
827 "ADMIN", rolename)));
828
829 /* Convert validuntil to internal form */
830 if (dvalidUntil)
831 {
835 Int32GetDatum(-1));
836 validUntil_null = false;
837 }
838 else
839 {
840 /* fetch existing setting in case hook needs it */
844 }
845
846 /*
847 * Call the password checking hook if there is one defined
848 */
850 (*check_password_hook) (rolename,
851 password,
855
856 /*
857 * Build an updated tuple, perusing the information just obtained
858 */
859
860 /*
861 * issuper/createrole/etc
862 */
863 if (dissuper)
864 {
865 bool should_be_super = boolVal(dissuper->arg);
866
867 if (!should_be_super && roleid == BOOTSTRAP_SUPERUSERID)
870 errmsg("permission denied to alter role"),
871 errdetail("The bootstrap superuser must have the %s attribute.",
872 "SUPERUSER")));
873
876 }
877
878 if (dinherit)
879 {
882 }
883
884 if (dcreaterole)
885 {
888 }
889
890 if (dcreatedb)
891 {
894 }
895
896 if (dcanlogin)
897 {
900 }
901
902 if (disreplication)
903 {
906 }
907
908 if (dconnlimit)
909 {
912 }
913
914 /* password */
915 if (password)
916 {
917 char *shadow_pass;
918 const char *logdetail = NULL;
919
920 /* Like in CREATE USER, don't allow an empty password. */
921 if (password[0] == '\0' ||
922 plain_crypt_verify(rolename, password, "", &logdetail) == STATUS_OK)
923 {
925 (errmsg("empty string is not a valid password, clearing password")));
927 }
928 else
929 {
930 /* Encrypt the password to the requested format. */
932 password);
935 }
937 }
938
939 /* unset password */
940 if (dpassword && dpassword->arg == NULL)
941 {
944 }
945
946 /* valid until */
950
951 if (dbypassRLS)
952 {
955 }
956
960
962
963 ReleaseSysCache(tuple);
965
967
968 /*
969 * Advance command counter so we can see new record; else tests in
970 * AddRoleMems may fail.
971 */
972 if (drolemembers)
973 {
974 List *rolemembers = (List *) drolemembers->arg;
975
977
978 if (stmt->action == +1) /* add members to role */
979 AddRoleMems(currentUserId, rolename, roleid,
981 InvalidOid, &popt);
982 else if (stmt->action == -1) /* drop members from role */
983 DelRoleMems(currentUserId, rolename, roleid,
985 InvalidOid, &popt, DROP_RESTRICT);
986 }
987
988 /*
989 * Close pg_authid, but keep lock till commit.
990 */
992
993 return roleid;
994}
995
996
997/*
998 * ALTER ROLE ... SET
999 */
1000Oid
1002{
1006 Oid roleid = InvalidOid;
1007
1008 if (stmt->role)
1009 {
1011 _("Cannot alter reserved roles."));
1012
1015 roleid = roleform->oid;
1016
1017 /*
1018 * Obtain a lock on the role and make sure it didn't go away in the
1019 * meantime.
1020 */
1022
1023 /*
1024 * To mess with a superuser you gotta be superuser; otherwise you need
1025 * CREATEROLE plus admin option on the target role; unless you're just
1026 * trying to change your own settings
1027 */
1028 if (roleform->rolsuper)
1029 {
1030 if (!superuser())
1031 ereport(ERROR,
1033 errmsg("permission denied to alter role"),
1034 errdetail("Only roles with the %s attribute may alter roles with the %s attribute.",
1035 "SUPERUSER", "SUPERUSER")));
1036 }
1037 else
1038 {
1039 if ((!have_createrole_privilege() ||
1040 !is_admin_of_role(GetUserId(), roleid))
1041 && roleid != GetUserId())
1042 ereport(ERROR,
1044 errmsg("permission denied to alter role"),
1045 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may alter this role.",
1046 "CREATEROLE", "ADMIN", NameStr(roleform->rolname))));
1047 }
1048
1050 }
1051
1052 /* look up and lock the database, if specified */
1053 if (stmt->database != NULL)
1054 {
1055 databaseid = get_database_oid(stmt->database, false);
1057
1058 if (!stmt->role)
1059 {
1060 /*
1061 * If no role is specified, then this is effectively the same as
1062 * ALTER DATABASE ... SET, so use the same permission check.
1063 */
1066 stmt->database);
1067 }
1068 }
1069
1070 if (!stmt->role && !stmt->database)
1071 {
1072 /* Must be superuser to alter settings globally. */
1073 if (!superuser())
1074 ereport(ERROR,
1076 errmsg("permission denied to alter setting"),
1077 errdetail("Only roles with the %s attribute may alter settings globally.",
1078 "SUPERUSER")));
1079 }
1080
1081 AlterSetting(databaseid, roleid, stmt->setstmt);
1082
1083 return roleid;
1084}
1085
1086
1087/*
1088 * DROP ROLE
1089 */
1090void
1092{
1095 ListCell *item;
1096 List *role_oids = NIL;
1097
1099 ereport(ERROR,
1101 errmsg("permission denied to drop role"),
1102 errdetail("Only roles with the %s attribute and the %s option on the target roles may drop roles.",
1103 "CREATEROLE", "ADMIN")));
1104
1105 /*
1106 * Scan the pg_authid relation to find the Oid of the role(s) to be
1107 * deleted and perform preliminary permissions and sanity checks.
1108 */
1111
1112 foreach(item, stmt->roles)
1113 {
1114 RoleSpec *rolspec = lfirst(item);
1115 char *role;
1116 HeapTuple tuple,
1117 tmp_tuple;
1121 Oid roleid;
1122
1123 if (rolspec->roletype != ROLESPEC_CSTRING)
1124 ereport(ERROR,
1126 errmsg("cannot use special role specifier in DROP ROLE")));
1127 role = rolspec->rolename;
1128
1130 if (!HeapTupleIsValid(tuple))
1131 {
1132 if (!stmt->missing_ok)
1133 {
1134 ereport(ERROR,
1136 errmsg("role \"%s\" does not exist", role)));
1137 }
1138 else
1139 {
1141 (errmsg("role \"%s\" does not exist, skipping",
1142 role)));
1143 }
1144
1145 continue;
1146 }
1147
1149 roleid = roleform->oid;
1150
1151 if (roleid == GetUserId())
1152 ereport(ERROR,
1154 errmsg("current user cannot be dropped")));
1155 if (roleid == GetOuterUserId())
1156 ereport(ERROR,
1158 errmsg("current user cannot be dropped")));
1159 if (roleid == GetSessionUserId())
1160 ereport(ERROR,
1162 errmsg("session user cannot be dropped")));
1163
1164 /*
1165 * For safety's sake, we allow createrole holders to drop ordinary
1166 * roles but not superuser roles, and only if they also have ADMIN
1167 * OPTION.
1168 */
1169 if (roleform->rolsuper && !superuser())
1170 ereport(ERROR,
1172 errmsg("permission denied to drop role"),
1173 errdetail("Only roles with the %s attribute may drop roles with the %s attribute.",
1174 "SUPERUSER", "SUPERUSER")));
1175 if (!is_admin_of_role(GetUserId(), roleid))
1176 ereport(ERROR,
1178 errmsg("permission denied to drop role"),
1179 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may drop this role.",
1180 "CREATEROLE", "ADMIN", NameStr(roleform->rolname))));
1181
1182 /* DROP hook for the role being removed */
1184
1185 /* Don't leak the syscache tuple */
1186 ReleaseSysCache(tuple);
1187
1188 /*
1189 * Lock the role, so nobody can add dependencies to her while we drop
1190 * her. We keep the lock until the end of transaction.
1191 */
1193
1194 /*
1195 * If there is a pg_auth_members entry that has one of the roles to be
1196 * dropped as the roleid or member, it should be silently removed, but
1197 * if there is a pg_auth_members entry that has one of the roles to be
1198 * dropped as the grantor, the operation should fail.
1199 *
1200 * It's possible, however, that a single pg_auth_members entry could
1201 * fall into multiple categories - e.g. the user could do "GRANT foo
1202 * TO bar GRANTED BY baz" and then "DROP ROLE baz, bar". We want such
1203 * an operation to succeed regardless of the order in which the
1204 * to-be-dropped roles are passed to DROP ROLE.
1205 *
1206 * To make that work, we remove all pg_auth_members entries that can
1207 * be silently removed in this loop, and then below we'll make a
1208 * second pass over the list of roles to be removed and check for any
1209 * remaining dependencies.
1210 */
1214 ObjectIdGetDatum(roleid));
1215
1217 true, NULL, 1, &scankey);
1218
1220 {
1222
1225 authmem_form->oid, 0);
1227 }
1228
1230
1234 ObjectIdGetDatum(roleid));
1235
1237 true, NULL, 1, &scankey);
1238
1240 {
1242
1245 authmem_form->oid, 0);
1247 }
1248
1250
1251 /*
1252 * Advance command counter so that later iterations of this loop will
1253 * see the changes already made. This is essential if, for example,
1254 * we are trying to drop both a role and one of its direct members ---
1255 * we'll get an error if we try to delete the linking pg_auth_members
1256 * tuple twice. (We do not need a CCI between the two delete loops
1257 * above, because it's not allowed for a role to directly contain
1258 * itself.)
1259 */
1261
1262 /* Looks tentatively OK, add it to the list if not there yet. */
1264 }
1265
1266 /*
1267 * Second pass over the roles to be removed.
1268 */
1269 foreach(item, role_oids)
1270 {
1271 Oid roleid = lfirst_oid(item);
1272 HeapTuple tuple;
1274 char *detail;
1275 char *detail_log;
1276
1277 /*
1278 * Re-find the pg_authid tuple.
1279 *
1280 * Since we've taken a lock on the role OID, it shouldn't be possible
1281 * for the tuple to have been deleted -- or for that matter updated --
1282 * unless the user is manually modifying the system catalogs.
1283 */
1284 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
1285 if (!HeapTupleIsValid(tuple))
1286 elog(ERROR, "could not find tuple for role %u", roleid);
1288
1289 /*
1290 * Check for pg_shdepend entries depending on this role.
1291 *
1292 * This needs to happen after we've completed removing any
1293 * pg_auth_members entries that can be removed silently, in order to
1294 * avoid spurious failures. See notes above for more details.
1295 */
1297 &detail, &detail_log))
1298 ereport(ERROR,
1300 errmsg("role \"%s\" cannot be dropped because some objects depend on it",
1301 NameStr(roleform->rolname)),
1302 errdetail_internal("%s", detail),
1303 errdetail_log("%s", detail_log)));
1304
1305 /*
1306 * Remove the role from the pg_authid table
1307 */
1309
1310 ReleaseSysCache(tuple);
1311
1312 /*
1313 * Remove any comments or security labels on this role.
1314 */
1317
1318 /*
1319 * Remove settings for this role.
1320 */
1321 DropSetting(InvalidOid, roleid);
1322 }
1323
1324 /*
1325 * Now we can clean up; but keep locks until commit.
1326 */
1329}
1330
1331/*
1332 * Rename role
1333 */
1335RenameRole(const char *oldname, const char *newname)
1336{
1337 HeapTuple oldtuple,
1338 newtuple;
1339 TupleDesc dsc;
1340 Relation rel;
1341 Datum datum;
1342 bool isnull;
1346 int i;
1347 Oid roleid;
1348 ObjectAddress address;
1350
1352 dsc = RelationGetDescr(rel);
1353
1355 if (!HeapTupleIsValid(oldtuple))
1356 ereport(ERROR,
1358 errmsg("role \"%s\" does not exist", oldname)));
1359
1360 /*
1361 * XXX Client applications probably store the session user somewhere, so
1362 * renaming it could cause confusion. On the other hand, there may not be
1363 * an actual problem besides a little confusion, so think about this and
1364 * decide. Same for SET ROLE ... we don't restrict renaming the current
1365 * effective userid, though.
1366 */
1367
1368 authform = (Form_pg_authid) GETSTRUCT(oldtuple);
1369 roleid = authform->oid;
1370
1371 if (roleid == GetSessionUserId())
1372 ereport(ERROR,
1374 errmsg("session user cannot be renamed")));
1375 if (roleid == GetOuterUserId())
1376 ereport(ERROR,
1378 errmsg("current user cannot be renamed")));
1379
1380 /*
1381 * Check that the user is not trying to rename a system role and not
1382 * trying to rename a role into the reserved "pg_" namespace.
1383 */
1384 if (IsReservedName(NameStr(authform->rolname)))
1385 ereport(ERROR,
1387 errmsg("role name \"%s\" is reserved",
1388 NameStr(authform->rolname)),
1389 errdetail("Role names starting with \"pg_\" are reserved.")));
1390
1391 if (IsReservedName(newname))
1392 ereport(ERROR,
1394 errmsg("role name \"%s\" is reserved",
1395 newname),
1396 errdetail("Role names starting with \"pg_\" are reserved.")));
1397
1398 /*
1399 * If built with appropriate switch, whine when regression-testing
1400 * conventions for role names are violated.
1401 */
1402#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1403 if (strncmp(newname, "regress_", 8) != 0)
1404 elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
1405#endif
1406
1407 /* make sure the new name doesn't exist */
1409 ereport(ERROR,
1411 errmsg("role \"%s\" already exists", newname)));
1412
1413 /*
1414 * Only superusers can mess with superusers. Otherwise, a user with
1415 * CREATEROLE can rename a role for which they have ADMIN OPTION.
1416 */
1417 if (authform->rolsuper)
1418 {
1419 if (!superuser())
1420 ereport(ERROR,
1422 errmsg("permission denied to rename role"),
1423 errdetail("Only roles with the %s attribute may rename roles with the %s attribute.",
1424 "SUPERUSER", "SUPERUSER")));
1425 }
1426 else
1427 {
1429 !is_admin_of_role(GetUserId(), roleid))
1430 ereport(ERROR,
1432 errmsg("permission denied to rename role"),
1433 errdetail("Only roles with the %s attribute and the %s option on role \"%s\" may rename this role.",
1434 "CREATEROLE", "ADMIN", NameStr(authform->rolname))));
1435 }
1436
1437 /* OK, construct the modified tuple */
1438 for (i = 0; i < Natts_pg_authid; i++)
1439 repl_repl[i] = false;
1440
1443 CStringGetDatum(newname));
1444 repl_null[Anum_pg_authid_rolname - 1] = false;
1445
1446 datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1447
1449 {
1450 /* MD5 uses the username as salt, so just clear it on a rename */
1453
1455 (errmsg("MD5 password cleared because of role rename")));
1456 }
1457
1458 newtuple = heap_modify_tuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
1459 CatalogTupleUpdate(rel, &oldtuple->t_self, newtuple);
1460
1462
1463 ObjectAddressSet(address, AuthIdRelationId, roleid);
1464
1465 ReleaseSysCache(oldtuple);
1466
1467 /*
1468 * Close pg_authid, but keep lock till commit.
1469 */
1470 table_close(rel, NoLock);
1471
1472 return address;
1473}
1474
1475/*
1476 * GrantRoleStmt
1477 *
1478 * Grant/Revoke roles to/from roles
1479 */
1480void
1482{
1484 Oid grantor;
1486 ListCell *item;
1487 GrantRoleOptions popt;
1489
1490 /* Parse options list. */
1491 InitGrantRoleOptions(&popt);
1492 foreach(item, stmt->opt)
1493 {
1494 DefElem *opt = (DefElem *) lfirst(item);
1495 char *optval = defGetString(opt);
1496
1497 if (strcmp(opt->defname, "admin") == 0)
1498 {
1500
1501 if (parse_bool(optval, &popt.admin))
1502 continue;
1503 }
1504 else if (strcmp(opt->defname, "inherit") == 0)
1505 {
1507 if (parse_bool(optval, &popt.inherit))
1508 continue;
1509 }
1510 else if (strcmp(opt->defname, "set") == 0)
1511 {
1513 if (parse_bool(optval, &popt.set))
1514 continue;
1515 }
1516 else
1517 ereport(ERROR,
1519 errmsg("unrecognized role option \"%s\"", opt->defname),
1520 parser_errposition(pstate, opt->location));
1521
1522 ereport(ERROR,
1524 errmsg("unrecognized value for role option \"%s\": \"%s\"",
1525 opt->defname, optval),
1526 parser_errposition(pstate, opt->location)));
1527 }
1528
1529 /* Lookup OID of grantor, if specified. */
1530 if (stmt->grantor)
1531 grantor = get_rolespec_oid(stmt->grantor, false);
1532 else
1533 grantor = InvalidOid;
1534
1535 grantee_ids = roleSpecsToIds(stmt->grantee_roles);
1536
1537 /* AccessShareLock is enough since we aren't modifying pg_authid */
1539
1540 /*
1541 * Step through all of the granted roles and add, update, or remove
1542 * entries in pg_auth_members as appropriate. If stmt->is_grant is true,
1543 * we are adding new grants or, if they already exist, updating options on
1544 * those grants. If stmt->is_grant is false, we are revoking grants or
1545 * removing options from them.
1546 */
1547 foreach(item, stmt->granted_roles)
1548 {
1549 AccessPriv *priv = (AccessPriv *) lfirst(item);
1550 char *rolename = priv->priv_name;
1551 Oid roleid;
1552
1553 /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1554 if (rolename == NULL || priv->cols != NIL)
1555 ereport(ERROR,
1557 errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
1558
1559 roleid = get_role_oid(rolename, false);
1561 roleid, stmt->is_grant);
1562 if (stmt->is_grant)
1563 AddRoleMems(currentUserId, rolename, roleid,
1564 stmt->grantee_roles, grantee_ids,
1565 grantor, &popt);
1566 else
1567 DelRoleMems(currentUserId, rolename, roleid,
1568 stmt->grantee_roles, grantee_ids,
1569 grantor, &popt, stmt->behavior);
1570 }
1571
1572 /*
1573 * Close pg_authid, but keep lock till commit.
1574 */
1576}
1577
1578/*
1579 * DropOwnedObjects
1580 *
1581 * Drop the objects owned by a given list of roles.
1582 */
1583void
1585{
1586 List *role_ids = roleSpecsToIds(stmt->roles);
1587 ListCell *cell;
1588
1589 /* Check privileges */
1590 foreach(cell, role_ids)
1591 {
1592 Oid roleid = lfirst_oid(cell);
1593
1594 if (!has_privs_of_role(GetUserId(), roleid))
1595 ereport(ERROR,
1597 errmsg("permission denied to drop objects"),
1598 errdetail("Only roles with privileges of role \"%s\" may drop objects owned by it.",
1599 GetUserNameFromId(roleid, false))));
1600 }
1601
1602 /* Ok, do it */
1603 shdepDropOwned(role_ids, stmt->behavior);
1604}
1605
1606/*
1607 * ReassignOwnedObjects
1608 *
1609 * Give the objects owned by a given list of roles away to another user.
1610 */
1611void
1613{
1614 List *role_ids = roleSpecsToIds(stmt->roles);
1615 ListCell *cell;
1616 Oid newrole;
1617
1618 /* Check privileges */
1619 foreach(cell, role_ids)
1620 {
1621 Oid roleid = lfirst_oid(cell);
1622
1623 if (!has_privs_of_role(GetUserId(), roleid))
1624 ereport(ERROR,
1626 errmsg("permission denied to reassign objects"),
1627 errdetail("Only roles with privileges of role \"%s\" may reassign objects owned by it.",
1628 GetUserNameFromId(roleid, false))));
1629 }
1630
1631 /* Must have privileges on the receiving side too */
1632 newrole = get_rolespec_oid(stmt->newrole, false);
1633
1634 if (!has_privs_of_role(GetUserId(), newrole))
1635 ereport(ERROR,
1637 errmsg("permission denied to reassign objects"),
1638 errdetail("Only roles with privileges of role \"%s\" may reassign objects to it.",
1639 GetUserNameFromId(newrole, false))));
1640
1641 /* Ok, do it */
1642 shdepReassignOwned(role_ids, newrole);
1643}
1644
1645/*
1646 * roleSpecsToIds
1647 *
1648 * Given a list of RoleSpecs, generate a list of role OIDs in the same order.
1649 *
1650 * ROLESPEC_PUBLIC is not allowed.
1651 */
1652List *
1654{
1655 List *result = NIL;
1656 ListCell *l;
1657
1658 foreach(l, memberNames)
1659 {
1661 Oid roleid;
1662
1663 roleid = get_rolespec_oid(rolespec, false);
1664 result = lappend_oid(result, roleid);
1665 }
1666 return result;
1667}
1668
1669/*
1670 * AddRoleMems -- Add given members to the specified role
1671 *
1672 * currentUserId: OID of role performing the operation
1673 * rolename: name of role to add to (used only for error messages)
1674 * roleid: OID of role to add to
1675 * memberSpecs: list of RoleSpec of roles to add (used only for error messages)
1676 * memberIds: OIDs of roles to add
1677 * grantorId: OID that should be recorded as having granted the membership
1678 * (InvalidOid if not set explicitly)
1679 * popt: information about grant options
1680 */
1681static void
1682AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
1685{
1690
1692
1693 /* Validate grantor (and resolve implicit grantor if not specified). */
1695
1698
1699 /*
1700 * Only allow changes to this role by one backend at a time, so that we
1701 * can check integrity constraints like the lack of circular ADMIN OPTION
1702 * grants without fear of race conditions.
1703 */
1706
1707 /* Preliminary sanity checks. */
1709 {
1712
1713 /*
1714 * pg_database_owner is never a role member. Lifting this restriction
1715 * would require a policy decision about membership loops. One could
1716 * prevent loops, which would include making "ALTER DATABASE x OWNER
1717 * TO proposed_datdba" fail if is_member_of_role(pg_database_owner,
1718 * proposed_datdba). Hence, gaining a membership could reduce what a
1719 * role could do. Alternately, one could allow these memberships to
1720 * complete loops. A role could then have actual WITH ADMIN OPTION on
1721 * itself, prompting a decision about is_admin_of_role() treatment of
1722 * the case.
1723 *
1724 * Lifting this restriction also has policy implications for ownership
1725 * of shared objects (databases and tablespaces). We allow such
1726 * ownership, but we might find cause to ban it in the future.
1727 * Designing such a ban would more troublesome if the design had to
1728 * address pg_database_owner being a member of role FOO that owns a
1729 * shared object. (The effect of such ownership is that any owner of
1730 * another database can act as the owner of affected shared objects.)
1731 */
1733 ereport(ERROR,
1735 errmsg("role \"%s\" cannot be a member of any role",
1737
1738 /*
1739 * Refuse creation of membership loops, including the trivial case
1740 * where a role is made a member of itself. We do this by checking to
1741 * see if the target role is already a member of the proposed member
1742 * role. We have to ignore possible superuserness, however, else we
1743 * could never grant membership in a superuser-privileged role.
1744 */
1746 ereport(ERROR,
1748 errmsg("role \"%s\" is a member of role \"%s\"",
1749 rolename, get_rolespec_name(memberRole))));
1750 }
1751
1752 /*
1753 * Disallow attempts to grant ADMIN OPTION back to a user who granted it
1754 * to you, similar to what check_circularity does for ACLs. We want the
1755 * chains of grants to remain acyclic, so that it's always possible to use
1756 * REVOKE .. CASCADE to clean up all grants that depend on the one being
1757 * revoked.
1758 *
1759 * NB: This check might look redundant with the check for membership loops
1760 * above, but it isn't. That's checking for role-member loop (e.g. A is a
1761 * member of B and B is a member of A) while this is checking for a
1762 * member-grantor loop (e.g. A gave ADMIN OPTION on X to B and now B, who
1763 * has no other source of ADMIN OPTION on X, tries to give ADMIN OPTION on
1764 * X back to A).
1765 */
1766 if (popt->admin && grantorId != BOOTSTRAP_SUPERUSERID)
1767 {
1769 RevokeRoleGrantAction *actions;
1770 int i;
1771
1772 /* Get the list of members for this role. */
1774 ObjectIdGetDatum(roleid));
1775
1776 /*
1777 * Figure out what would happen if we removed all existing grants to
1778 * every role to which we've been asked to make a new grant.
1779 */
1781 foreach(iditem, memberIds)
1782 {
1784
1786 ereport(ERROR,
1788 errmsg("%s option cannot be granted back to your own grantor",
1789 "ADMIN")));
1791 }
1792
1793 /*
1794 * If the result would be that the grantor role would no longer have
1795 * the ability to perform the grant, then the proposed grant would
1796 * create a circularity.
1797 */
1798 for (i = 0; i < memlist->n_members; ++i)
1799 {
1802
1803 authmem_tuple = &memlist->members[i]->tuple;
1805
1806 if (actions[i] == RRG_NOOP &&
1807 authmem_form->member == grantorId &&
1808 authmem_form->admin_option)
1809 break;
1810 }
1811 if (i >= memlist->n_members)
1812 ereport(ERROR,
1814 errmsg("%s option cannot be granted back to your own grantor",
1815 "ADMIN")));
1816
1818 }
1819
1820 /* Now perform the catalog updates. */
1822 {
1826 HeapTuple tuple;
1830
1831 /* Common initialization for possible insert or update */
1833 ObjectIdGetDatum(roleid);
1838
1839 /* Find any existing tuple */
1841 ObjectIdGetDatum(roleid),
1844
1845 /*
1846 * If we found a tuple, update it with new option values, unless there
1847 * are no changes, in which case issue a WARNING.
1848 *
1849 * If we didn't find a tuple, just insert one.
1850 */
1852 {
1854 bool at_least_one_change = false;
1855
1857
1858 if ((popt->specified & GRANT_ROLE_SPECIFIED_ADMIN) != 0
1859 && authmem_form->admin_option != popt->admin)
1860 {
1862 BoolGetDatum(popt->admin);
1864 true;
1865 at_least_one_change = true;
1866 }
1867
1868 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0
1869 && authmem_form->inherit_option != popt->inherit)
1870 {
1872 BoolGetDatum(popt->inherit);
1874 true;
1875 at_least_one_change = true;
1876 }
1877
1878 if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0
1879 && authmem_form->set_option != popt->set)
1880 {
1882 BoolGetDatum(popt->set);
1884 true;
1885 at_least_one_change = true;
1886 }
1887
1889 {
1891 (errmsg("role \"%s\" has already been granted membership in role \"%s\" by role \"%s\"",
1892 get_rolespec_name(memberRole), rolename,
1893 GetUserNameFromId(grantorId, false))));
1895 continue;
1896 }
1897
1899 new_record,
1901 CatalogTupleUpdate(pg_authmem_rel, &tuple->t_self, tuple);
1902
1904 }
1905 else
1906 {
1907 Oid objectId;
1909
1910 /*
1911 * The values for these options can be taken directly from 'popt'.
1912 * Either they were specified, or the defaults as set by
1913 * InitGrantRoleOptions are correct.
1914 */
1916 BoolGetDatum(popt->admin);
1918 BoolGetDatum(popt->set);
1919
1920 /*
1921 * If the user specified a value for the inherit option, use
1922 * whatever was specified. Otherwise, set the default value based
1923 * on the role-level property.
1924 */
1925 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0)
1927 BoolGetDatum(popt->inherit);
1928 else
1929 {
1932
1934 if (!HeapTupleIsValid(mrtup))
1935 elog(ERROR, "cache lookup failed for role %u", memberid);
1938 BoolGetDatum(mrform->rolinherit);
1940 }
1941
1942 /* get an OID for the new row and insert it */
1949
1950 /* updateAclDependencies wants to pfree array inputs */
1951 newmembers[0] = grantorId;
1953 0, InvalidOid,
1954 0, NULL,
1955 1, newmembers);
1956 }
1957
1958 /* CCI after each change, in case there are duplicates in list */
1960 }
1961
1962 /*
1963 * Close pg_authmem, but keep lock till commit.
1964 */
1966}
1967
1968/*
1969 * DelRoleMems -- Remove given members from the specified role
1970 *
1971 * rolename: name of role to del from (used only for error messages)
1972 * roleid: OID of role to del from
1973 * memberSpecs: list of RoleSpec of roles to del (used only for error messages)
1974 * memberIds: OIDs of roles to del
1975 * grantorId: who is revoking the membership
1976 * popt: information about grant options
1977 * behavior: RESTRICT or CASCADE behavior for recursive removal
1978 */
1979static void
1980DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid,
1982 Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
1983{
1989 RevokeRoleGrantAction *actions;
1990 int i;
1991
1993
1994 /* Validate grantor (and resolve implicit grantor if not specified). */
1996
1999
2000 /*
2001 * Only allow changes to this role by one backend at a time, so that we
2002 * can check for things like dependent privileges without fear of race
2003 * conditions.
2004 */
2007
2010
2011 /*
2012 * We may need to recurse to dependent privileges if DROP_CASCADE was
2013 * specified, or refuse to perform the operation if dependent privileges
2014 * exist and DROP_RESTRICT was specified. plan_single_revoke() will figure
2015 * out what to do with each catalog tuple.
2016 */
2018 {
2021
2023 popt, behavior))
2024 {
2026 (errmsg("role \"%s\" has not been granted membership in role \"%s\" by role \"%s\"",
2027 get_rolespec_name(memberRole), rolename,
2028 GetUserNameFromId(grantorId, false))));
2029 continue;
2030 }
2031 }
2032
2033 /*
2034 * We now know what to do with each catalog tuple: it should either be
2035 * left alone, deleted, or just have the admin_option flag cleared.
2036 * Perform the appropriate action in each case.
2037 */
2038 for (i = 0; i < memlist->n_members; ++i)
2039 {
2042
2043 if (actions[i] == RRG_NOOP)
2044 continue;
2045
2046 authmem_tuple = &memlist->members[i]->tuple;
2048
2049 if (actions[i] == RRG_DELETE_GRANT)
2050 {
2051 /*
2052 * Remove the entry altogether, after first removing its
2053 * dependencies
2054 */
2056 authmem_form->oid, 0);
2058 }
2059 else
2060 {
2061 /* Just turn off the specified option */
2062 HeapTuple tuple;
2066
2067 /* Build a tuple to update with */
2068 if (actions[i] == RRG_REMOVE_ADMIN_OPTION)
2069 {
2071 BoolGetDatum(false);
2073 true;
2074 }
2075 else if (actions[i] == RRG_REMOVE_INHERIT_OPTION)
2076 {
2078 BoolGetDatum(false);
2080 true;
2081 }
2082 else if (actions[i] == RRG_REMOVE_SET_OPTION)
2083 {
2085 BoolGetDatum(false);
2087 true;
2088 }
2089 else
2090 elog(ERROR, "unknown role revoke action");
2091
2093 new_record,
2095 CatalogTupleUpdate(pg_authmem_rel, &tuple->t_self, tuple);
2096 }
2097 }
2098
2100
2101 /*
2102 * Close pg_authmem, but keep lock till commit.
2103 */
2105}
2106
2107/*
2108 * Check that currentUserId has permission to modify the membership list for
2109 * roleid. Throw an error if not.
2110 */
2111static void
2113 bool is_grant)
2114{
2115 /*
2116 * The charter of pg_database_owner is to have exactly one, implicit,
2117 * situation-dependent member. There's no technical need for this
2118 * restriction. (One could lift it and take the further step of making
2119 * object_ownercheck(DatabaseRelationId, ...) equivalent to
2120 * has_privs_of_role(roleid, ROLE_PG_DATABASE_OWNER), in which case
2121 * explicit, situation-independent members could act as the owner of any
2122 * database.)
2123 */
2124 if (is_grant && roleid == ROLE_PG_DATABASE_OWNER)
2125 ereport(ERROR,
2127 errmsg("role \"%s\" cannot have explicit members",
2128 GetUserNameFromId(roleid, false)));
2129
2130 /* To mess with a superuser role, you gotta be superuser. */
2131 if (superuser_arg(roleid))
2132 {
2134 {
2135 if (is_grant)
2136 ereport(ERROR,
2138 errmsg("permission denied to grant role \"%s\"",
2139 GetUserNameFromId(roleid, false)),
2140 errdetail("Only roles with the %s attribute may grant roles with the %s attribute.",
2141 "SUPERUSER", "SUPERUSER")));
2142 else
2143 ereport(ERROR,
2145 errmsg("permission denied to revoke role \"%s\"",
2146 GetUserNameFromId(roleid, false)),
2147 errdetail("Only roles with the %s attribute may revoke roles with the %s attribute.",
2148 "SUPERUSER", "SUPERUSER")));
2149 }
2150 }
2151 else
2152 {
2153 /*
2154 * Otherwise, must have admin option on the role to be changed.
2155 */
2156 if (!is_admin_of_role(currentUserId, roleid))
2157 {
2158 if (is_grant)
2159 ereport(ERROR,
2161 errmsg("permission denied to grant role \"%s\"",
2162 GetUserNameFromId(roleid, false)),
2163 errdetail("Only roles with the %s option on role \"%s\" may grant this role.",
2164 "ADMIN", GetUserNameFromId(roleid, false))));
2165 else
2166 ereport(ERROR,
2168 errmsg("permission denied to revoke role \"%s\"",
2169 GetUserNameFromId(roleid, false)),
2170 errdetail("Only roles with the %s option on role \"%s\" may revoke this role.",
2171 "ADMIN", GetUserNameFromId(roleid, false))));
2172 }
2173 }
2174}
2175
2176/*
2177 * Sanity-check, or infer, the grantor for a GRANT or REVOKE statement
2178 * targeting a role.
2179 *
2180 * The grantor must always be either a role with ADMIN OPTION on the role in
2181 * which membership is being granted, or the bootstrap superuser. This is
2182 * similar to the restriction enforced by select_best_grantor, except that
2183 * roles don't have owners, so we regard the bootstrap superuser as the
2184 * implicit owner.
2185 *
2186 * If the grantor was not explicitly specified by the user, grantorId should
2187 * be passed as InvalidOid, and this function will infer the user to be
2188 * recorded as the grantor. In many cases, this will be the current user, but
2189 * things get more complicated when the current user doesn't possess ADMIN
2190 * OPTION on the role but rather relies on having SUPERUSER privileges, or
2191 * on inheriting the privileges of a role which does have ADMIN OPTION. See
2192 * below for details.
2193 *
2194 * If the grantor was specified by the user, then it must be a user that
2195 * can legally be recorded as the grantor, as per the rule stated above.
2196 * This is an integrity constraint, not a permissions check, and thus even
2197 * superusers are subject to this restriction. However, there is also a
2198 * permissions check: to specify a role as the grantor, the current user
2199 * must possess the privileges of that role. Superusers will always pass
2200 * this check, but for non-superusers it may lead to an error.
2201 *
2202 * The return value is the OID to be regarded as the grantor when executing
2203 * the operation.
2204 */
2205static Oid
2207{
2208 /* If the grantor ID was not specified, pick one to use. */
2209 if (!OidIsValid(grantorId))
2210 {
2211 /*
2212 * Grants where the grantor is recorded as the bootstrap superuser do
2213 * not depend on any other existing grants, so always default to this
2214 * interpretation when possible.
2215 */
2217 return BOOTSTRAP_SUPERUSERID;
2218
2219 /*
2220 * Otherwise, the grantor must either have ADMIN OPTION on the role or
2221 * inherit the privileges of a role which does. In the former case,
2222 * record the grantor as the current user; in the latter, pick one of
2223 * the roles that is "most directly" inherited by the current role
2224 * (i.e. fewest "hops").
2225 *
2226 * (We shouldn't fail to find a best grantor, because we've already
2227 * established that the current user has permission to perform the
2228 * operation.)
2229 */
2231 if (!OidIsValid(grantorId))
2232 elog(ERROR, "no possible grantors");
2233 return grantorId;
2234 }
2235
2236 /*
2237 * If an explicit grantor is specified, it must be a role whose privileges
2238 * the current user possesses.
2239 *
2240 * It should also be a role that has ADMIN OPTION on the target role, but
2241 * we check this condition only in case of GRANT. For REVOKE, no matching
2242 * grant should exist anyway, but if it somehow does, let the user get rid
2243 * of it.
2244 */
2245 if (is_grant)
2246 {
2248 ereport(ERROR,
2250 errmsg("permission denied to grant privileges as role \"%s\"",
2252 errdetail("Only roles with privileges of role \"%s\" may grant privileges as this role.",
2253 GetUserNameFromId(grantorId, false))));
2254
2257 ereport(ERROR,
2259 errmsg("permission denied to grant privileges as role \"%s\"",
2261 errdetail("The grantor must have the %s option on role \"%s\".",
2262 "ADMIN", GetUserNameFromId(roleid, false))));
2263 }
2264 else
2265 {
2267 ereport(ERROR,
2269 errmsg("permission denied to revoke privileges granted by role \"%s\"",
2271 errdetail("Only roles with privileges of role \"%s\" may revoke privileges granted by this role.",
2272 GetUserNameFromId(grantorId, false))));
2273 }
2274
2275 /*
2276 * If a grantor was specified explicitly, always attribute the grant to
2277 * that role (unless we error out above).
2278 */
2279 return grantorId;
2280}
2281
2282/*
2283 * Initialize an array of RevokeRoleGrantAction objects.
2284 *
2285 * 'memlist' should be a list of all grants for the target role.
2286 *
2287 * This constructs an array indicating that no actions are to be performed;
2288 * that is, every element is initially RRG_NOOP.
2289 */
2290static RevokeRoleGrantAction *
2292{
2293 RevokeRoleGrantAction *result;
2294 int i;
2295
2296 if (memlist->n_members == 0)
2297 return NULL;
2298
2299 result = palloc_array(RevokeRoleGrantAction, memlist->n_members);
2300 for (i = 0; i < memlist->n_members; i++)
2301 result[i] = RRG_NOOP;
2302 return result;
2303}
2304
2305/*
2306 * Figure out what we would need to do in order to revoke a grant, or just the
2307 * admin option on a grant, given that there might be dependent privileges.
2308 *
2309 * 'memlist' should be a list of all grants for the target role.
2310 *
2311 * Whatever actions prove to be necessary will be signalled by updating
2312 * 'actions'.
2313 *
2314 * If behavior is DROP_RESTRICT, an error will occur if there are dependent
2315 * role membership grants; if DROP_CASCADE, those grants will be scheduled
2316 * for deletion.
2317 *
2318 * The return value is true if the matching grant was found in the list,
2319 * and false if not.
2320 */
2321static bool
2323 Oid member, Oid grantor, GrantRoleOptions *popt,
2324 DropBehavior behavior)
2325{
2326 int i;
2327
2328 /*
2329 * If popt.specified == 0, we're revoking the grant entirely; otherwise,
2330 * we expect just one bit to be set, and we're revoking the corresponding
2331 * option. As of this writing, there's no syntax that would allow for an
2332 * attempt to revoke multiple options at once, and the logic below
2333 * wouldn't work properly if such syntax were added, so assert that our
2334 * caller isn't trying to do that.
2335 */
2336 Assert(pg_popcount32(popt->specified) <= 1);
2337
2338 for (i = 0; i < memlist->n_members; ++i)
2339 {
2342
2343 authmem_tuple = &memlist->members[i]->tuple;
2345
2346 if (authmem_form->member == member &&
2347 authmem_form->grantor == grantor)
2348 {
2349 if ((popt->specified & GRANT_ROLE_SPECIFIED_INHERIT) != 0)
2350 {
2351 /*
2352 * Revoking the INHERIT option doesn't change anything for
2353 * dependent privileges, so we don't need to recurse.
2354 */
2355 actions[i] = RRG_REMOVE_INHERIT_OPTION;
2356 }
2357 else if ((popt->specified & GRANT_ROLE_SPECIFIED_SET) != 0)
2358 {
2359 /* Here too, no need to recurse. */
2360 actions[i] = RRG_REMOVE_SET_OPTION;
2361 }
2362 else
2363 {
2365
2366 /*
2367 * Revoking the grant entirely, or ADMIN option on a grant,
2368 * implicates dependent privileges, so we may need to recurse.
2369 */
2373 revoke_admin_option_only, behavior);
2374 }
2375 return true;
2376 }
2377 }
2378
2379 return false;
2380}
2381
2382/*
2383 * Figure out what we would need to do in order to revoke all grants to
2384 * a given member, given that there might be dependent privileges.
2385 *
2386 * 'memlist' should be a list of all grants for the target role.
2387 *
2388 * Whatever actions prove to be necessary will be signalled by updating
2389 * 'actions'.
2390 */
2391static void
2393 Oid member)
2394{
2395 int i;
2396
2397 for (i = 0; i < memlist->n_members; ++i)
2398 {
2401
2402 authmem_tuple = &memlist->members[i]->tuple;
2404
2405 if (authmem_form->member == member)
2406 plan_recursive_revoke(memlist, actions, i, false, DROP_CASCADE);
2407 }
2408}
2409
2410/*
2411 * Workhorse for figuring out recursive revocation of role grants.
2412 *
2413 * This is similar to what recursive_revoke() does for ACLs.
2414 */
2415static void
2417 int index,
2419{
2420 bool would_still_have_admin_option = false;
2423 int i;
2424
2425 /* If it's already been done, we can just return. */
2426 if (actions[index] == RRG_DELETE_GRANT)
2427 return;
2428 if (actions[index] == RRG_REMOVE_ADMIN_OPTION &&
2430 return;
2431
2432 /* Locate tuple data. */
2433 authmem_tuple = &memlist->members[index]->tuple;
2435
2436 /*
2437 * If the existing tuple does not have admin_option set, then we do not
2438 * need to recurse. If we're just supposed to clear that bit we don't need
2439 * to do anything at all; if we're supposed to remove the grant, we need
2440 * to do something, but only to the tuple, and not any others.
2441 */
2443 {
2444 actions[index] = RRG_DELETE_GRANT;
2445 if (!authmem_form->admin_option)
2446 return;
2447 }
2448 else
2449 {
2450 if (!authmem_form->admin_option)
2451 return;
2452 actions[index] = RRG_REMOVE_ADMIN_OPTION;
2453 }
2454
2455 /* Determine whether the member would still have ADMIN OPTION. */
2456 for (i = 0; i < memlist->n_members; ++i)
2457 {
2460
2461 am_cascade_tuple = &memlist->members[i]->tuple;
2463
2464 if (am_cascade_form->member == authmem_form->member &&
2465 am_cascade_form->admin_option && actions[i] == RRG_NOOP)
2466 {
2468 break;
2469 }
2470 }
2471
2472 /* If the member would still have ADMIN OPTION, we need not recurse. */
2474 return;
2475
2476 /*
2477 * Recurse to grants that are not yet slated for deletion which have this
2478 * member as the grantor.
2479 */
2480 for (i = 0; i < memlist->n_members; ++i)
2481 {
2484
2485 am_cascade_tuple = &memlist->members[i]->tuple;
2487
2488 if (am_cascade_form->grantor == authmem_form->member &&
2489 actions[i] != RRG_DELETE_GRANT)
2490 {
2491 if (behavior == DROP_RESTRICT)
2492 ereport(ERROR,
2494 errmsg("dependent privileges exist"),
2495 errhint("Use CASCADE to revoke them too.")));
2496
2497 plan_recursive_revoke(memlist, actions, i, false, behavior);
2498 }
2499 }
2500}
2501
2502/*
2503 * Initialize a GrantRoleOptions object with default values.
2504 */
2505static void
2507{
2508 popt->specified = 0;
2509 popt->admin = false;
2510 popt->inherit = false;
2511 popt->set = true;
2512}
2513
2514/*
2515 * GUC check_hook for createrole_self_grant
2516 */
2517bool
2519{
2520 char *rawstring;
2521 List *elemlist;
2522 ListCell *l;
2523 unsigned options = 0;
2524 unsigned *result;
2525
2526 /* Need a modifiable copy of string */
2528
2530 {
2531 /* syntax error in list */
2532 GUC_check_errdetail("List syntax is invalid.");
2535 return false;
2536 }
2537
2538 foreach(l, elemlist)
2539 {
2540 char *tok = (char *) lfirst(l);
2541
2542 if (pg_strcasecmp(tok, "SET") == 0)
2544 else if (pg_strcasecmp(tok, "INHERIT") == 0)
2546 else
2547 {
2548 GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
2551 return false;
2552 }
2553 }
2554
2557
2558 result = (unsigned *) guc_malloc(LOG, sizeof(unsigned));
2559 if (!result)
2560 return false;
2561 *result = options;
2562 *extra = result;
2563
2564 return true;
2565}
2566
2567/*
2568 * GUC assign_hook for createrole_self_grant
2569 */
2570void
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5414
Oid select_best_admin(Oid member, Oid role)
Definition acl.c:5439
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition acl.c:5392
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5284
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5552
char * get_rolespec_name(const RoleSpec *role)
Definition acl.c:5671
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5693
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5586
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5625
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
bool has_bypassrls_privilege(Oid roleid)
Definition aclchk.c:4188
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:4090
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4169
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:97
#define TextDatumGetCString(d)
Definition builtins.h:98
#define NameStr(name)
Definition c.h:765
#define STATUS_OK
Definition c.h:1158
#define Assert(condition)
Definition c.h:873
#define OidIsValid(objectId)
Definition c.h:788
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:374
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
Definition crypt.c:256
PasswordType get_password_type(const char *shadow_pass)
Definition crypt.c:90
char * encrypt_password(PasswordType target_type, const char *role, const char *password)
Definition crypt.c:117
@ PASSWORD_TYPE_SCRAM_SHA_256
Definition crypt.h:44
@ PASSWORD_TYPE_MD5
Definition crypt.h:43
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:685
char * defGetString(DefElem *def)
Definition define.c:34
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
int errdetail_internal(const char *fmt,...)
Definition elog.c:1243
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
int errdetail_log(const char *fmt,...)
Definition elog.c:1264
#define _(x)
Definition elog.c:91
#define LOG
Definition elog.h:31
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#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:505
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
FormData_pg_auth_members * Form_pg_auth_members
FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:56
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:491
#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:56
bool superuser(void)
Definition superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220
HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:240
Datum SysCacheGetAttr(int 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:1335
#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:2322
static GrantRoleOptions createrole_self_grant_options
Definition user.c:89
static void InitGrantRoleOptions(GrantRoleOptions *popt)
Definition user.c:2506
static void plan_member_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, Oid member)
Definition user.c:2392
static void AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt)
Definition user.c:1682
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
Definition user.c:1612
Oid AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
Definition user.c:620
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:1001
static Oid check_role_grantor(Oid currentUserId, Oid roleid, Oid grantorId, bool is_grant)
Definition user.c:2206
int Password_encryption
Definition user.c:86
bool check_createrole_self_grant(char **newval, void **extra, GucSource source)
Definition user.c:2518
void assign_createrole_self_grant(const char *newval, void *extra)
Definition user.c:2571
static void check_role_membership_authorization(Oid currentUserId, Oid roleid, bool is_grant)
Definition user.c:2112
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:1091
Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
Definition user.c:133
void GrantRole(ParseState *pstate, GrantRoleStmt *stmt)
Definition user.c:1481
List * roleSpecsToIds(List *memberNames)
Definition user.c:1653
static void plan_recursive_revoke(CatCList *memlist, RevokeRoleGrantAction *actions, int index, bool revoke_admin_option_only, DropBehavior behavior)
Definition user.c:2416
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:2291
void DropOwnedObjects(DropOwnedStmt *stmt)
Definition user.c:1584
static void DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
Definition user.c:1980
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:2730
void CommandCounterIncrement(void)
Definition xact.c:1101