PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

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

Oid AlterRole ( AlterRoleStmt stmt)

Definition at line 493 of file user.c.

References AlterRoleStmt::action, AddRoleMems(), Anum_pg_authid_rolbypassrls, Anum_pg_authid_rolcanlogin, Anum_pg_authid_rolconnlimit, Anum_pg_authid_rolcreatedb, Anum_pg_authid_rolcreaterole, Anum_pg_authid_rolinherit, Anum_pg_authid_rolpassword, Anum_pg_authid_rolreplication, Anum_pg_authid_rolsuper, Anum_pg_authid_rolvaliduntil, DefElem::arg, AuthIdRelationId, 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_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleGetOid, Int32GetDatum, intVal, InvalidOid, InvokeObjectPostAlterHook, lfirst, MemSet, NameStr, Natts_pg_authid, NIL, NoLock, NULL, ObjectIdGetDatum, AlterRoleStmt::options, password, Password_encryption, PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, PASSWORD_TYPE_SCRAM, pstrdup(), RelationGetDescr, ReleaseSysCache(), AlterRoleStmt::role, roleSpecsToIds(), RowExclusiveLock, strVal, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, and timestamptz_in().

Referenced by standard_ProcessUtility().

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

Definition at line 874 of file user.c.

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

Referenced by standard_ProcessUtility().

875 {
876  HeapTuple roletuple;
877  Oid databaseid = InvalidOid;
878  Oid roleid = InvalidOid;
879 
880  if (stmt->role)
881  {
883  "Cannot alter reserved roles.");
884 
885  roletuple = get_rolespec_tuple(stmt->role);
886  roleid = HeapTupleGetOid(roletuple);
887 
888  /*
889  * Obtain a lock on the role and make sure it didn't go away in the
890  * meantime.
891  */
893 
894  /*
895  * To mess with a superuser you gotta be superuser; else you need
896  * createrole, or just want to change your own settings
897  */
898  if (((Form_pg_authid) GETSTRUCT(roletuple))->rolsuper)
899  {
900  if (!superuser())
901  ereport(ERROR,
902  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
903  errmsg("must be superuser to alter superusers")));
904  }
905  else
906  {
907  if (!have_createrole_privilege() &&
908  HeapTupleGetOid(roletuple) != GetUserId())
909  ereport(ERROR,
910  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
911  errmsg("permission denied")));
912  }
913 
914  ReleaseSysCache(roletuple);
915  }
916 
917  /* look up and lock the database, if specified */
918  if (stmt->database != NULL)
919  {
920  databaseid = get_database_oid(stmt->database, false);
922 
923  if (!stmt->role)
924  {
925  /*
926  * If no role is specified, then this is effectively the same as
927  * ALTER DATABASE ... SET, so use the same permission check.
928  */
929  if (!pg_database_ownercheck(databaseid, GetUserId()))
931  stmt->database);
932  }
933  }
934 
935  if (!stmt->role && !stmt->database)
936  {
937  /* Must be superuser to alter settings globally. */
938  if (!superuser())
939  ereport(ERROR,
940  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
941  errmsg("must be superuser to alter settings globally")));
942  }
943 
944  AlterSetting(databaseid, roleid, stmt->setstmt);
945 
946  return roleid;
947 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
#define DatabaseRelationId
Definition: pg_database.h:29
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
RoleSpec * role
Definition: parsenodes.h:2391
unsigned int Oid
Definition: postgres_ext.h:31
#define AuthIdRelationId
Definition: pg_authid.h:42
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define ERROR
Definition: elog.h:43
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:986
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3377
#define ereport(elevel, rest)
Definition: elog.h:122
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:4938
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition: acl.c:5233
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
VariableSetStmt * setstmt
Definition: parsenodes.h:2393
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2001
#define InvalidOid
Definition: postgres_ext.h:36
#define NULL
Definition: c.h:229
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5167
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool have_createrole_privilege(void)
Definition: user.c:62
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
Oid CreateRole ( ParseState pstate,
CreateRoleStmt stmt 
)

Definition at line 72 of file user.c.

References AddRoleMems(), Anum_pg_authid_rolbypassrls, Anum_pg_authid_rolcanlogin, Anum_pg_authid_rolconnlimit, Anum_pg_authid_rolcreatedb, Anum_pg_authid_rolcreaterole, Anum_pg_authid_rolinherit, Anum_pg_authid_rolname, Anum_pg_authid_rolpassword, Anum_pg_authid_rolreplication, Anum_pg_authid_rolsuper, Anum_pg_authid_rolvaliduntil, DefElem::arg, AuthIdRelationId, 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(), GETSTRUCT, GetUserId(), have_createrole_privilege(), heap_close, heap_form_tuple(), heap_open(), HeapTupleGetOid, HeapTupleSetOid, Int32GetDatum, intVal, InvalidOid, InvokeObjectPostCreateHook, IsBinaryUpgrade, IsReservedName(), lfirst, list_make1, list_make1_oid, DefElem::location, makeString(), MemSet, namein(), NameStr, Natts_pg_authid, NIL, NoLock, NOTICE, NULL, ObjectIdGetDatum, OidIsValid, CreateRoleStmt::options, parser_errposition(), password, Password_encryption, PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, PASSWORD_TYPE_SCRAM, RelationGetDescr, ReleaseSysCache(), CreateRoleStmt::role, roleSpecsToIds(), ROLESTMT_GROUP, ROLESTMT_ROLE, ROLESTMT_USER, RowExclusiveLock, CreateRoleStmt::stmt_type, strVal, superuser(), and timestamptz_in().

Referenced by standard_ProcessUtility().

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

Definition at line 1321 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().

1322 {
1323  List *role_ids = roleSpecsToIds(stmt->roles);
1324  ListCell *cell;
1325 
1326  /* Check privileges */
1327  foreach(cell, role_ids)
1328  {
1329  Oid roleid = lfirst_oid(cell);
1330 
1331  if (!has_privs_of_role(GetUserId(), roleid))
1332  ereport(ERROR,
1333  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1334  errmsg("permission denied to drop objects")));
1335  }
1336 
1337  /* Ok, do it */
1338  shdepDropOwned(role_ids, stmt->behavior);
1339 }
void shdepDropOwned(List *roleids, DropBehavior behavior)
Definition: pg_shdepend.c:1162
Oid GetUserId(void)
Definition: miscinit.c:283
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4813
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
DropBehavior behavior
Definition: parsenodes.h:3248
#define ereport(elevel, rest)
Definition: elog.h:122
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1384
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
void DropRole ( DropRoleStmt stmt)

Definition at line 954 of file user.c.

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

Referenced by standard_ProcessUtility().

955 {
956  Relation pg_authid_rel,
957  pg_auth_members_rel;
958  ListCell *item;
959 
961  ereport(ERROR,
962  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
963  errmsg("permission denied to drop role")));
964 
965  /*
966  * Scan the pg_authid relation to find the Oid of the role(s) to be
967  * deleted.
968  */
969  pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
970  pg_auth_members_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
971 
972  foreach(item, stmt->roles)
973  {
974  RoleSpec *rolspec = lfirst(item);
975  char *role;
976  HeapTuple tuple,
977  tmp_tuple;
978  ScanKeyData scankey;
979  char *detail;
980  char *detail_log;
981  SysScanDesc sscan;
982  Oid roleid;
983 
984  if (rolspec->roletype != ROLESPEC_CSTRING)
985  ereport(ERROR,
986  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
987  errmsg("cannot use special role specifier in DROP ROLE")));
988  role = rolspec->rolename;
989 
990  tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role));
991  if (!HeapTupleIsValid(tuple))
992  {
993  if (!stmt->missing_ok)
994  {
995  ereport(ERROR,
996  (errcode(ERRCODE_UNDEFINED_OBJECT),
997  errmsg("role \"%s\" does not exist", role)));
998  }
999  else
1000  {
1001  ereport(NOTICE,
1002  (errmsg("role \"%s\" does not exist, skipping",
1003  role)));
1004  }
1005 
1006  continue;
1007  }
1008 
1009  roleid = HeapTupleGetOid(tuple);
1010 
1011  if (roleid == GetUserId())
1012  ereport(ERROR,
1013  (errcode(ERRCODE_OBJECT_IN_USE),
1014  errmsg("current user cannot be dropped")));
1015  if (roleid == GetOuterUserId())
1016  ereport(ERROR,
1017  (errcode(ERRCODE_OBJECT_IN_USE),
1018  errmsg("current user cannot be dropped")));
1019  if (roleid == GetSessionUserId())
1020  ereport(ERROR,
1021  (errcode(ERRCODE_OBJECT_IN_USE),
1022  errmsg("session user cannot be dropped")));
1023 
1024  /*
1025  * For safety's sake, we allow createrole holders to drop ordinary
1026  * roles but not superuser roles. This is mainly to avoid the
1027  * scenario where you accidentally drop the last superuser.
1028  */
1029  if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper &&
1030  !superuser())
1031  ereport(ERROR,
1032  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1033  errmsg("must be superuser to drop superusers")));
1034 
1035  /* DROP hook for the role being removed */
1037 
1038  /*
1039  * Lock the role, so nobody can add dependencies to her while we drop
1040  * her. We keep the lock until the end of transaction.
1041  */
1043 
1044  /* Check for pg_shdepend entries depending on this role */
1046  &detail, &detail_log))
1047  ereport(ERROR,
1048  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1049  errmsg("role \"%s\" cannot be dropped because some objects depend on it",
1050  role),
1051  errdetail_internal("%s", detail),
1052  errdetail_log("%s", detail_log)));
1053 
1054  /*
1055  * Remove the role from the pg_authid table
1056  */
1057  CatalogTupleDelete(pg_authid_rel, &tuple->t_self);
1058 
1059  ReleaseSysCache(tuple);
1060 
1061  /*
1062  * Remove role from the pg_auth_members table. We have to remove all
1063  * tuples that show it as either a role or a member.
1064  *
1065  * XXX what about grantor entries? Maybe we should do one heap scan.
1066  */
1067  ScanKeyInit(&scankey,
1069  BTEqualStrategyNumber, F_OIDEQ,
1070  ObjectIdGetDatum(roleid));
1071 
1072  sscan = systable_beginscan(pg_auth_members_rel, AuthMemRoleMemIndexId,
1073  true, NULL, 1, &scankey);
1074 
1075  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1076  {
1077  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1078  }
1079 
1080  systable_endscan(sscan);
1081 
1082  ScanKeyInit(&scankey,
1084  BTEqualStrategyNumber, F_OIDEQ,
1085  ObjectIdGetDatum(roleid));
1086 
1087  sscan = systable_beginscan(pg_auth_members_rel, AuthMemMemRoleIndexId,
1088  true, NULL, 1, &scankey);
1089 
1090  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1091  {
1092  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1093  }
1094 
1095  systable_endscan(sscan);
1096 
1097  /*
1098  * Remove any comments or security labels on this role.
1099  */
1102 
1103  /*
1104  * Remove settings for this role.
1105  */
1106  DropSetting(InvalidOid, roleid);
1107 
1108  /*
1109  * Advance command counter so that later iterations of this loop will
1110  * see the changes already made. This is essential if, for example,
1111  * we are trying to drop both a role and one of its direct members ---
1112  * we'll get an error if we try to delete the linking pg_auth_members
1113  * tuple twice. (We do not need a CCI between the two delete loops
1114  * above, because it's not allowed for a role to directly contain
1115  * itself.)
1116  */
1118  }
1119 
1120  /*
1121  * Now we can clean up; but keep locks until commit.
1122  */
1123  heap_close(pg_auth_members_rel, NoLock);
1124  heap_close(pg_authid_rel, NoLock);
1125 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:283
#define PointerGetDatum(X)
Definition: postgres.h:562
#define AuthMemRelationId
#define InvokeObjectDropHook(classId, objectId, subId)
Definition: objectaccess.h:154
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
List * roles
Definition: parsenodes.h:2399
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:317
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:150
int errdetail_internal(const char *fmt,...)
Definition: elog.c:900
#define AuthIdRelationId
Definition: pg_authid.h:42
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
Oid GetOuterUserId(void)
Definition: miscinit.c:294
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:921
#define ereport(elevel, rest)
Definition: elog.h:122
#define AuthMemRoleMemIndexId
Definition: indexing.h:102
#define Anum_pg_auth_members_roleid
void CommandCounterIncrement(void)
Definition: xact.c:922
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
RoleSpecType roletype
Definition: parsenodes.h:319
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:871
#define InvalidOid
Definition: postgres_ext.h:36
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
void DeleteSharedComments(Oid oid, Oid classoid)
Definition: comment.c:372
#define AuthMemMemRoleIndexId
Definition: indexing.h:104
char * rolename
Definition: parsenodes.h:320
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition: seclabel.c:414
#define AccessExclusiveLock
Definition: lockdefs.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool have_createrole_privilege(void)
Definition: user.c:62
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:521
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
void DropSetting(Oid databaseid, Oid roleid)
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define Anum_pg_auth_members_member
void GrantRole ( GrantRoleStmt stmt)

Definition at line 1262 of file user.c.

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

Referenced by standard_ProcessUtility().

1263 {
1264  Relation pg_authid_rel;
1265  Oid grantor;
1266  List *grantee_ids;
1267  ListCell *item;
1268 
1269  if (stmt->grantor)
1270  grantor = get_rolespec_oid(stmt->grantor, false);
1271  else
1272  grantor = GetUserId();
1273 
1274  grantee_ids = roleSpecsToIds(stmt->grantee_roles);
1275 
1276  /* AccessShareLock is enough since we aren't modifying pg_authid */
1277  pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
1278 
1279  /*
1280  * Step through all of the granted roles and add/remove entries for the
1281  * grantees, or, if admin_opt is set, then just add/remove the admin
1282  * option.
1283  *
1284  * Note: Permissions checking is done by AddRoleMems/DelRoleMems
1285  */
1286  foreach(item, stmt->granted_roles)
1287  {
1288  AccessPriv *priv = (AccessPriv *) lfirst(item);
1289  char *rolename = priv->priv_name;
1290  Oid roleid;
1291 
1292  /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1293  if (rolename == NULL || priv->cols != NIL)
1294  ereport(ERROR,
1295  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1296  errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
1297 
1298  roleid = get_role_oid(rolename, false);
1299  if (stmt->is_grant)
1300  AddRoleMems(rolename, roleid,
1301  stmt->grantee_roles, grantee_ids,
1302  grantor, stmt->admin_opt);
1303  else
1304  DelRoleMems(rolename, roleid,
1305  stmt->grantee_roles, grantee_ids,
1306  stmt->admin_opt);
1307  }
1308 
1309  /*
1310  * Close pg_authid, but keep lock till commit.
1311  */
1312  heap_close(pg_authid_rel, NoLock);
1313 }
#define NIL
Definition: pg_list.h:69
Oid GetUserId(void)
Definition: miscinit.c:283
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
List * granted_roles
Definition: parsenodes.h:1856
#define heap_close(r, l)
Definition: heapam.h:97
List * cols
Definition: parsenodes.h:1841
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5096
#define AuthIdRelationId
Definition: pg_authid.h:42
#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:1413
#define NoLock
Definition: lockdefs.h:34
#define ereport(elevel, rest)
Definition: elog.h:122
RoleSpec * grantor
Definition: parsenodes.h:1860
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5129
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1384
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
int errmsg(const char *fmt,...)
Definition: elog.c:797
List * grantee_roles
Definition: parsenodes.h:1857
Definition: pg_list.h:45
char * priv_name
Definition: parsenodes.h:1840
static void DelRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, bool admin_opt)
Definition: user.c:1557
void ReassignOwnedObjects ( ReassignOwnedStmt stmt)

Definition at line 1347 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().

1348 {
1349  List *role_ids = roleSpecsToIds(stmt->roles);
1350  ListCell *cell;
1351  Oid newrole;
1352 
1353  /* Check privileges */
1354  foreach(cell, role_ids)
1355  {
1356  Oid roleid = lfirst_oid(cell);
1357 
1358  if (!has_privs_of_role(GetUserId(), roleid))
1359  ereport(ERROR,
1360  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1361  errmsg("permission denied to reassign objects")));
1362  }
1363 
1364  /* Must have privileges on the receiving side too */
1365  newrole = get_rolespec_oid(stmt->newrole, false);
1366 
1367  if (!has_privs_of_role(GetUserId(), newrole))
1368  ereport(ERROR,
1369  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1370  errmsg("permission denied to reassign objects")));
1371 
1372  /* Ok, do it */
1373  shdepReassignOwned(role_ids, newrole);
1374 }
Oid GetUserId(void)
Definition: miscinit.c:283
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4813
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
void shdepReassignOwned(List *roleids, Oid newrole)
Definition: pg_shdepend.c:1284
#define ereport(elevel, rest)
Definition: elog.h:122
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5129
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1384
RoleSpec * newrole
Definition: parsenodes.h:3258
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108
ObjectAddress RenameRole ( const char *  oldname,
const char *  newname 
)

Definition at line 1131 of file user.c.

References Anum_pg_authid_rolname, Anum_pg_authid_rolpassword, AuthIdRelationId, AUTHNAME, CatalogTupleUpdate(), CStringGetDatum, DirectFunctionCall1, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errmsg(), ERROR, get_password_type(), GetOuterUserId(), GetSessionUserId(), GETSTRUCT, have_createrole_privilege(), heap_close, heap_getattr, heap_modify_tuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, InvokeObjectPostAlterHook, IsReservedName(), namein(), NameStr, Natts_pg_authid, NoLock, NOTICE, ObjectAddressSet, PASSWORD_TYPE_MD5, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1, SearchSysCacheExists1, superuser(), HeapTupleData::t_self, and TextDatumGetCString.

Referenced by ExecRenameStmt().

1132 {
1133  HeapTuple oldtuple,
1134  newtuple;
1135  TupleDesc dsc;
1136  Relation rel;
1137  Datum datum;
1138  bool isnull;
1139  Datum repl_val[Natts_pg_authid];
1140  bool repl_null[Natts_pg_authid];
1141  bool repl_repl[Natts_pg_authid];
1142  int i;
1143  Oid roleid;
1144  ObjectAddress address;
1145  Form_pg_authid authform;
1146 
1148  dsc = RelationGetDescr(rel);
1149 
1150  oldtuple = SearchSysCache1(AUTHNAME, CStringGetDatum(oldname));
1151  if (!HeapTupleIsValid(oldtuple))
1152  ereport(ERROR,
1153  (errcode(ERRCODE_UNDEFINED_OBJECT),
1154  errmsg("role \"%s\" does not exist", oldname)));
1155 
1156  /*
1157  * XXX Client applications probably store the session user somewhere, so
1158  * renaming it could cause confusion. On the other hand, there may not be
1159  * an actual problem besides a little confusion, so think about this and
1160  * decide. Same for SET ROLE ... we don't restrict renaming the current
1161  * effective userid, though.
1162  */
1163 
1164  roleid = HeapTupleGetOid(oldtuple);
1165  authform = (Form_pg_authid) GETSTRUCT(oldtuple);
1166 
1167  if (roleid == GetSessionUserId())
1168  ereport(ERROR,
1169  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1170  errmsg("session user cannot be renamed")));
1171  if (roleid == GetOuterUserId())
1172  ereport(ERROR,
1173  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1174  errmsg("current user cannot be renamed")));
1175 
1176  /*
1177  * Check that the user is not trying to rename a system role and not
1178  * trying to rename a role into the reserved "pg_" namespace.
1179  */
1180  if (IsReservedName(NameStr(authform->rolname)))
1181  ereport(ERROR,
1182  (errcode(ERRCODE_RESERVED_NAME),
1183  errmsg("role name \"%s\" is reserved",
1184  NameStr(authform->rolname)),
1185  errdetail("Role names starting with \"pg_\" are reserved.")));
1186 
1187  if (IsReservedName(newname))
1188  ereport(ERROR,
1189  (errcode(ERRCODE_RESERVED_NAME),
1190  errmsg("role name \"%s\" is reserved",
1191  newname),
1192  errdetail("Role names starting with \"pg_\" are reserved.")));
1193 
1194  /* make sure the new name doesn't exist */
1196  ereport(ERROR,
1198  errmsg("role \"%s\" already exists", newname)));
1199 
1200  /*
1201  * createrole is enough privilege unless you want to mess with a superuser
1202  */
1203  if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)
1204  {
1205  if (!superuser())
1206  ereport(ERROR,
1207  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1208  errmsg("must be superuser to rename superusers")));
1209  }
1210  else
1211  {
1213  ereport(ERROR,
1214  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1215  errmsg("permission denied to rename role")));
1216  }
1217 
1218  /* OK, construct the modified tuple */
1219  for (i = 0; i < Natts_pg_authid; i++)
1220  repl_repl[i] = false;
1221 
1222  repl_repl[Anum_pg_authid_rolname - 1] = true;
1224  CStringGetDatum(newname));
1225  repl_null[Anum_pg_authid_rolname - 1] = false;
1226 
1227  datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1228 
1229  if (!isnull && get_password_type(TextDatumGetCString(datum)) == PASSWORD_TYPE_MD5)
1230  {
1231  /* MD5 uses the username as salt, so just clear it on a rename */
1232  repl_repl[Anum_pg_authid_rolpassword - 1] = true;
1233  repl_null[Anum_pg_authid_rolpassword - 1] = true;
1234 
1235  ereport(NOTICE,
1236  (errmsg("MD5 password cleared because of role rename")));
1237  }
1238 
1239  newtuple = heap_modify_tuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
1240  CatalogTupleUpdate(rel, &oldtuple->t_self, newtuple);
1241 
1243 
1244  ObjectAddressSet(address, AuthIdRelationId, roleid);
1245 
1246  ReleaseSysCache(oldtuple);
1247 
1248  /*
1249  * Close pg_authid, but keep lock till commit.
1250  */
1251  heap_close(rel, NoLock);
1252 
1253  return address;
1254 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:111
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define Anum_pg_authid_rolpassword
Definition: pg_authid.h:88
#define heap_close(r, l)
Definition: heapam.h:97
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:576
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:193
Oid GetSessionUserId(void)
Definition: miscinit.c:317
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:150
#define AuthIdRelationId
Definition: pg_authid.h:42
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:168
Oid GetOuterUserId(void)
Definition: miscinit.c:294
#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:873
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define TextDatumGetCString(d)
Definition: builtins.h:92
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1093
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define Anum_pg_authid_rolname
Definition: pg_authid.h:79
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool have_createrole_privilege(void)
Definition: user.c:62
int i
#define NameStr(name)
Definition: c.h:499
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define Natts_pg_authid
Definition: pg_authid.h:78
List* roleSpecsToIds ( List memberNames)

Definition at line 1384 of file user.c.

References castNode, get_rolespec_oid(), lappend_oid(), lfirst, NIL, and result.

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

1385 {
1386  List *result = NIL;
1387  ListCell *l;
1388 
1389  foreach(l, memberNames)
1390  {
1391  RoleSpec *rolespec = castNode(RoleSpec, lfirst(l));
1392  Oid roleid;
1393 
1394  roleid = get_rolespec_oid(rolespec, false);
1395  result = lappend_oid(result, roleid);
1396  }
1397  return result;
1398 }
#define NIL
Definition: pg_list.h:69
#define castNode(_type_, nodeptr)
Definition: nodes.h:589
return result
Definition: formatting.c:1618
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5129
#define lfirst(lc)
Definition: pg_list.h:106
Definition: pg_list.h:45

Variable Documentation

Definition at line 50 of file user.c.

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

int Password_encryption

Definition at line 47 of file user.c.

Referenced by AlterRole(), and CreateRole().