PostgreSQL Source Code  git master
user.h File Reference
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 (AlterRoleStmt *stmt)
 
Oid AlterRoleSet (AlterRoleSetStmt *stmt)
 
void DropRole (DropRoleStmt *stmt)
 
void GrantRole (GrantRoleStmt *stmt)
 
ObjectAddress RenameRole (const char *oldname, const char *newname)
 
void DropOwnedObjects (DropOwnedStmt *stmt)
 
void ReassignOwnedObjects (ReassignOwnedStmt *stmt)
 
ListroleSpecsToIds (List *memberNames)
 

Variables

int Password_encryption
 
PGDLLIMPORT check_password_hook_type check_password_hook
 

Typedef Documentation

◆ check_password_hook_type

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

Definition at line 23 of file user.h.

Function Documentation

◆ AlterRole()

Oid AlterRole ( AlterRoleStmt stmt)

Definition at line 520 of file user.c.

References AlterRoleStmt::action, AddRoleMems(), DefElem::arg, AUTHNAME, BoolGetDatum, CatalogTupleUpdate(), check_password_hook, check_rolespec_name(), CommandCounterIncrement(), createdb(), CStringGetDatum, CStringGetTextDatum, DefElem::defname, DelRoleMems(), DirectFunctionCall3, elog, encrypt_password(), ereport, errcode(), errmsg(), ERROR, get_password_type(), get_rolespec_tuple(), GETSTRUCT, GetUserId(), have_createrole_privilege(), heap_freetuple(), heap_modify_tuple(), Int32GetDatum, intVal, InvalidOid, InvokeObjectPostAlterHook, lfirst, MemSet, NameStr, NIL, NoLock, NOTICE, ObjectIdGetDatum, AlterRoleStmt::options, password, Password_encryption, plain_crypt_verify(), pstrdup(), RelationGetDescr, ReleaseSysCache(), AlterRoleStmt::role, roleSpecsToIds(), RowExclusiveLock, STATUS_OK, strVal, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, table_close(), table_open(), and timestamptz_in().

Referenced by standard_ProcessUtility().

521 {
522  Datum new_record[Natts_pg_authid];
523  bool new_record_nulls[Natts_pg_authid];
524  bool new_record_repl[Natts_pg_authid];
525  Relation pg_authid_rel;
526  TupleDesc pg_authid_dsc;
527  HeapTuple tuple,
528  new_tuple;
529  Form_pg_authid authform;
530  ListCell *option;
531  char *rolename = NULL;
532  char *password = NULL; /* user password */
533  int issuper = -1; /* Make the user a superuser? */
534  int inherit = -1; /* Auto inherit privileges? */
535  int createrole = -1; /* Can this user create roles? */
536  int createdb = -1; /* Can the user create databases? */
537  int canlogin = -1; /* Can this user login? */
538  int isreplication = -1; /* Is this a replication role? */
539  int connlimit = -1; /* maximum connections allowed */
540  List *rolemembers = NIL; /* roles to be added/removed */
541  char *validUntil = NULL; /* time the login is valid until */
542  Datum validUntil_datum; /* same, as timestamptz Datum */
543  bool validUntil_null;
544  int bypassrls = -1;
545  DefElem *dpassword = NULL;
546  DefElem *dissuper = NULL;
547  DefElem *dinherit = NULL;
548  DefElem *dcreaterole = NULL;
549  DefElem *dcreatedb = NULL;
550  DefElem *dcanlogin = NULL;
551  DefElem *disreplication = NULL;
552  DefElem *dconnlimit = NULL;
553  DefElem *drolemembers = NULL;
554  DefElem *dvalidUntil = NULL;
555  DefElem *dbypassRLS = NULL;
556  Oid roleid;
557 
559  "Cannot alter reserved roles.");
560 
561  /* Extract options from the statement node tree */
562  foreach(option, stmt->options)
563  {
564  DefElem *defel = (DefElem *) lfirst(option);
565 
566  if (strcmp(defel->defname, "password") == 0)
567  {
568  if (dpassword)
569  ereport(ERROR,
570  (errcode(ERRCODE_SYNTAX_ERROR),
571  errmsg("conflicting or redundant options")));
572  dpassword = defel;
573  }
574  else if (strcmp(defel->defname, "superuser") == 0)
575  {
576  if (dissuper)
577  ereport(ERROR,
578  (errcode(ERRCODE_SYNTAX_ERROR),
579  errmsg("conflicting or redundant options")));
580  dissuper = defel;
581  }
582  else if (strcmp(defel->defname, "inherit") == 0)
583  {
584  if (dinherit)
585  ereport(ERROR,
586  (errcode(ERRCODE_SYNTAX_ERROR),
587  errmsg("conflicting or redundant options")));
588  dinherit = defel;
589  }
590  else if (strcmp(defel->defname, "createrole") == 0)
591  {
592  if (dcreaterole)
593  ereport(ERROR,
594  (errcode(ERRCODE_SYNTAX_ERROR),
595  errmsg("conflicting or redundant options")));
596  dcreaterole = defel;
597  }
598  else if (strcmp(defel->defname, "createdb") == 0)
599  {
600  if (dcreatedb)
601  ereport(ERROR,
602  (errcode(ERRCODE_SYNTAX_ERROR),
603  errmsg("conflicting or redundant options")));
604  dcreatedb = defel;
605  }
606  else if (strcmp(defel->defname, "canlogin") == 0)
607  {
608  if (dcanlogin)
609  ereport(ERROR,
610  (errcode(ERRCODE_SYNTAX_ERROR),
611  errmsg("conflicting or redundant options")));
612  dcanlogin = defel;
613  }
614  else if (strcmp(defel->defname, "isreplication") == 0)
615  {
616  if (disreplication)
617  ereport(ERROR,
618  (errcode(ERRCODE_SYNTAX_ERROR),
619  errmsg("conflicting or redundant options")));
620  disreplication = defel;
621  }
622  else if (strcmp(defel->defname, "connectionlimit") == 0)
623  {
624  if (dconnlimit)
625  ereport(ERROR,
626  (errcode(ERRCODE_SYNTAX_ERROR),
627  errmsg("conflicting or redundant options")));
628  dconnlimit = defel;
629  }
630  else if (strcmp(defel->defname, "rolemembers") == 0 &&
631  stmt->action != 0)
632  {
633  if (drolemembers)
634  ereport(ERROR,
635  (errcode(ERRCODE_SYNTAX_ERROR),
636  errmsg("conflicting or redundant options")));
637  drolemembers = defel;
638  }
639  else if (strcmp(defel->defname, "validUntil") == 0)
640  {
641  if (dvalidUntil)
642  ereport(ERROR,
643  (errcode(ERRCODE_SYNTAX_ERROR),
644  errmsg("conflicting or redundant options")));
645  dvalidUntil = defel;
646  }
647  else if (strcmp(defel->defname, "bypassrls") == 0)
648  {
649  if (dbypassRLS)
650  ereport(ERROR,
651  (errcode(ERRCODE_SYNTAX_ERROR),
652  errmsg("conflicting or redundant options")));
653  dbypassRLS = defel;
654  }
655  else
656  elog(ERROR, "option \"%s\" not recognized",
657  defel->defname);
658  }
659 
660  if (dpassword && dpassword->arg)
661  password = strVal(dpassword->arg);
662  if (dissuper)
663  issuper = intVal(dissuper->arg);
664  if (dinherit)
665  inherit = intVal(dinherit->arg);
666  if (dcreaterole)
667  createrole = intVal(dcreaterole->arg);
668  if (dcreatedb)
669  createdb = intVal(dcreatedb->arg);
670  if (dcanlogin)
671  canlogin = intVal(dcanlogin->arg);
672  if (disreplication)
673  isreplication = intVal(disreplication->arg);
674  if (dconnlimit)
675  {
676  connlimit = intVal(dconnlimit->arg);
677  if (connlimit < -1)
678  ereport(ERROR,
679  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
680  errmsg("invalid connection limit: %d", connlimit)));
681  }
682  if (drolemembers)
683  rolemembers = (List *) drolemembers->arg;
684  if (dvalidUntil)
685  validUntil = strVal(dvalidUntil->arg);
686  if (dbypassRLS)
687  bypassrls = intVal(dbypassRLS->arg);
688 
689  /*
690  * Scan the pg_authid relation to be certain the user exists.
691  */
692  pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock);
693  pg_authid_dsc = RelationGetDescr(pg_authid_rel);
694 
695  tuple = get_rolespec_tuple(stmt->role);
696  authform = (Form_pg_authid) GETSTRUCT(tuple);
697  rolename = pstrdup(NameStr(authform->rolname));
698  roleid = authform->oid;
699 
700  /*
701  * To mess with a superuser you gotta be superuser; else you need
702  * createrole, or just want to change your own password
703  */
704  if (authform->rolsuper || issuper >= 0)
705  {
706  if (!superuser())
707  ereport(ERROR,
708  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
709  errmsg("must be superuser to alter superusers")));
710  }
711  else if (authform->rolreplication || isreplication >= 0)
712  {
713  if (!superuser())
714  ereport(ERROR,
715  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
716  errmsg("must be superuser to alter replication users")));
717  }
718  else if (authform->rolbypassrls || bypassrls >= 0)
719  {
720  if (!superuser())
721  ereport(ERROR,
722  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
723  errmsg("must be superuser to change bypassrls attribute")));
724  }
725  else if (!have_createrole_privilege())
726  {
727  if (!(inherit < 0 &&
728  createrole < 0 &&
729  createdb < 0 &&
730  canlogin < 0 &&
731  isreplication < 0 &&
732  !dconnlimit &&
733  !rolemembers &&
734  !validUntil &&
735  dpassword &&
736  roleid == GetUserId()))
737  ereport(ERROR,
738  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
739  errmsg("permission denied")));
740  }
741 
742  /* Convert validuntil to internal form */
743  if (validUntil)
744  {
745  validUntil_datum = DirectFunctionCall3(timestamptz_in,
746  CStringGetDatum(validUntil),
748  Int32GetDatum(-1));
749  validUntil_null = false;
750  }
751  else
752  {
753  /* fetch existing setting in case hook needs it */
754  validUntil_datum = SysCacheGetAttr(AUTHNAME, tuple,
755  Anum_pg_authid_rolvaliduntil,
756  &validUntil_null);
757  }
758 
759  /*
760  * Call the password checking hook if there is one defined
761  */
762  if (check_password_hook && password)
763  (*check_password_hook) (rolename,
764  password,
765  get_password_type(password),
766  validUntil_datum,
767  validUntil_null);
768 
769  /*
770  * Build an updated tuple, perusing the information just obtained
771  */
772  MemSet(new_record, 0, sizeof(new_record));
773  MemSet(new_record_nulls, false, sizeof(new_record_nulls));
774  MemSet(new_record_repl, false, sizeof(new_record_repl));
775 
776  /*
777  * issuper/createrole/etc
778  */
779  if (issuper >= 0)
780  {
781  new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
782  new_record_repl[Anum_pg_authid_rolsuper - 1] = true;
783  }
784 
785  if (inherit >= 0)
786  {
787  new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit > 0);
788  new_record_repl[Anum_pg_authid_rolinherit - 1] = true;
789  }
790 
791  if (createrole >= 0)
792  {
793  new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);
794  new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
795  }
796 
797  if (createdb >= 0)
798  {
799  new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0);
800  new_record_repl[Anum_pg_authid_rolcreatedb - 1] = true;
801  }
802 
803  if (canlogin >= 0)
804  {
805  new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0);
806  new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true;
807  }
808 
809  if (isreplication >= 0)
810  {
811  new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication > 0);
812  new_record_repl[Anum_pg_authid_rolreplication - 1] = true;
813  }
814 
815  if (dconnlimit)
816  {
817  new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
818  new_record_repl[Anum_pg_authid_rolconnlimit - 1] = true;
819  }
820 
821  /* password */
822  if (password)
823  {
824  char *shadow_pass;
825  char *logdetail;
826 
827  /* Like in CREATE USER, don't allow an empty password. */
828  if (password[0] == '\0' ||
829  plain_crypt_verify(rolename, password, "", &logdetail) == STATUS_OK)
830  {
831  ereport(NOTICE,
832  (errmsg("empty string is not a valid password, clearing password")));
833  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
834  }
835  else
836  {
837  /* Encrypt the password to the requested format. */
838  shadow_pass = encrypt_password(Password_encryption, rolename,
839  password);
840  new_record[Anum_pg_authid_rolpassword - 1] =
841  CStringGetTextDatum(shadow_pass);
842  }
843  new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
844  }
845 
846  /* unset password */
847  if (dpassword && dpassword->arg == NULL)
848  {
849  new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
850  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
851  }
852 
853  /* valid until */
854  new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
855  new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
856  new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = true;
857 
858  if (bypassrls >= 0)
859  {
860  new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls > 0);
861  new_record_repl[Anum_pg_authid_rolbypassrls - 1] = true;
862  }
863 
864  new_tuple = heap_modify_tuple(tuple, pg_authid_dsc, new_record,
865  new_record_nulls, new_record_repl);
866  CatalogTupleUpdate(pg_authid_rel, &tuple->t_self, new_tuple);
867 
868  InvokeObjectPostAlterHook(AuthIdRelationId, roleid, 0);
869 
870  ReleaseSysCache(tuple);
871  heap_freetuple(new_tuple);
872 
873  /*
874  * Advance command counter so we can see new record; else tests in
875  * AddRoleMems may fail.
876  */
877  if (rolemembers)
879 
880  if (stmt->action == +1) /* add members to role */
881  AddRoleMems(rolename, roleid,
882  rolemembers, roleSpecsToIds(rolemembers),
883  GetUserId(), false);
884  else if (stmt->action == -1) /* drop members from role */
885  DelRoleMems(rolename, roleid,
886  rolemembers, roleSpecsToIds(rolemembers),
887  false);
888 
889  /*
890  * Close pg_authid, but keep lock till commit.
891  */
892  table_close(pg_authid_rel, NoLock);
893 
894  return roleid;
895 }
#define NIL
Definition: pg_list.h:65
static char password[100]
Definition: streamutil.c:55
RoleSpec * role
Definition: parsenodes.h:2494
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:445
Oid GetUserId(void)
Definition: miscinit.c:380
int Password_encryption
Definition: user.c:46
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * encrypt_password(PasswordType target_type, const char *role, const char *password)
Definition: crypt.c:114
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, char **logdetail)
Definition: crypt.c:222
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
static void AddRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt)
Definition: user.c:1452
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
#define STATUS_OK
Definition: c.h:1089
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:621
Node * arg
Definition: parsenodes.h:731
uintptr_t Datum
Definition: postgres.h:367
void CommandCounterIncrement(void)
Definition: xact.c:1003
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition: acl.c:5330
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
#define BoolGetDatum(X)
Definition: postgres.h:402
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1423
#define lfirst(lc)
Definition: pg_list.h:190
List * options
Definition: parsenodes.h:2495
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5263
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define Int32GetDatum(X)
Definition: postgres.h:479
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition: timestamp.c:400
#define intVal(v)
Definition: value.h:52
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition: dbcommands.c:101
int errmsg(const char *fmt,...)
Definition: elog.c:784
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:89
#define elog(elevel,...)
Definition: elog.h:226
static bool have_createrole_privilege(void)
Definition: user.c:61
#define NameStr(name)
Definition: c.h:609
#define CStringGetTextDatum(s)
Definition: builtins.h:83
char * defname
Definition: parsenodes.h:730
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
check_password_hook_type check_password_hook
Definition: user.c:49
Definition: pg_list.h:50
static void DelRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, bool admin_opt)
Definition: user.c:1596

◆ AlterRoleSet()

Oid AlterRoleSet ( AlterRoleSetStmt stmt)

Definition at line 902 of file user.c.

References aclcheck_error(), ACLCHECK_NOT_OWNER, AlterSetting(), check_rolespec_name(), AlterRoleSetStmt::database, ereport, errcode(), errmsg(), ERROR, get_database_oid(), get_rolespec_tuple(), GETSTRUCT, GetUserId(), have_createrole_privilege(), InvalidOid, OBJECT_DATABASE, pg_database_ownercheck(), ReleaseSysCache(), AlterRoleSetStmt::role, AlterRoleSetStmt::setstmt, shdepLockAndCheckObject(), and superuser().

Referenced by standard_ProcessUtility().

903 {
904  HeapTuple roletuple;
905  Form_pg_authid roleform;
906  Oid databaseid = InvalidOid;
907  Oid roleid = InvalidOid;
908 
909  if (stmt->role)
910  {
912  "Cannot alter reserved roles.");
913 
914  roletuple = get_rolespec_tuple(stmt->role);
915  roleform = (Form_pg_authid) GETSTRUCT(roletuple);
916  roleid = roleform->oid;
917 
918  /*
919  * Obtain a lock on the role and make sure it didn't go away in the
920  * meantime.
921  */
922  shdepLockAndCheckObject(AuthIdRelationId, roleid);
923 
924  /*
925  * To mess with a superuser you gotta be superuser; else you need
926  * createrole, or just want to change your own settings
927  */
928  if (roleform->rolsuper)
929  {
930  if (!superuser())
931  ereport(ERROR,
932  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
933  errmsg("must be superuser to alter superusers")));
934  }
935  else
936  {
937  if (!have_createrole_privilege() && roleid != GetUserId())
938  ereport(ERROR,
939  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
940  errmsg("permission denied")));
941  }
942 
943  ReleaseSysCache(roletuple);
944  }
945 
946  /* look up and lock the database, if specified */
947  if (stmt->database != NULL)
948  {
949  databaseid = get_database_oid(stmt->database, false);
950  shdepLockAndCheckObject(DatabaseRelationId, databaseid);
951 
952  if (!stmt->role)
953  {
954  /*
955  * If no role is specified, then this is effectively the same as
956  * ALTER DATABASE ... SET, so use the same permission check.
957  */
958  if (!pg_database_ownercheck(databaseid, GetUserId()))
960  stmt->database);
961  }
962  }
963 
964  if (!stmt->role && !stmt->database)
965  {
966  /* Must be superuser to alter settings globally. */
967  if (!superuser())
968  ereport(ERROR,
969  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
970  errmsg("must be superuser to alter settings globally")));
971  }
972 
973  AlterSetting(databaseid, roleid, stmt->setstmt);
974 
975  return roleid;
976 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid GetUserId(void)
Definition: miscinit.c:380
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
RoleSpec * role
Definition: parsenodes.h:2502
unsigned int Oid
Definition: postgres_ext.h:31
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define ERROR
Definition: elog.h:43
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:1072
#define ereport(elevel, rest)
Definition: elog.h:141
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:5173
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition: acl.c:5330
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
VariableSetStmt * setstmt
Definition: parsenodes.h:2504
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2053
#define InvalidOid
Definition: postgres_ext.h:36
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5263
int errmsg(const char *fmt,...)
Definition: elog.c:784
static bool have_createrole_privilege(void)
Definition: user.c:61

◆ CreateRole()

Oid CreateRole ( ParseState pstate,
CreateRoleStmt stmt 
)

Definition at line 71 of file user.c.

References AddRoleMems(), DefElem::arg, AuthIdOidIndexId, binary_upgrade_next_pg_authid_oid, BoolGetDatum, CatalogTupleInsert(), check_password_hook, CommandCounterIncrement(), createdb(), CStringGetDatum, CStringGetTextDatum, DefElem::defname, DirectFunctionCall1, DirectFunctionCall3, elog, encrypt_password(), ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errmsg(), ERROR, get_password_type(), get_role_oid(), get_rolespec_tuple(), GetNewOidWithIndex(), GETSTRUCT, GetUserId(), have_createrole_privilege(), heap_form_tuple(), Int32GetDatum, intVal, InvalidOid, InvokeObjectPostCreateHook, IsBinaryUpgrade, IsReservedName(), lfirst, list_make1, list_make1_oid, DefElem::location, makeString(), MemSet, namein(), NameStr, NIL, NoLock, NOTICE, ObjectIdGetDatum, OidIsValid, CreateRoleStmt::options, parser_errposition(), password, Password_encryption, plain_crypt_verify(), RelationGetDescr, ReleaseSysCache(), CreateRoleStmt::role, roleSpecsToIds(), ROLESTMT_GROUP, ROLESTMT_ROLE, ROLESTMT_USER, RowExclusiveLock, STATUS_OK, CreateRoleStmt::stmt_type, strVal, superuser(), table_close(), table_open(), timestamptz_in(), and WARNING.

Referenced by standard_ProcessUtility().

72 {
73  Relation pg_authid_rel;
74  TupleDesc pg_authid_dsc;
75  HeapTuple tuple;
76  Datum new_record[Natts_pg_authid];
77  bool new_record_nulls[Natts_pg_authid];
78  Oid roleid;
79  ListCell *item;
81  char *password = NULL; /* user password */
82  bool issuper = false; /* Make the user a superuser? */
83  bool inherit = true; /* Auto inherit privileges? */
84  bool createrole = false; /* Can this user create roles? */
85  bool createdb = false; /* Can the user create databases? */
86  bool canlogin = false; /* Can this user login? */
87  bool isreplication = false; /* Is this a replication role? */
88  bool bypassrls = false; /* Is this a row security enabled role? */
89  int connlimit = -1; /* maximum connections allowed */
90  List *addroleto = NIL; /* roles to make this a member of */
91  List *rolemembers = NIL; /* roles to be members of this role */
92  List *adminmembers = NIL; /* roles to be admins of this role */
93  char *validUntil = NULL; /* time the login is valid until */
94  Datum validUntil_datum; /* same, as timestamptz Datum */
95  bool validUntil_null;
96  DefElem *dpassword = NULL;
97  DefElem *dissuper = NULL;
98  DefElem *dinherit = NULL;
99  DefElem *dcreaterole = NULL;
100  DefElem *dcreatedb = NULL;
101  DefElem *dcanlogin = NULL;
102  DefElem *disreplication = NULL;
103  DefElem *dconnlimit = NULL;
104  DefElem *daddroleto = NULL;
105  DefElem *drolemembers = NULL;
106  DefElem *dadminmembers = NULL;
107  DefElem *dvalidUntil = NULL;
108  DefElem *dbypassRLS = NULL;
109 
110  /* The defaults can vary depending on the original statement type */
111  switch (stmt->stmt_type)
112  {
113  case ROLESTMT_ROLE:
114  break;
115  case ROLESTMT_USER:
116  canlogin = true;
117  /* may eventually want inherit to default to false here */
118  break;
119  case ROLESTMT_GROUP:
120  break;
121  }
122 
123  /* Extract options from the statement node tree */
124  foreach(option, stmt->options)
125  {
126  DefElem *defel = (DefElem *) lfirst(option);
127 
128  if (strcmp(defel->defname, "password") == 0)
129  {
130  if (dpassword)
131  ereport(ERROR,
132  (errcode(ERRCODE_SYNTAX_ERROR),
133  errmsg("conflicting or redundant options"),
134  parser_errposition(pstate, defel->location)));
135  dpassword = defel;
136  }
137  else if (strcmp(defel->defname, "sysid") == 0)
138  {
139  ereport(NOTICE,
140  (errmsg("SYSID can no longer be specified")));
141  }
142  else if (strcmp(defel->defname, "superuser") == 0)
143  {
144  if (dissuper)
145  ereport(ERROR,
146  (errcode(ERRCODE_SYNTAX_ERROR),
147  errmsg("conflicting or redundant options"),
148  parser_errposition(pstate, defel->location)));
149  dissuper = defel;
150  }
151  else if (strcmp(defel->defname, "inherit") == 0)
152  {
153  if (dinherit)
154  ereport(ERROR,
155  (errcode(ERRCODE_SYNTAX_ERROR),
156  errmsg("conflicting or redundant options"),
157  parser_errposition(pstate, defel->location)));
158  dinherit = defel;
159  }
160  else if (strcmp(defel->defname, "createrole") == 0)
161  {
162  if (dcreaterole)
163  ereport(ERROR,
164  (errcode(ERRCODE_SYNTAX_ERROR),
165  errmsg("conflicting or redundant options"),
166  parser_errposition(pstate, defel->location)));
167  dcreaterole = defel;
168  }
169  else if (strcmp(defel->defname, "createdb") == 0)
170  {
171  if (dcreatedb)
172  ereport(ERROR,
173  (errcode(ERRCODE_SYNTAX_ERROR),
174  errmsg("conflicting or redundant options"),
175  parser_errposition(pstate, defel->location)));
176  dcreatedb = defel;
177  }
178  else if (strcmp(defel->defname, "canlogin") == 0)
179  {
180  if (dcanlogin)
181  ereport(ERROR,
182  (errcode(ERRCODE_SYNTAX_ERROR),
183  errmsg("conflicting or redundant options"),
184  parser_errposition(pstate, defel->location)));
185  dcanlogin = defel;
186  }
187  else if (strcmp(defel->defname, "isreplication") == 0)
188  {
189  if (disreplication)
190  ereport(ERROR,
191  (errcode(ERRCODE_SYNTAX_ERROR),
192  errmsg("conflicting or redundant options"),
193  parser_errposition(pstate, defel->location)));
194  disreplication = defel;
195  }
196  else if (strcmp(defel->defname, "connectionlimit") == 0)
197  {
198  if (dconnlimit)
199  ereport(ERROR,
200  (errcode(ERRCODE_SYNTAX_ERROR),
201  errmsg("conflicting or redundant options"),
202  parser_errposition(pstate, defel->location)));
203  dconnlimit = defel;
204  }
205  else if (strcmp(defel->defname, "addroleto") == 0)
206  {
207  if (daddroleto)
208  ereport(ERROR,
209  (errcode(ERRCODE_SYNTAX_ERROR),
210  errmsg("conflicting or redundant options"),
211  parser_errposition(pstate, defel->location)));
212  daddroleto = defel;
213  }
214  else if (strcmp(defel->defname, "rolemembers") == 0)
215  {
216  if (drolemembers)
217  ereport(ERROR,
218  (errcode(ERRCODE_SYNTAX_ERROR),
219  errmsg("conflicting or redundant options"),
220  parser_errposition(pstate, defel->location)));
221  drolemembers = defel;
222  }
223  else if (strcmp(defel->defname, "adminmembers") == 0)
224  {
225  if (dadminmembers)
226  ereport(ERROR,
227  (errcode(ERRCODE_SYNTAX_ERROR),
228  errmsg("conflicting or redundant options"),
229  parser_errposition(pstate, defel->location)));
230  dadminmembers = defel;
231  }
232  else if (strcmp(defel->defname, "validUntil") == 0)
233  {
234  if (dvalidUntil)
235  ereport(ERROR,
236  (errcode(ERRCODE_SYNTAX_ERROR),
237  errmsg("conflicting or redundant options"),
238  parser_errposition(pstate, defel->location)));
239  dvalidUntil = defel;
240  }
241  else if (strcmp(defel->defname, "bypassrls") == 0)
242  {
243  if (dbypassRLS)
244  ereport(ERROR,
245  (errcode(ERRCODE_SYNTAX_ERROR),
246  errmsg("conflicting or redundant options"),
247  parser_errposition(pstate, defel->location)));
248  dbypassRLS = defel;
249  }
250  else
251  elog(ERROR, "option \"%s\" not recognized",
252  defel->defname);
253  }
254 
255  if (dpassword && dpassword->arg)
256  password = strVal(dpassword->arg);
257  if (dissuper)
258  issuper = intVal(dissuper->arg) != 0;
259  if (dinherit)
260  inherit = intVal(dinherit->arg) != 0;
261  if (dcreaterole)
262  createrole = intVal(dcreaterole->arg) != 0;
263  if (dcreatedb)
264  createdb = intVal(dcreatedb->arg) != 0;
265  if (dcanlogin)
266  canlogin = intVal(dcanlogin->arg) != 0;
267  if (disreplication)
268  isreplication = intVal(disreplication->arg) != 0;
269  if (dconnlimit)
270  {
271  connlimit = intVal(dconnlimit->arg);
272  if (connlimit < -1)
273  ereport(ERROR,
274  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
275  errmsg("invalid connection limit: %d", connlimit)));
276  }
277  if (daddroleto)
278  addroleto = (List *) daddroleto->arg;
279  if (drolemembers)
280  rolemembers = (List *) drolemembers->arg;
281  if (dadminmembers)
282  adminmembers = (List *) dadminmembers->arg;
283  if (dvalidUntil)
284  validUntil = strVal(dvalidUntil->arg);
285  if (dbypassRLS)
286  bypassrls = intVal(dbypassRLS->arg) != 0;
287 
288  /* Check some permissions first */
289  if (issuper)
290  {
291  if (!superuser())
292  ereport(ERROR,
293  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
294  errmsg("must be superuser to create superusers")));
295  }
296  else if (isreplication)
297  {
298  if (!superuser())
299  ereport(ERROR,
300  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
301  errmsg("must be superuser to create replication users")));
302  }
303  else if (bypassrls)
304  {
305  if (!superuser())
306  ereport(ERROR,
307  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
308  errmsg("must be superuser to change bypassrls attribute")));
309  }
310  else
311  {
313  ereport(ERROR,
314  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
315  errmsg("permission denied to create role")));
316  }
317 
318  /*
319  * Check that the user is not trying to create a role in the reserved
320  * "pg_" namespace.
321  */
322  if (IsReservedName(stmt->role))
323  ereport(ERROR,
324  (errcode(ERRCODE_RESERVED_NAME),
325  errmsg("role name \"%s\" is reserved",
326  stmt->role),
327  errdetail("Role names starting with \"pg_\" are reserved.")));
328 
329  /*
330  * If built with appropriate switch, whine when regression-testing
331  * conventions for role names are violated.
332  */
333 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
334  if (strncmp(stmt->role, "regress_", 8) != 0)
335  elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
336 #endif
337 
338  /*
339  * Check the pg_authid relation to be certain the role doesn't already
340  * exist.
341  */
342  pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock);
343  pg_authid_dsc = RelationGetDescr(pg_authid_rel);
344 
345  if (OidIsValid(get_role_oid(stmt->role, true)))
346  ereport(ERROR,
348  errmsg("role \"%s\" already exists",
349  stmt->role)));
350 
351  /* Convert validuntil to internal form */
352  if (validUntil)
353  {
354  validUntil_datum = DirectFunctionCall3(timestamptz_in,
355  CStringGetDatum(validUntil),
357  Int32GetDatum(-1));
358  validUntil_null = false;
359  }
360  else
361  {
362  validUntil_datum = (Datum) 0;
363  validUntil_null = true;
364  }
365 
366  /*
367  * Call the password checking hook if there is one defined
368  */
369  if (check_password_hook && password)
370  (*check_password_hook) (stmt->role,
371  password,
372  get_password_type(password),
373  validUntil_datum,
374  validUntil_null);
375 
376  /*
377  * Build a tuple to insert
378  */
379  MemSet(new_record, 0, sizeof(new_record));
380  MemSet(new_record_nulls, false, sizeof(new_record_nulls));
381 
382  new_record[Anum_pg_authid_rolname - 1] =
384 
385  new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);
386  new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
387  new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
388  new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
389  new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
390  new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication);
391  new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
392 
393  if (password)
394  {
395  char *shadow_pass;
396  char *logdetail;
397 
398  /*
399  * Don't allow an empty password. Libpq treats an empty password the
400  * same as no password at all, and won't even try to authenticate. But
401  * other clients might, so allowing it would be confusing. By clearing
402  * the password when an empty string is specified, the account is
403  * consistently locked for all clients.
404  *
405  * Note that this only covers passwords stored in the database itself.
406  * There are also checks in the authentication code, to forbid an
407  * empty password from being used with authentication methods that
408  * fetch the password from an external system, like LDAP or PAM.
409  */
410  if (password[0] == '\0' ||
411  plain_crypt_verify(stmt->role, password, "", &logdetail) == STATUS_OK)
412  {
413  ereport(NOTICE,
414  (errmsg("empty string is not a valid password, clearing password")));
415  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
416  }
417  else
418  {
419  /* Encrypt the password to the requested format. */
420  shadow_pass = encrypt_password(Password_encryption, stmt->role,
421  password);
422  new_record[Anum_pg_authid_rolpassword - 1] =
423  CStringGetTextDatum(shadow_pass);
424  }
425  }
426  else
427  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
428 
429  new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
430  new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
431 
432  new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls);
433 
434  /*
435  * pg_largeobject_metadata contains pg_authid.oid's, so we use the
436  * binary-upgrade override.
437  */
438  if (IsBinaryUpgrade)
439  {
441  ereport(ERROR,
442  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
443  errmsg("pg_authid OID value not set when in binary upgrade mode")));
444 
447  }
448  else
449  {
450  roleid = GetNewOidWithIndex(pg_authid_rel, AuthIdOidIndexId,
451  Anum_pg_authid_oid);
452  }
453 
454  new_record[Anum_pg_authid_oid - 1] = ObjectIdGetDatum(roleid);
455 
456  tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls);
457 
458  /*
459  * Insert new record in the pg_authid table
460  */
461  CatalogTupleInsert(pg_authid_rel, tuple);
462 
463  /*
464  * Advance command counter so we can see new record; else tests in
465  * AddRoleMems may fail.
466  */
467  if (addroleto || adminmembers || rolemembers)
469 
470  /*
471  * Add the new role to the specified existing roles.
472  */
473  foreach(item, addroleto)
474  {
475  RoleSpec *oldrole = lfirst(item);
476  HeapTuple oldroletup = get_rolespec_tuple(oldrole);
477  Form_pg_authid oldroleform = (Form_pg_authid) GETSTRUCT(oldroletup);
478  Oid oldroleid = oldroleform->oid;
479  char *oldrolename = NameStr(oldroleform->rolname);
480 
481  AddRoleMems(oldrolename, oldroleid,
482  list_make1(makeString(stmt->role)),
483  list_make1_oid(roleid),
484  GetUserId(), false);
485 
486  ReleaseSysCache(oldroletup);
487  }
488 
489  /*
490  * Add the specified members to this new role. adminmembers get the admin
491  * option, rolemembers don't.
492  */
493  AddRoleMems(stmt->role, roleid,
494  adminmembers, roleSpecsToIds(adminmembers),
495  GetUserId(), true);
496  AddRoleMems(stmt->role, roleid,
497  rolemembers, roleSpecsToIds(rolemembers),
498  GetUserId(), false);
499 
500  /* Post creation hook for new role */
501  InvokeObjectPostCreateHook(AuthIdRelationId, roleid, 0);
502 
503  /*
504  * Close pg_authid, but keep lock till commit.
505  */
506  table_close(pg_authid_rel, NoLock);
507 
508  return roleid;
509 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
static char password[100]
Definition: streamutil.c:55
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:323
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid binary_upgrade_next_pg_authid_oid
Definition: user.c:42
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:145
#define RelationGetDescr(relation)
Definition: rel.h:445
Oid GetUserId(void)
Definition: miscinit.c:380
int Password_encryption
Definition: user.c:46
RoleStmtType stmt_type
Definition: parsenodes.h:2486
char * encrypt_password(PasswordType target_type, const char *role, const char *password)
Definition: crypt.c:114
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, char **logdetail)
Definition: crypt.c:222
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define MemSet(start, val, len)
Definition: c.h:955
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define AuthIdOidIndexId
Definition: indexing.h:101
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:214
#define OidIsValid(objectId)
Definition: c.h:638
bool IsBinaryUpgrade
Definition: globals.c:110
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5191
#define list_make1(x1)
Definition: pg_list.h:227
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
static void AddRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt)
Definition: user.c:1452
#define NoLock
Definition: lockdefs.h:34
int location
Definition: parsenodes.h:733
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
#define STATUS_OK
Definition: c.h:1089
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:621
Node * arg
Definition: parsenodes.h:731
#define WARNING
Definition: elog.h:40
uintptr_t Datum
Definition: postgres.h:367
void CommandCounterIncrement(void)
Definition: xact.c:1003
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define list_make1_oid(x1)
Definition: pg_list.h:249
#define BoolGetDatum(X)
Definition: postgres.h:402
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1423
#define lfirst(lc)
Definition: pg_list.h:190
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5263
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define Int32GetDatum(X)
Definition: postgres.h:479
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition: timestamp.c:400
#define intVal(v)
Definition: value.h:52
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition: dbcommands.c:101
int errmsg(const char *fmt,...)
Definition: elog.c:784
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:89
#define elog(elevel,...)
Definition: elog.h:226
static bool have_createrole_privilege(void)
Definition: user.c:61
#define NameStr(name)
Definition: c.h:609
#define CStringGetTextDatum(s)
Definition: builtins.h:83
char * defname
Definition: parsenodes.h:730
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
check_password_hook_type check_password_hook
Definition: user.c:49
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:33
Definition: pg_list.h:50
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:183

◆ DropOwnedObjects()

void DropOwnedObjects ( DropOwnedStmt stmt)

Definition at line 1360 of file user.c.

References DropOwnedStmt::behavior, ereport, errcode(), errmsg(), ERROR, GetUserId(), has_privs_of_role(), lfirst_oid, DropOwnedStmt::roles, roleSpecsToIds(), and shdepDropOwned().

Referenced by ProcessUtilitySlow().

1361 {
1362  List *role_ids = roleSpecsToIds(stmt->roles);
1363  ListCell *cell;
1364 
1365  /* Check privileges */
1366  foreach(cell, role_ids)
1367  {
1368  Oid roleid = lfirst_oid(cell);
1369 
1370  if (!has_privs_of_role(GetUserId(), roleid))
1371  ereport(ERROR,
1372  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1373  errmsg("permission denied to drop objects")));
1374  }
1375 
1376  /* Ok, do it */
1377  shdepDropOwned(role_ids, stmt->behavior);
1378 }
void shdepDropOwned(List *roleids, DropBehavior behavior)
Definition: pg_shdepend.c:1248
Oid GetUserId(void)
Definition: miscinit.c:380
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
DropBehavior behavior
Definition: parsenodes.h:3424
#define ereport(elevel, rest)
Definition: elog.h:141
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1423
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ DropRole()

void DropRole ( DropRoleStmt stmt)

Definition at line 983 of file user.c.

References AccessExclusiveLock, AuthMemMemRoleIndexId, AuthMemRoleMemIndexId, AUTHNAME, BTEqualStrategyNumber, CatalogTupleDelete(), checkSharedDependencies(), CommandCounterIncrement(), DeleteSharedComments(), DeleteSharedSecurityLabel(), DropSetting(), ereport, errcode(), errdetail_internal(), errdetail_log(), errmsg(), ERROR, GetOuterUserId(), GetSessionUserId(), GETSTRUCT, GetUserId(), have_createrole_privilege(), HeapTupleIsValid, InvalidOid, InvokeObjectDropHook, lfirst, LockSharedObject(), DropRoleStmt::missing_ok, NoLock, NOTICE, ObjectIdGetDatum, PointerGetDatum, ReleaseSysCache(), RoleSpec::rolename, DropRoleStmt::roles, ROLESPEC_CSTRING, RoleSpec::roletype, RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), superuser(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by standard_ProcessUtility().

984 {
985  Relation pg_authid_rel,
986  pg_auth_members_rel;
987  ListCell *item;
988 
990  ereport(ERROR,
991  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
992  errmsg("permission denied to drop role")));
993 
994  /*
995  * Scan the pg_authid relation to find the Oid of the role(s) to be
996  * deleted.
997  */
998  pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock);
999  pg_auth_members_rel = table_open(AuthMemRelationId, RowExclusiveLock);
1000 
1001  foreach(item, stmt->roles)
1002  {
1003  RoleSpec *rolspec = lfirst(item);
1004  char *role;
1005  HeapTuple tuple,
1006  tmp_tuple;
1007  Form_pg_authid roleform;
1008  ScanKeyData scankey;
1009  char *detail;
1010  char *detail_log;
1011  SysScanDesc sscan;
1012  Oid roleid;
1013 
1014  if (rolspec->roletype != ROLESPEC_CSTRING)
1015  ereport(ERROR,
1016  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1017  errmsg("cannot use special role specifier in DROP ROLE")));
1018  role = rolspec->rolename;
1019 
1020  tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role));
1021  if (!HeapTupleIsValid(tuple))
1022  {
1023  if (!stmt->missing_ok)
1024  {
1025  ereport(ERROR,
1026  (errcode(ERRCODE_UNDEFINED_OBJECT),
1027  errmsg("role \"%s\" does not exist", role)));
1028  }
1029  else
1030  {
1031  ereport(NOTICE,
1032  (errmsg("role \"%s\" does not exist, skipping",
1033  role)));
1034  }
1035 
1036  continue;
1037  }
1038 
1039  roleform = (Form_pg_authid) GETSTRUCT(tuple);
1040  roleid = roleform->oid;
1041 
1042  if (roleid == GetUserId())
1043  ereport(ERROR,
1044  (errcode(ERRCODE_OBJECT_IN_USE),
1045  errmsg("current user cannot be dropped")));
1046  if (roleid == GetOuterUserId())
1047  ereport(ERROR,
1048  (errcode(ERRCODE_OBJECT_IN_USE),
1049  errmsg("current user cannot be dropped")));
1050  if (roleid == GetSessionUserId())
1051  ereport(ERROR,
1052  (errcode(ERRCODE_OBJECT_IN_USE),
1053  errmsg("session user cannot be dropped")));
1054 
1055  /*
1056  * For safety's sake, we allow createrole holders to drop ordinary
1057  * roles but not superuser roles. This is mainly to avoid the
1058  * scenario where you accidentally drop the last superuser.
1059  */
1060  if (roleform->rolsuper && !superuser())
1061  ereport(ERROR,
1062  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1063  errmsg("must be superuser to drop superusers")));
1064 
1065  /* DROP hook for the role being removed */
1066  InvokeObjectDropHook(AuthIdRelationId, roleid, 0);
1067 
1068  /*
1069  * Lock the role, so nobody can add dependencies to her while we drop
1070  * her. We keep the lock until the end of transaction.
1071  */
1072  LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);
1073 
1074  /* Check for pg_shdepend entries depending on this role */
1075  if (checkSharedDependencies(AuthIdRelationId, roleid,
1076  &detail, &detail_log))
1077  ereport(ERROR,
1078  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1079  errmsg("role \"%s\" cannot be dropped because some objects depend on it",
1080  role),
1081  errdetail_internal("%s", detail),
1082  errdetail_log("%s", detail_log)));
1083 
1084  /*
1085  * Remove the role from the pg_authid table
1086  */
1087  CatalogTupleDelete(pg_authid_rel, &tuple->t_self);
1088 
1089  ReleaseSysCache(tuple);
1090 
1091  /*
1092  * Remove role from the pg_auth_members table. We have to remove all
1093  * tuples that show it as either a role or a member.
1094  *
1095  * XXX what about grantor entries? Maybe we should do one heap scan.
1096  */
1097  ScanKeyInit(&scankey,
1098  Anum_pg_auth_members_roleid,
1099  BTEqualStrategyNumber, F_OIDEQ,
1100  ObjectIdGetDatum(roleid));
1101 
1102  sscan = systable_beginscan(pg_auth_members_rel, AuthMemRoleMemIndexId,
1103  true, NULL, 1, &scankey);
1104 
1105  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1106  {
1107  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1108  }
1109 
1110  systable_endscan(sscan);
1111 
1112  ScanKeyInit(&scankey,
1113  Anum_pg_auth_members_member,
1114  BTEqualStrategyNumber, F_OIDEQ,
1115  ObjectIdGetDatum(roleid));
1116 
1117  sscan = systable_beginscan(pg_auth_members_rel, AuthMemMemRoleIndexId,
1118  true, NULL, 1, &scankey);
1119 
1120  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1121  {
1122  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1123  }
1124 
1125  systable_endscan(sscan);
1126 
1127  /*
1128  * Remove any comments or security labels on this role.
1129  */
1130  DeleteSharedComments(roleid, AuthIdRelationId);
1131  DeleteSharedSecurityLabel(roleid, AuthIdRelationId);
1132 
1133  /*
1134  * Remove settings for this role.
1135  */
1136  DropSetting(InvalidOid, roleid);
1137 
1138  /*
1139  * Advance command counter so that later iterations of this loop will
1140  * see the changes already made. This is essential if, for example,
1141  * we are trying to drop both a role and one of its direct members ---
1142  * we'll get an error if we try to delete the linking pg_auth_members
1143  * tuple twice. (We do not need a CCI between the two delete loops
1144  * above, because it's not allowed for a role to directly contain
1145  * itself.)
1146  */
1148  }
1149 
1150  /*
1151  * Now we can clean up; but keep locks until commit.
1152  */
1153  table_close(pg_auth_members_rel, NoLock);
1154  table_close(pg_authid_rel, NoLock);
1155 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
Oid GetUserId(void)
Definition: miscinit.c:380
#define PointerGetDatum(X)
Definition: postgres.h:556
#define InvokeObjectDropHook(classId, objectId, subId)
Definition: objectaccess.h:154
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
List * roles
Definition: parsenodes.h:2510
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:414
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
int errdetail_internal(const char *fmt,...)
Definition: elog.c:887
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
Oid GetOuterUserId(void)
Definition: miscinit.c:391
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail_log(const char *fmt,...)
Definition: elog.c:908
#define ereport(elevel, rest)
Definition: elog.h:141
#define AuthMemRoleMemIndexId
Definition: indexing.h:104
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void CommandCounterIncrement(void)
Definition: xact.c:1003
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
RoleSpecType roletype
Definition: parsenodes.h:328
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1002
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
void DeleteSharedComments(Oid oid, Oid classoid)
Definition: comment.c:373
#define AuthMemMemRoleIndexId
Definition: indexing.h:106
char * rolename
Definition: parsenodes.h:329
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition: seclabel.c:414
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:784
static bool have_createrole_privilege(void)
Definition: user.c:61
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
bool checkSharedDependencies(Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
Definition: pg_shdepend.c:578
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void DropSetting(Oid databaseid, Oid roleid)
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ GrantRole()

void GrantRole ( GrantRoleStmt stmt)

Definition at line 1301 of file user.c.

References AccessShareLock, AddRoleMems(), GrantRoleStmt::admin_opt, AccessPriv::cols, DelRoleMems(), ereport, errcode(), errmsg(), ERROR, get_role_oid(), get_rolespec_oid(), GetUserId(), GrantRoleStmt::granted_roles, GrantRoleStmt::grantee_roles, grantor, GrantRoleStmt::grantor, GrantRoleStmt::is_grant, lfirst, NIL, NoLock, AccessPriv::priv_name, roleSpecsToIds(), table_close(), and table_open().

Referenced by standard_ProcessUtility().

1302 {
1303  Relation pg_authid_rel;
1304  Oid grantor;
1305  List *grantee_ids;
1306  ListCell *item;
1307 
1308  if (stmt->grantor)
1309  grantor = get_rolespec_oid(stmt->grantor, false);
1310  else
1311  grantor = GetUserId();
1312 
1313  grantee_ids = roleSpecsToIds(stmt->grantee_roles);
1314 
1315  /* AccessShareLock is enough since we aren't modifying pg_authid */
1316  pg_authid_rel = table_open(AuthIdRelationId, AccessShareLock);
1317 
1318  /*
1319  * Step through all of the granted roles and add/remove entries for the
1320  * grantees, or, if admin_opt is set, then just add/remove the admin
1321  * option.
1322  *
1323  * Note: Permissions checking is done by AddRoleMems/DelRoleMems
1324  */
1325  foreach(item, stmt->granted_roles)
1326  {
1327  AccessPriv *priv = (AccessPriv *) lfirst(item);
1328  char *rolename = priv->priv_name;
1329  Oid roleid;
1330 
1331  /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1332  if (rolename == NULL || priv->cols != NIL)
1333  ereport(ERROR,
1334  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1335  errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
1336 
1337  roleid = get_role_oid(rolename, false);
1338  if (stmt->is_grant)
1339  AddRoleMems(rolename, roleid,
1340  stmt->grantee_roles, grantee_ids,
1341  grantor, stmt->admin_opt);
1342  else
1343  DelRoleMems(rolename, roleid,
1344  stmt->grantee_roles, grantee_ids,
1345  stmt->admin_opt);
1346  }
1347 
1348  /*
1349  * Close pg_authid, but keep lock till commit.
1350  */
1351  table_close(pg_authid_rel, NoLock);
1352 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
Oid GetUserId(void)
Definition: miscinit.c:380
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:570
List * granted_roles
Definition: parsenodes.h:1957
List * cols
Definition: parsenodes.h:1942
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5191
Oid grantor
#define ERROR
Definition: elog.h:43
static void AddRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, Oid grantorId, bool admin_opt)
Definition: user.c:1452
#define NoLock
Definition: lockdefs.h:34
#define ereport(elevel, rest)
Definition: elog.h:141
RoleSpec * grantor
Definition: parsenodes.h:1961
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5225
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1423
#define lfirst(lc)
Definition: pg_list.h:190
int errmsg(const char *fmt,...)
Definition: elog.c:784
List * grantee_roles
Definition: parsenodes.h:1958
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
char * priv_name
Definition: parsenodes.h:1941
static void DelRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, bool admin_opt)
Definition: user.c:1596

◆ ReassignOwnedObjects()

void ReassignOwnedObjects ( ReassignOwnedStmt stmt)

Definition at line 1386 of file user.c.

References ereport, errcode(), errmsg(), ERROR, get_rolespec_oid(), GetUserId(), has_privs_of_role(), lfirst_oid, ReassignOwnedStmt::newrole, ReassignOwnedStmt::roles, roleSpecsToIds(), and shdepReassignOwned().

Referenced by standard_ProcessUtility().

1387 {
1388  List *role_ids = roleSpecsToIds(stmt->roles);
1389  ListCell *cell;
1390  Oid newrole;
1391 
1392  /* Check privileges */
1393  foreach(cell, role_ids)
1394  {
1395  Oid roleid = lfirst_oid(cell);
1396 
1397  if (!has_privs_of_role(GetUserId(), roleid))
1398  ereport(ERROR,
1399  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1400  errmsg("permission denied to reassign objects")));
1401  }
1402 
1403  /* Must have privileges on the receiving side too */
1404  newrole = get_rolespec_oid(stmt->newrole, false);
1405 
1406  if (!has_privs_of_role(GetUserId(), newrole))
1407  ereport(ERROR,
1408  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1409  errmsg("permission denied to reassign objects")));
1410 
1411  /* Ok, do it */
1412  shdepReassignOwned(role_ids, newrole);
1413 }
Oid GetUserId(void)
Definition: miscinit.c:380
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
void shdepReassignOwned(List *roleids, Oid newrole)
Definition: pg_shdepend.c:1378
#define ereport(elevel, rest)
Definition: elog.h:141
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5225
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1423
RoleSpec * newrole
Definition: parsenodes.h:3434
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ RenameRole()

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

Definition at line 1161 of file user.c.

References AUTHNAME, CatalogTupleUpdate(), CStringGetDatum, DirectFunctionCall1, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errmsg(), ERROR, get_password_type(), GetOuterUserId(), GetSessionUserId(), GETSTRUCT, have_createrole_privilege(), heap_getattr, heap_modify_tuple(), HeapTupleIsValid, i, InvokeObjectPostAlterHook, 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().

1162 {
1163  HeapTuple oldtuple,
1164  newtuple;
1165  TupleDesc dsc;
1166  Relation rel;
1167  Datum datum;
1168  bool isnull;
1169  Datum repl_val[Natts_pg_authid];
1170  bool repl_null[Natts_pg_authid];
1171  bool repl_repl[Natts_pg_authid];
1172  int i;
1173  Oid roleid;
1174  ObjectAddress address;
1175  Form_pg_authid authform;
1176 
1177  rel = table_open(AuthIdRelationId, RowExclusiveLock);
1178  dsc = RelationGetDescr(rel);
1179 
1180  oldtuple = SearchSysCache1(AUTHNAME, CStringGetDatum(oldname));
1181  if (!HeapTupleIsValid(oldtuple))
1182  ereport(ERROR,
1183  (errcode(ERRCODE_UNDEFINED_OBJECT),
1184  errmsg("role \"%s\" does not exist", oldname)));
1185 
1186  /*
1187  * XXX Client applications probably store the session user somewhere, so
1188  * renaming it could cause confusion. On the other hand, there may not be
1189  * an actual problem besides a little confusion, so think about this and
1190  * decide. Same for SET ROLE ... we don't restrict renaming the current
1191  * effective userid, though.
1192  */
1193 
1194  authform = (Form_pg_authid) GETSTRUCT(oldtuple);
1195  roleid = authform->oid;
1196 
1197  if (roleid == GetSessionUserId())
1198  ereport(ERROR,
1199  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1200  errmsg("session user cannot be renamed")));
1201  if (roleid == GetOuterUserId())
1202  ereport(ERROR,
1203  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1204  errmsg("current user cannot be renamed")));
1205 
1206  /*
1207  * Check that the user is not trying to rename a system role and not
1208  * trying to rename a role into the reserved "pg_" namespace.
1209  */
1210  if (IsReservedName(NameStr(authform->rolname)))
1211  ereport(ERROR,
1212  (errcode(ERRCODE_RESERVED_NAME),
1213  errmsg("role name \"%s\" is reserved",
1214  NameStr(authform->rolname)),
1215  errdetail("Role names starting with \"pg_\" are reserved.")));
1216 
1217  if (IsReservedName(newname))
1218  ereport(ERROR,
1219  (errcode(ERRCODE_RESERVED_NAME),
1220  errmsg("role name \"%s\" is reserved",
1221  newname),
1222  errdetail("Role names starting with \"pg_\" are reserved.")));
1223 
1224  /*
1225  * If built with appropriate switch, whine when regression-testing
1226  * conventions for role names are violated.
1227  */
1228 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1229  if (strncmp(newname, "regress_", 8) != 0)
1230  elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\"");
1231 #endif
1232 
1233  /* make sure the new name doesn't exist */
1235  ereport(ERROR,
1237  errmsg("role \"%s\" already exists", newname)));
1238 
1239  /*
1240  * createrole is enough privilege unless you want to mess with a superuser
1241  */
1242  if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)
1243  {
1244  if (!superuser())
1245  ereport(ERROR,
1246  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1247  errmsg("must be superuser to rename superusers")));
1248  }
1249  else
1250  {
1252  ereport(ERROR,
1253  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1254  errmsg("permission denied to rename role")));
1255  }
1256 
1257  /* OK, construct the modified tuple */
1258  for (i = 0; i < Natts_pg_authid; i++)
1259  repl_repl[i] = false;
1260 
1261  repl_repl[Anum_pg_authid_rolname - 1] = true;
1262  repl_val[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein,
1263  CStringGetDatum(newname));
1264  repl_null[Anum_pg_authid_rolname - 1] = false;
1265 
1266  datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1267 
1268  if (!isnull && get_password_type(TextDatumGetCString(datum)) == PASSWORD_TYPE_MD5)
1269  {
1270  /* MD5 uses the username as salt, so just clear it on a rename */
1271  repl_repl[Anum_pg_authid_rolpassword - 1] = true;
1272  repl_null[Anum_pg_authid_rolpassword - 1] = true;
1273 
1274  ereport(NOTICE,
1275  (errmsg("MD5 password cleared because of role rename")));
1276  }
1277 
1278  newtuple = heap_modify_tuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
1279  CatalogTupleUpdate(rel, &oldtuple->t_self, newtuple);
1280 
1281  InvokeObjectPostAlterHook(AuthIdRelationId, roleid, 0);
1282 
1283  ObjectAddressSet(address, AuthIdRelationId, roleid);
1284 
1285  ReleaseSysCache(oldtuple);
1286 
1287  /*
1288  * Close pg_authid, but keep lock till commit.
1289  */
1290  table_close(rel, NoLock);
1291 
1292  return address;
1293 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:445
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:214
Oid GetSessionUserId(void)
Definition: miscinit.c:414
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
Oid GetOuterUserId(void)
Definition: miscinit.c:391
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define WARNING
Definition: elog.h:40
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
#define TextDatumGetCString(d)
Definition: builtins.h:84
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:784
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:89
#define elog(elevel,...)
Definition: elog.h:226
static bool have_createrole_privilege(void)
Definition: user.c:61
int i
#define NameStr(name)
Definition: c.h:609
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:33

◆ roleSpecsToIds()

List* roleSpecsToIds ( List memberNames)

Definition at line 1423 of file user.c.

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

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

1424 {
1425  List *result = NIL;
1426  ListCell *l;
1427 
1428  foreach(l, memberNames)
1429  {
1430  RoleSpec *rolespec = lfirst_node(RoleSpec, l);
1431  Oid roleid;
1432 
1433  roleid = get_rolespec_oid(rolespec, false);
1434  result = lappend_oid(result, roleid);
1435  }
1436  return result;
1437 }
#define NIL
Definition: pg_list.h:65
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
#define lfirst_node(type, lc)
Definition: pg_list.h:193
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5225
Definition: pg_list.h:50

Variable Documentation

◆ check_password_hook

Definition at line 49 of file user.c.

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

◆ Password_encryption

int Password_encryption

Definition at line 46 of file user.c.

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