PostgreSQL Source Code git master
Loading...
Searching...
No Matches
user.h File Reference
#include "catalog/objectaddress.h"
#include "libpq/crypt.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/guc.h"
Include dependency graph for user.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef void(* check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null)
 

Functions

Oid CreateRole (ParseState *pstate, CreateRoleStmt *stmt)
 
Oid AlterRole (ParseState *pstate, AlterRoleStmt *stmt)
 
Oid AlterRoleSet (AlterRoleSetStmt *stmt)
 
void DropRole (DropRoleStmt *stmt)
 
void GrantRole (ParseState *pstate, GrantRoleStmt *stmt)
 
ObjectAddress RenameRole (const char *oldname, const char *newname)
 
void DropOwnedObjects (DropOwnedStmt *stmt)
 
void ReassignOwnedObjects (ReassignOwnedStmt *stmt)
 
ListroleSpecsToIds (List *memberNames)
 
bool check_createrole_self_grant (char **newval, void **extra, GucSource source)
 
void assign_createrole_self_grant (const char *newval, void *extra)
 

Variables

PGDLLIMPORT int Password_encryption
 
PGDLLIMPORT charcreaterole_self_grant
 
PGDLLIMPORT check_password_hook_type check_password_hook
 

Typedef Documentation

◆ check_password_hook_type

Definition at line 25 of file user.h.

Function Documentation

◆ AlterRole()

Oid AlterRole ( ParseState pstate,
AlterRoleStmt stmt 
)
extern

Definition at line 626 of file user.c.

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}
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5416
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5695
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5627
bool has_bypassrls_privilege(Oid roleid)
Definition aclchk.c:4206
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition timestamp.c:418
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define NameStr(name)
Definition c.h:798
#define STATUS_OK
Definition c.h:1207
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
bool have_createdb_privilege(void)
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
int errdetail(const char *fmt,...) pg_attribute_printf(1
#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 DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
static void * GETSTRUCT(const HeapTupleData *tuple)
#define stmt
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
#define NoLock
Definition lockdefs.h:34
#define RowExclusiveLock
Definition lockdefs.h:38
char * pstrdup(const char *in)
Definition mcxt.c:1781
Oid GetUserId(void)
Definition miscinit.c:469
bool has_rolreplication(Oid roleid)
Definition miscinit.c:688
#define InvokeObjectPostAlterHook(classId, objectId, subId)
@ DROP_RESTRICT
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
#define lfirst(lc)
Definition pg_list.h:172
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
static char * password
Definition streamutil.c:51
ItemPointerData t_self
Definition htup.h:65
Definition pg_list.h:54
bool superuser(void)
Definition superuser.c:47
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
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
static void InitGrantRoleOptions(GrantRoleOptions *popt)
Definition user.c:2518
static void AddRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt)
Definition user.c:1694
int Password_encryption
Definition user.c:86
List * roleSpecsToIds(List *memberNames)
Definition user.c:1665
check_password_hook_type check_password_hook
Definition user.c:92
static void DelRoleMems(Oid currentUserId, const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, GrantRoleOptions *popt, DropBehavior behavior)
Definition user.c:1992
#define boolVal(v)
Definition value.h:81
#define intVal(v)
Definition value.h:79
#define strVal(v)
Definition value.h:82
void CommandCounterIncrement(void)
Definition xact.c:1101

References _, AddRoleMems(), BoolGetDatum(), boolVal, CatalogTupleUpdate(), check_password_hook, check_rolespec_name(), CommandCounterIncrement(), CStringGetDatum(), CStringGetTextDatum, DelRoleMems(), DirectFunctionCall3, DROP_RESTRICT, elog, encrypt_password(), ereport, errcode(), errdetail(), errmsg(), ERROR, errorConflictingDefElem(), fb(), Form_pg_authid, get_password_type(), get_rolespec_tuple(), GETSTRUCT(), GetUserId(), has_bypassrls_privilege(), has_rolreplication(), have_createdb_privilege(), have_createrole_privilege(), heap_freetuple(), heap_modify_tuple(), InitGrantRoleOptions(), Int32GetDatum(), intVal, InvalidOid, InvokeObjectPostAlterHook, is_admin_of_role(), lfirst, NameStr, NoLock, NOTICE, ObjectIdGetDatum(), password, Password_encryption, plain_crypt_verify(), pstrdup(), RelationGetDescr, ReleaseSysCache(), roleSpecsToIds(), RowExclusiveLock, STATUS_OK, stmt, strVal, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, table_close(), table_open(), and timestamptz_in().

Referenced by standard_ProcessUtility().

◆ AlterRoleSet()

Oid AlterRoleSet ( AlterRoleSetStmt stmt)
extern

Definition at line 1007 of file user.c.

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}
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
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
Oid get_database_oid(const char *dbname, bool missing_ok)
@ OBJECT_DATABASE
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
void shdepLockAndCheckObject(Oid classId, Oid objectId)

References _, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterSetting(), check_rolespec_name(), ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), Form_pg_authid, get_database_oid(), get_rolespec_tuple(), GETSTRUCT(), GetUserId(), have_createrole_privilege(), InvalidOid, is_admin_of_role(), NameStr, OBJECT_DATABASE, object_ownercheck(), ReleaseSysCache(), shdepLockAndCheckObject(), stmt, and superuser().

Referenced by standard_ProcessUtility().

◆ assign_createrole_self_grant()

void assign_createrole_self_grant ( const char newval,
void extra 
)
extern

◆ check_createrole_self_grant()

bool check_createrole_self_grant ( char **  newval,
void **  extra,
GucSource  source 
)
extern

Definition at line 2530 of file user.c.

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}
#define LOG
Definition elog.h:31
void * guc_malloc(int elevel, size_t size)
Definition guc.c:636
#define newval
#define GUC_check_errdetail
Definition guc.h:506
void list_free(List *list)
Definition list.c:1546
void pfree(void *pointer)
Definition mcxt.c:1616
int pg_strcasecmp(const char *s1, const char *s2)
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition varlena.c:2775

References fb(), GRANT_ROLE_SPECIFIED_INHERIT, GRANT_ROLE_SPECIFIED_SET, GUC_check_errdetail, guc_malloc(), lfirst, list_free(), LOG, newval, pfree(), pg_strcasecmp(), pstrdup(), and SplitIdentifierString().

◆ CreateRole()

Oid CreateRole ( ParseState pstate,
CreateRoleStmt stmt 
)
extern

Definition at line 133 of file user.c.

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}
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5554
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4187
#define OidIsValid(objectId)
Definition c.h:821
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:448
bool IsReservedName(const char *name)
Definition catalog.c:278
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition dbcommands.c:686
#define WARNING
Definition elog.h:36
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
bool IsBinaryUpgrade
Definition globals.c:121
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
Datum namein(PG_FUNCTION_ARGS)
Definition name.c:48
#define makeNode(_type_)
Definition nodes.h:161
#define InvokeObjectPostCreateHook(classId, objectId, subId)
@ ROLESPEC_CSTRING
Definition parsenodes.h:419
@ ROLESPEC_CURRENT_ROLE
Definition parsenodes.h:420
@ ROLESTMT_ROLE
@ ROLESTMT_USER
@ ROLESTMT_GROUP
#define NIL
Definition pg_list.h:68
#define list_make1_oid(x1)
Definition pg_list.h:242
#define list_make1(x1)
Definition pg_list.h:212
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
bool superuser_arg(Oid roleid)
Definition superuser.c:57
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

References AddRoleMems(), GrantRoleOptions::admin, binary_upgrade_next_pg_authid_oid, BoolGetDatum(), boolVal, CatalogTupleInsert(), check_password_hook, check_role_membership_authorization(), CommandCounterIncrement(), createdb(), createrole_self_grant_enabled, createrole_self_grant_options, CStringGetDatum(), CStringGetTextDatum, DirectFunctionCall1, DirectFunctionCall3, elog, encrypt_password(), ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errmsg(), ERROR, errorConflictingDefElem(), fb(), Form_pg_authid, get_password_type(), get_role_oid(), get_rolespec_tuple(), GetNewOidWithIndex(), GETSTRUCT(), GetUserId(), GRANT_ROLE_SPECIFIED_ADMIN, GRANT_ROLE_SPECIFIED_INHERIT, GRANT_ROLE_SPECIFIED_SET, has_bypassrls_privilege(), has_createrole_privilege(), has_rolreplication(), have_createdb_privilege(), heap_form_tuple(), InitGrantRoleOptions(), Int32GetDatum(), intVal, InvalidOid, InvokeObjectPostCreateHook, IsBinaryUpgrade, IsReservedName(), lfirst, list_make1, list_make1_oid, makeNode, namein(), NameStr, NIL, NoLock, NOTICE, ObjectIdGetDatum(), OidIsValid, password, Password_encryption, plain_crypt_verify(), RelationGetDescr, ReleaseSysCache(), ROLESPEC_CSTRING, ROLESPEC_CURRENT_ROLE, roleSpecsToIds(), ROLESTMT_GROUP, ROLESTMT_ROLE, ROLESTMT_USER, RowExclusiveLock, GrantRoleOptions::specified, STATUS_OK, stmt, strVal, superuser(), superuser_arg(), table_close(), table_open(), timestamptz_in(), and WARNING.

Referenced by standard_ProcessUtility().

◆ DropOwnedObjects()

void DropOwnedObjects ( DropOwnedStmt stmt)
extern

Definition at line 1596 of file user.c.

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}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5286
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:988
#define lfirst_oid(lc)
Definition pg_list.h:174
void shdepDropOwned(List *roleids, DropBehavior behavior)

References ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), GetUserId(), GetUserNameFromId(), has_privs_of_role(), lfirst_oid, roleSpecsToIds(), shdepDropOwned(), and stmt.

Referenced by ProcessUtilitySlow().

◆ DropRole()

void DropRole ( DropRoleStmt stmt)
extern

Definition at line 1097 of file user.c.

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}
void DeleteSharedComments(Oid oid, Oid classoid)
Definition comment.c:384
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int int int errdetail_log(const char *fmt,...) pg_attribute_printf(1
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
#define HeapTupleIsValid(tuple)
Definition htup.h:78
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
List * list_append_unique_oid(List *list, Oid datum)
Definition list.c:1380
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1088
#define AccessExclusiveLock
Definition lockdefs.h:43
Oid GetOuterUserId(void)
Definition miscinit.c:480
Oid GetSessionUserId(void)
Definition miscinit.c:508
#define InvokeObjectDropHook(classId, objectId, subId)
END_CATALOG_STRUCT typedef FormData_pg_auth_members * Form_pg_auth_members
void DropSetting(Oid databaseid, Oid roleid)
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
bool checkSharedDependencies(Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
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
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220

References AccessExclusiveLock, BTEqualStrategyNumber, CatalogTupleDelete(), checkSharedDependencies(), CommandCounterIncrement(), DeleteSharedComments(), deleteSharedDependencyRecordsFor(), DeleteSharedSecurityLabel(), DropSetting(), elog, ereport, errcode(), errdetail(), errdetail_internal(), errdetail_log(), errmsg(), ERROR, fb(), Form_pg_auth_members, Form_pg_authid, GetOuterUserId(), GetSessionUserId(), GETSTRUCT(), GetUserId(), have_createrole_privilege(), HeapTupleIsValid, InvalidOid, InvokeObjectDropHook, is_admin_of_role(), lfirst, lfirst_oid, list_append_unique_oid(), LockSharedObject(), NameStr, NIL, NoLock, NOTICE, ObjectIdGetDatum(), PointerGetDatum(), ReleaseSysCache(), ROLESPEC_CSTRING, RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), stmt, superuser(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by standard_ProcessUtility().

◆ GrantRole()

void GrantRole ( ParseState pstate,
GrantRoleStmt stmt 
)
extern

Definition at line 1493 of file user.c.

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}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5588
bool parse_bool(const char *value, bool *result)
Definition bool.c:31
char * defGetString(DefElem *def)
Definition define.c:34
#define AccessShareLock
Definition lockdefs.h:36
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
char * priv_name
List * cols
char * defname
Definition parsenodes.h:844
ParseLoc location
Definition parsenodes.h:848

References AccessShareLock, AddRoleMems(), GrantRoleOptions::admin, check_role_membership_authorization(), AccessPriv::cols, defGetString(), DefElem::defname, DelRoleMems(), ereport, errcode(), errmsg(), ERROR, fb(), get_role_oid(), get_rolespec_oid(), GetUserId(), GRANT_ROLE_SPECIFIED_ADMIN, GRANT_ROLE_SPECIFIED_INHERIT, GRANT_ROLE_SPECIFIED_SET, GrantRoleOptions::inherit, InitGrantRoleOptions(), InvalidOid, lfirst, DefElem::location, NIL, NoLock, parse_bool(), parser_errposition(), AccessPriv::priv_name, roleSpecsToIds(), GrantRoleOptions::set, GrantRoleOptions::specified, stmt, table_close(), and table_open().

Referenced by standard_ProcessUtility().

◆ ReassignOwnedObjects()

void ReassignOwnedObjects ( ReassignOwnedStmt stmt)
extern

Definition at line 1624 of file user.c.

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}
void shdepReassignOwned(List *roleids, Oid newrole)

References ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), get_rolespec_oid(), GetUserId(), GetUserNameFromId(), has_privs_of_role(), lfirst_oid, roleSpecsToIds(), shdepReassignOwned(), and stmt.

Referenced by standard_ProcessUtility().

◆ RenameRole()

ObjectAddress RenameRole ( const char oldname,
const char newname 
)
extern

Definition at line 1341 of file user.c.

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}
#define TextDatumGetCString(d)
Definition builtins.h:99
@ PASSWORD_TYPE_MD5
Definition crypt.h:46
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
int i
Definition isn.c:77
#define ObjectAddressSet(addr, class_id, object_id)
#define SearchSysCacheExists1(cacheId, key1)
Definition syscache.h:100

References CatalogTupleUpdate(), CStringGetDatum(), DirectFunctionCall1, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errmsg(), ERROR, fb(), Form_pg_authid, get_password_type(), GetOuterUserId(), GetSessionUserId(), GETSTRUCT(), GetUserId(), have_createrole_privilege(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, i, InvokeObjectPostAlterHook, is_admin_of_role(), IsReservedName(), namein(), NameStr, NoLock, NOTICE, ObjectAddressSet, PASSWORD_TYPE_MD5, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), SearchSysCacheExists1, superuser(), HeapTupleData::t_self, table_close(), table_open(), TextDatumGetCString, and WARNING.

Referenced by ExecRenameStmt().

◆ roleSpecsToIds()

List * roleSpecsToIds ( List memberNames)
extern

Definition at line 1665 of file user.c.

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}
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
#define lfirst_node(type, lc)
Definition pg_list.h:176

References fb(), get_rolespec_oid(), lappend_oid(), lfirst_node, and NIL.

Referenced by AlterRole(), AlterTableMoveAll(), CreateRole(), DropOwnedObjects(), GrantRole(), and ReassignOwnedObjects().

Variable Documentation

◆ check_password_hook

PGDLLIMPORT check_password_hook_type check_password_hook
extern

Definition at line 92 of file user.c.

Referenced by _PG_init(), AlterRole(), and CreateRole().

◆ createrole_self_grant

PGDLLIMPORT char* createrole_self_grant
extern

Definition at line 87 of file user.c.

◆ Password_encryption

PGDLLIMPORT int Password_encryption
extern

Definition at line 86 of file user.c.

Referenced by AlterRole(), CheckPWChallengeAuth(), and CreateRole().