37 #include "utils/fmgroids.h"
54 Oid grantorId,
bool admin_opt);
82 char *password =
NULL;
87 bool createrole =
false;
89 bool canlogin =
false;
90 bool isreplication =
false;
91 bool bypassrls =
false;
97 char *validUntil =
NULL;
98 Datum validUntil_datum;
132 if (strcmp(defel->
defname,
"password") == 0 ||
133 strcmp(defel->
defname,
"encryptedPassword") == 0 ||
134 strcmp(defel->
defname,
"unencryptedPassword") == 0)
138 (
errcode(ERRCODE_SYNTAX_ERROR),
139 errmsg(
"conflicting or redundant options")));
141 if (strcmp(defel->
defname,
"encryptedPassword") == 0)
142 encrypt_password =
true;
143 else if (strcmp(defel->
defname,
"unencryptedPassword") == 0)
144 encrypt_password =
false;
146 else if (strcmp(defel->
defname,
"sysid") == 0)
149 (
errmsg(
"SYSID can no longer be specified")));
151 else if (strcmp(defel->
defname,
"superuser") == 0)
155 (
errcode(ERRCODE_SYNTAX_ERROR),
156 errmsg(
"conflicting or redundant options")));
159 else if (strcmp(defel->
defname,
"inherit") == 0)
163 (
errcode(ERRCODE_SYNTAX_ERROR),
164 errmsg(
"conflicting or redundant options")));
167 else if (strcmp(defel->
defname,
"createrole") == 0)
171 (
errcode(ERRCODE_SYNTAX_ERROR),
172 errmsg(
"conflicting or redundant options")));
175 else if (strcmp(defel->
defname,
"createdb") == 0)
179 (
errcode(ERRCODE_SYNTAX_ERROR),
180 errmsg(
"conflicting or redundant options")));
183 else if (strcmp(defel->
defname,
"canlogin") == 0)
187 (
errcode(ERRCODE_SYNTAX_ERROR),
188 errmsg(
"conflicting or redundant options")));
191 else if (strcmp(defel->
defname,
"isreplication") == 0)
195 (
errcode(ERRCODE_SYNTAX_ERROR),
196 errmsg(
"conflicting or redundant options")));
197 disreplication = defel;
199 else if (strcmp(defel->
defname,
"connectionlimit") == 0)
203 (
errcode(ERRCODE_SYNTAX_ERROR),
204 errmsg(
"conflicting or redundant options")));
207 else if (strcmp(defel->
defname,
"addroleto") == 0)
211 (
errcode(ERRCODE_SYNTAX_ERROR),
212 errmsg(
"conflicting or redundant options")));
215 else if (strcmp(defel->
defname,
"rolemembers") == 0)
219 (
errcode(ERRCODE_SYNTAX_ERROR),
220 errmsg(
"conflicting or redundant options")));
221 drolemembers = defel;
223 else if (strcmp(defel->
defname,
"adminmembers") == 0)
227 (
errcode(ERRCODE_SYNTAX_ERROR),
228 errmsg(
"conflicting or redundant options")));
229 dadminmembers = defel;
231 else if (strcmp(defel->
defname,
"validUntil") == 0)
235 (
errcode(ERRCODE_SYNTAX_ERROR),
236 errmsg(
"conflicting or redundant options")));
239 else if (strcmp(defel->
defname,
"bypassrls") == 0)
243 (
errcode(ERRCODE_SYNTAX_ERROR),
244 errmsg(
"conflicting or redundant options")));
248 elog(
ERROR,
"option \"%s\" not recognized",
252 if (dpassword && dpassword->
arg)
259 createrole =
intVal(dcreaterole->
arg) != 0;
265 isreplication =
intVal(disreplication->
arg) != 0;
271 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
272 errmsg(
"invalid connection limit: %d", connlimit)));
275 addroleto = (
List *) daddroleto->
arg;
277 rolemembers = (
List *) drolemembers->
arg;
279 adminmembers = (
List *) dadminmembers->
arg;
283 bypassrls =
intVal(dbypassRLS->
arg) != 0;
290 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
291 errmsg(
"must be superuser to create superusers")));
293 else if (isreplication)
297 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
298 errmsg(
"must be superuser to create replication users")));
304 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
305 errmsg(
"must be superuser to change bypassrls attribute")));
311 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
312 errmsg(
"permission denied to create role")));
321 (
errcode(ERRCODE_RESERVED_NAME),
322 errmsg(
"role name \"%s\" is reserved",
324 errdetail(
"Role names starting with \"pg_\" are reserved.")));
336 errmsg(
"role \"%s\" already exists",
346 validUntil_null =
false;
350 validUntil_datum = (
Datum) 0;
351 validUntil_null =
true;
358 (*check_password_hook) (stmt->
role,
367 MemSet(new_record, 0,
sizeof(new_record));
368 MemSet(new_record_nulls,
false,
sizeof(new_record_nulls));
383 if (!encrypt_password ||
isMD5(password))
390 elog(
ERROR,
"password encryption failed");
413 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
414 errmsg(
"pg_authid OID value not set when in binary upgrade mode")));
430 if (addroleto || adminmembers || rolemembers)
436 foreach(item, addroleto)
493 char *rolename =
NULL;
494 char *password =
NULL;
502 int isreplication = -1;
505 char *validUntil =
NULL;
506 Datum validUntil_datum;
507 bool validUntil_null;
523 "Cannot alter reserved roles.");
530 if (strcmp(defel->
defname,
"password") == 0 ||
531 strcmp(defel->
defname,
"encryptedPassword") == 0 ||
532 strcmp(defel->
defname,
"unencryptedPassword") == 0)
536 (
errcode(ERRCODE_SYNTAX_ERROR),
537 errmsg(
"conflicting or redundant options")));
539 if (strcmp(defel->
defname,
"encryptedPassword") == 0)
540 encrypt_password =
true;
541 else if (strcmp(defel->
defname,
"unencryptedPassword") == 0)
542 encrypt_password =
false;
544 else if (strcmp(defel->
defname,
"superuser") == 0)
548 (
errcode(ERRCODE_SYNTAX_ERROR),
549 errmsg(
"conflicting or redundant options")));
552 else if (strcmp(defel->
defname,
"inherit") == 0)
556 (
errcode(ERRCODE_SYNTAX_ERROR),
557 errmsg(
"conflicting or redundant options")));
560 else if (strcmp(defel->
defname,
"createrole") == 0)
564 (
errcode(ERRCODE_SYNTAX_ERROR),
565 errmsg(
"conflicting or redundant options")));
568 else if (strcmp(defel->
defname,
"createdb") == 0)
572 (
errcode(ERRCODE_SYNTAX_ERROR),
573 errmsg(
"conflicting or redundant options")));
576 else if (strcmp(defel->
defname,
"canlogin") == 0)
580 (
errcode(ERRCODE_SYNTAX_ERROR),
581 errmsg(
"conflicting or redundant options")));
584 else if (strcmp(defel->
defname,
"isreplication") == 0)
588 (
errcode(ERRCODE_SYNTAX_ERROR),
589 errmsg(
"conflicting or redundant options")));
590 disreplication = defel;
592 else if (strcmp(defel->
defname,
"connectionlimit") == 0)
596 (
errcode(ERRCODE_SYNTAX_ERROR),
597 errmsg(
"conflicting or redundant options")));
600 else if (strcmp(defel->
defname,
"rolemembers") == 0 &&
605 (
errcode(ERRCODE_SYNTAX_ERROR),
606 errmsg(
"conflicting or redundant options")));
607 drolemembers = defel;
609 else if (strcmp(defel->
defname,
"validUntil") == 0)
613 (
errcode(ERRCODE_SYNTAX_ERROR),
614 errmsg(
"conflicting or redundant options")));
617 else if (strcmp(defel->
defname,
"bypassrls") == 0)
621 (
errcode(ERRCODE_SYNTAX_ERROR),
622 errmsg(
"conflicting or redundant options")));
626 elog(
ERROR,
"option \"%s\" not recognized",
630 if (dpassword && dpassword->
arg)
643 isreplication =
intVal(disreplication->
arg);
649 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
650 errmsg(
"invalid connection limit: %d", connlimit)));
653 rolemembers = (
List *) drolemembers->
arg;
674 if (authform->rolsuper || issuper >= 0)
678 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
679 errmsg(
"must be superuser to alter superusers")));
681 else if (authform->rolreplication || isreplication >= 0)
685 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
686 errmsg(
"must be superuser to alter replication users")));
688 else if (authform->rolbypassrls || bypassrls >= 0)
692 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
693 errmsg(
"must be superuser to change bypassrls attribute")));
708 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
709 errmsg(
"permission denied")));
719 validUntil_null =
false;
733 (*check_password_hook) (rolename,
742 MemSet(new_record, 0,
sizeof(new_record));
743 MemSet(new_record_nulls,
false,
sizeof(new_record_nulls));
744 MemSet(new_record_repl,
false,
sizeof(new_record_repl));
779 if (isreplication >= 0)
794 if (!encrypt_password ||
isMD5(password))
801 elog(
ERROR,
"password encryption failed");
809 if (dpassword && dpassword->
arg ==
NULL)
827 new_record_nulls, new_record_repl);
849 else if (stmt->
action == -1)
876 "Cannot alter reserved roles.");
895 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
896 errmsg(
"must be superuser to alter superusers")));
903 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
904 errmsg(
"permission denied")));
933 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
934 errmsg(
"must be superuser to alter settings globally")));
955 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
956 errmsg(
"permission denied to drop role")));
965 foreach(item, stmt->
roles)
979 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
980 errmsg(
"cannot use special role specifier in DROP ROLE")));
989 (
errcode(ERRCODE_UNDEFINED_OBJECT),
990 errmsg(
"role \"%s\" does not exist", role)));
995 (
errmsg(
"role \"%s\" does not exist, skipping",
1006 (
errcode(ERRCODE_OBJECT_IN_USE),
1007 errmsg(
"current user cannot be dropped")));
1010 (
errcode(ERRCODE_OBJECT_IN_USE),
1011 errmsg(
"current user cannot be dropped")));
1014 (
errcode(ERRCODE_OBJECT_IN_USE),
1015 errmsg(
"session user cannot be dropped")));
1025 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1026 errmsg(
"must be superuser to drop superusers")));
1039 &detail, &detail_log))
1041 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1042 errmsg(
"role \"%s\" cannot be dropped because some objects depend on it",
1066 true,
NULL, 1, &scankey);
1081 true,
NULL, 1, &scankey);
1146 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1147 errmsg(
"role \"%s\" does not exist", oldname)));
1162 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1163 errmsg(
"session user cannot be renamed")));
1166 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1167 errmsg(
"current user cannot be renamed")));
1175 (
errcode(ERRCODE_RESERVED_NAME),
1176 errmsg(
"role name \"%s\" is reserved",
1178 errdetail(
"Role names starting with \"pg_\" are reserved.")));
1182 (
errcode(ERRCODE_RESERVED_NAME),
1183 errmsg(
"role name \"%s\" is reserved",
1185 errdetail(
"Role names starting with \"pg_\" are reserved.")));
1191 errmsg(
"role \"%s\" already exists", newname)));
1200 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1201 errmsg(
"must be superuser to rename superusers")));
1207 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1208 errmsg(
"permission denied to rename role")));
1213 repl_repl[i] =
false;
1229 (
errmsg(
"MD5 password cleared because of role rename")));
1290 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1291 errmsg(
"column names cannot be included in GRANT/REVOKE ROLE")));
1322 foreach(cell, role_ids)
1328 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1329 errmsg(
"permission denied to drop objects")));
1349 foreach(cell, role_ids)
1355 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1356 errmsg(
"permission denied to reassign objects")));
1364 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1365 errmsg(
"permission denied to reassign objects")));
1384 foreach(l, memberNames)
1409 List *memberSpecs,
List *memberIds,
1410 Oid grantorId,
bool admin_opt)
1431 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1432 errmsg(
"must be superuser to alter superusers")));
1439 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1440 errmsg(
"must have admin option on role \"%s\"",
1456 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1457 errmsg(
"must be superuser to set grantor")));
1462 forboth(specitem, memberSpecs, iditem, memberIds)
1481 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1482 (
errmsg(
"role \"%s\" is a member of role \"%s\"",
1497 (
errmsg(
"role \"%s\" is already a member of role \"%s\"",
1504 MemSet(new_record, 0,
sizeof(new_record));
1505 MemSet(new_record_nulls,
false,
sizeof(new_record_nulls));
1506 MemSet(new_record_repl,
false,
sizeof(new_record_repl));
1519 new_record_nulls, new_record_repl);
1527 new_record, new_record_nulls);
1555 List *memberSpecs,
List *memberIds,
1577 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1578 errmsg(
"must be superuser to alter superusers")));
1585 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1586 errmsg(
"must have admin option on role \"%s\"",
1593 forboth(specitem, memberSpecs, iditem, memberIds)
1608 (
errmsg(
"role \"%s\" is not a member of role \"%s\"",
1627 MemSet(new_record, 0,
sizeof(new_record));
1628 MemSet(new_record_nulls,
false,
sizeof(new_record_nulls));
1629 MemSet(new_record_repl,
false,
sizeof(new_record_repl));
1636 new_record_nulls, new_record_repl);
bool has_createrole_privilege(Oid roleid)
Value * makeString(char *str)
Oid CreateRole(CreateRoleStmt *stmt)
void shdepDropOwned(List *roleids, DropBehavior behavior)
Datum namein(PG_FUNCTION_ARGS)
#define forboth(cell1, list1, cell2, list2)
void systable_endscan(SysScanDesc sysscan)
Oid binary_upgrade_next_pg_authid_oid
#define PASSWORD_TYPE_MD5
char * get_rolespec_name(const Node *node)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Oid createdb(const CreatedbStmt *stmt)
#define RelationGetDescr(relation)
#define PointerGetDatum(X)
#define AuthMemRelationId
char * pstrdup(const char *in)
#define DatabaseRelationId
void DropOwnedObjects(DropOwnedStmt *stmt)
bool has_privs_of_role(Oid member, Oid role)
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
#define InvokeObjectDropHook(classId, objectId, subId)
bool is_admin_of_role(Oid member, Oid role)
int errcode(int sqlerrcode)
#define MemSet(start, val, len)
#define Anum_pg_authid_rolpassword
Oid get_rolespec_oid(const Node *node, bool missing_ok)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
#define Anum_pg_authid_rolreplication
#define DirectFunctionCall1(func, arg1)
void heap_freetuple(HeapTuple htup)
bool IsReservedName(const char *name)
List * lappend_oid(List *list, Oid datum)
#define OidIsValid(objectId)
Oid GetSessionUserId(void)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
void check_rolespec_name(const Node *node, const char *detail_msg)
#define SearchSysCache1(cacheId, key1)
int errdetail_internal(const char *fmt,...)
Oid get_role_oid(const char *rolname, bool missing_ok)
#define HeapTupleSetOid(tuple, oid)
#define Natts_pg_auth_members
FormData_pg_authid * Form_pg_authid
HeapTuple systable_getnext(SysScanDesc sysscan)
#define SearchSysCacheExists1(cacheId, key1)
bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf)
#define ObjectIdGetDatum(X)
void GrantRole(GrantRoleStmt *stmt)
#define Anum_pg_authid_rolvaliduntil
static void AddRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt)
void shdepLockAndCheckObject(Oid classId, Oid objectId)
void shdepReassignOwned(List *roleids, Oid newrole)
#define Anum_pg_authid_rolsuper
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
int errdetail(const char *fmt,...)
#define Anum_pg_auth_members_grantor
#define CStringGetDatum(X)
#define Anum_pg_authid_rolcanlogin
int errdetail_log(const char *fmt,...)
#define Anum_pg_authid_rolconnlimit
HeapTuple get_rolespec_tuple(const Node *node)
#define ereport(elevel, rest)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
bool superuser_arg(Oid roleid)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
#define AuthMemRoleMemIndexId
Oid AlterRole(AlterRoleStmt *stmt)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
#define Anum_pg_authid_rolbypassrls
void(* check_password_hook_type)(const char *username, const char *password, int password_type, Datum validuntil_time, bool validuntil_null)
#define TextDatumGetCString(d)
#define Anum_pg_auth_members_roleid
void CommandCounterIncrement(void)
void ReleaseSysCache(HeapTuple tuple)
Oid AlterRoleSet(AlterRoleSetStmt *stmt)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
#define list_make1_oid(x1)
Oid simple_heap_insert(Relation relation, HeapTuple tup)
Relation heap_open(Oid relationId, LOCKMODE lockmode)
FormData_pg_auth_members * Form_pg_auth_members
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
#define Anum_pg_authid_rolcreatedb
VariableSetStmt * setstmt
Oid get_database_oid(const char *dbname, bool missing_ok)
ObjectAddress RenameRole(const char *oldname, const char *newname)
List * roleSpecsToIds(List *memberNames)
#define HeapTupleIsValid(tuple)
#define Assert(condition)
void CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple)
#define AuthMemMemRoleIndexId
static int list_length(const List *l)
void simple_heap_delete(Relation relation, ItemPointer tid)
void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
#define ObjectAddressSet(addr, class_id, object_id)
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
#define Anum_pg_authid_rolname
#define AccessExclusiveLock
bool is_member_of_role_nosuper(Oid member, Oid role)
Datum timestamptz_in(PG_FUNCTION_ARGS)
int errmsg(const char *fmt,...)
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
static bool have_createrole_privilege(void)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define Anum_pg_auth_members_admin_option
#define CStringGetTextDatum(s)
void DropRole(DropRoleStmt *stmt)
#define Anum_pg_authid_rolcreaterole
bool checkSharedDependencies(Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
#define PASSWORD_TYPE_PLAINTEXT
#define HeapTupleGetOid(tuple)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
check_password_hook_type check_password_hook
void DropSetting(Oid databaseid, Oid roleid)
#define ERRCODE_DUPLICATE_OBJECT
#define Anum_pg_authid_rolinherit
#define BTEqualStrategyNumber
static void DelRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, bool admin_opt)
#define Anum_pg_auth_members_member
#define SearchSysCache2(cacheId, key1, key2)