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 504 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, NOTICE, NULL, ObjectIdGetDatum, AlterRoleStmt::options, password, Password_encryption, plain_crypt_verify(), pstrdup(), RelationGetDescr, ReleaseSysCache(), AlterRoleStmt::role, roleSpecsToIds(), RowExclusiveLock, STATUS_OK, strVal, superuser(), SysCacheGetAttr(), HeapTupleData::t_self, and timestamptz_in().

Referenced by standard_ProcessUtility().

505 {
506  Datum new_record[Natts_pg_authid];
507  bool new_record_nulls[Natts_pg_authid];
508  bool new_record_repl[Natts_pg_authid];
509  Relation pg_authid_rel;
510  TupleDesc pg_authid_dsc;
511  HeapTuple tuple,
512  new_tuple;
513  Form_pg_authid authform;
514  ListCell *option;
515  char *rolename = NULL;
516  char *password = NULL; /* user password */
517  int issuper = -1; /* Make the user a superuser? */
518  int inherit = -1; /* Auto inherit privileges? */
519  int createrole = -1; /* Can this user create roles? */
520  int createdb = -1; /* Can the user create databases? */
521  int canlogin = -1; /* Can this user login? */
522  int isreplication = -1; /* Is this a replication role? */
523  int connlimit = -1; /* maximum connections allowed */
524  List *rolemembers = NIL; /* roles to be added/removed */
525  char *validUntil = NULL; /* time the login is valid until */
526  Datum validUntil_datum; /* same, as timestamptz Datum */
527  bool validUntil_null;
528  int bypassrls = -1;
529  DefElem *dpassword = NULL;
530  DefElem *dissuper = NULL;
531  DefElem *dinherit = NULL;
532  DefElem *dcreaterole = NULL;
533  DefElem *dcreatedb = NULL;
534  DefElem *dcanlogin = NULL;
535  DefElem *disreplication = NULL;
536  DefElem *dconnlimit = NULL;
537  DefElem *drolemembers = NULL;
538  DefElem *dvalidUntil = NULL;
539  DefElem *dbypassRLS = NULL;
540  Oid roleid;
541 
543  "Cannot alter reserved roles.");
544 
545  /* Extract options from the statement node tree */
546  foreach(option, stmt->options)
547  {
548  DefElem *defel = (DefElem *) lfirst(option);
549 
550  if (strcmp(defel->defname, "password") == 0)
551  {
552  if (dpassword)
553  ereport(ERROR,
554  (errcode(ERRCODE_SYNTAX_ERROR),
555  errmsg("conflicting or redundant options")));
556  dpassword = defel;
557  }
558  else if (strcmp(defel->defname, "superuser") == 0)
559  {
560  if (dissuper)
561  ereport(ERROR,
562  (errcode(ERRCODE_SYNTAX_ERROR),
563  errmsg("conflicting or redundant options")));
564  dissuper = defel;
565  }
566  else if (strcmp(defel->defname, "inherit") == 0)
567  {
568  if (dinherit)
569  ereport(ERROR,
570  (errcode(ERRCODE_SYNTAX_ERROR),
571  errmsg("conflicting or redundant options")));
572  dinherit = defel;
573  }
574  else if (strcmp(defel->defname, "createrole") == 0)
575  {
576  if (dcreaterole)
577  ereport(ERROR,
578  (errcode(ERRCODE_SYNTAX_ERROR),
579  errmsg("conflicting or redundant options")));
580  dcreaterole = defel;
581  }
582  else if (strcmp(defel->defname, "createdb") == 0)
583  {
584  if (dcreatedb)
585  ereport(ERROR,
586  (errcode(ERRCODE_SYNTAX_ERROR),
587  errmsg("conflicting or redundant options")));
588  dcreatedb = defel;
589  }
590  else if (strcmp(defel->defname, "canlogin") == 0)
591  {
592  if (dcanlogin)
593  ereport(ERROR,
594  (errcode(ERRCODE_SYNTAX_ERROR),
595  errmsg("conflicting or redundant options")));
596  dcanlogin = defel;
597  }
598  else if (strcmp(defel->defname, "isreplication") == 0)
599  {
600  if (disreplication)
601  ereport(ERROR,
602  (errcode(ERRCODE_SYNTAX_ERROR),
603  errmsg("conflicting or redundant options")));
604  disreplication = defel;
605  }
606  else if (strcmp(defel->defname, "connectionlimit") == 0)
607  {
608  if (dconnlimit)
609  ereport(ERROR,
610  (errcode(ERRCODE_SYNTAX_ERROR),
611  errmsg("conflicting or redundant options")));
612  dconnlimit = defel;
613  }
614  else if (strcmp(defel->defname, "rolemembers") == 0 &&
615  stmt->action != 0)
616  {
617  if (drolemembers)
618  ereport(ERROR,
619  (errcode(ERRCODE_SYNTAX_ERROR),
620  errmsg("conflicting or redundant options")));
621  drolemembers = defel;
622  }
623  else if (strcmp(defel->defname, "validUntil") == 0)
624  {
625  if (dvalidUntil)
626  ereport(ERROR,
627  (errcode(ERRCODE_SYNTAX_ERROR),
628  errmsg("conflicting or redundant options")));
629  dvalidUntil = defel;
630  }
631  else if (strcmp(defel->defname, "bypassrls") == 0)
632  {
633  if (dbypassRLS)
634  ereport(ERROR,
635  (errcode(ERRCODE_SYNTAX_ERROR),
636  errmsg("conflicting or redundant options")));
637  dbypassRLS = defel;
638  }
639  else
640  elog(ERROR, "option \"%s\" not recognized",
641  defel->defname);
642  }
643 
644  if (dpassword && dpassword->arg)
645  password = strVal(dpassword->arg);
646  if (dissuper)
647  issuper = intVal(dissuper->arg);
648  if (dinherit)
649  inherit = intVal(dinherit->arg);
650  if (dcreaterole)
651  createrole = intVal(dcreaterole->arg);
652  if (dcreatedb)
653  createdb = intVal(dcreatedb->arg);
654  if (dcanlogin)
655  canlogin = intVal(dcanlogin->arg);
656  if (disreplication)
657  isreplication = intVal(disreplication->arg);
658  if (dconnlimit)
659  {
660  connlimit = intVal(dconnlimit->arg);
661  if (connlimit < -1)
662  ereport(ERROR,
663  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
664  errmsg("invalid connection limit: %d", connlimit)));
665  }
666  if (drolemembers)
667  rolemembers = (List *) drolemembers->arg;
668  if (dvalidUntil)
669  validUntil = strVal(dvalidUntil->arg);
670  if (dbypassRLS)
671  bypassrls = intVal(dbypassRLS->arg);
672 
673  /*
674  * Scan the pg_authid relation to be certain the user exists.
675  */
676  pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
677  pg_authid_dsc = RelationGetDescr(pg_authid_rel);
678 
679  tuple = get_rolespec_tuple(stmt->role);
680  authform = (Form_pg_authid) GETSTRUCT(tuple);
681  rolename = pstrdup(NameStr(authform->rolname));
682  roleid = HeapTupleGetOid(tuple);
683 
684  /*
685  * To mess with a superuser you gotta be superuser; else you need
686  * createrole, or just want to change your own password
687  */
688  if (authform->rolsuper || issuper >= 0)
689  {
690  if (!superuser())
691  ereport(ERROR,
692  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
693  errmsg("must be superuser to alter superusers")));
694  }
695  else if (authform->rolreplication || isreplication >= 0)
696  {
697  if (!superuser())
698  ereport(ERROR,
699  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
700  errmsg("must be superuser to alter replication users")));
701  }
702  else if (authform->rolbypassrls || bypassrls >= 0)
703  {
704  if (!superuser())
705  ereport(ERROR,
706  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
707  errmsg("must be superuser to change bypassrls attribute")));
708  }
709  else if (!have_createrole_privilege())
710  {
711  if (!(inherit < 0 &&
712  createrole < 0 &&
713  createdb < 0 &&
714  canlogin < 0 &&
715  isreplication < 0 &&
716  !dconnlimit &&
717  !rolemembers &&
718  !validUntil &&
719  dpassword &&
720  roleid == GetUserId()))
721  ereport(ERROR,
722  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
723  errmsg("permission denied")));
724  }
725 
726  /* Convert validuntil to internal form */
727  if (validUntil)
728  {
729  validUntil_datum = DirectFunctionCall3(timestamptz_in,
730  CStringGetDatum(validUntil),
732  Int32GetDatum(-1));
733  validUntil_null = false;
734  }
735  else
736  {
737  /* fetch existing setting in case hook needs it */
738  validUntil_datum = SysCacheGetAttr(AUTHNAME, tuple,
740  &validUntil_null);
741  }
742 
743  /*
744  * Call the password checking hook if there is one defined
745  */
746  if (check_password_hook && password)
747  (*check_password_hook) (rolename,
748  password,
749  get_password_type(password),
750  validUntil_datum,
751  validUntil_null);
752 
753  /*
754  * Build an updated tuple, perusing the information just obtained
755  */
756  MemSet(new_record, 0, sizeof(new_record));
757  MemSet(new_record_nulls, false, sizeof(new_record_nulls));
758  MemSet(new_record_repl, false, sizeof(new_record_repl));
759 
760  /*
761  * issuper/createrole/etc
762  */
763  if (issuper >= 0)
764  {
765  new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
766  new_record_repl[Anum_pg_authid_rolsuper - 1] = true;
767  }
768 
769  if (inherit >= 0)
770  {
771  new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit > 0);
772  new_record_repl[Anum_pg_authid_rolinherit - 1] = true;
773  }
774 
775  if (createrole >= 0)
776  {
777  new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);
778  new_record_repl[Anum_pg_authid_rolcreaterole - 1] = true;
779  }
780 
781  if (createdb >= 0)
782  {
783  new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0);
784  new_record_repl[Anum_pg_authid_rolcreatedb - 1] = true;
785  }
786 
787  if (canlogin >= 0)
788  {
789  new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0);
790  new_record_repl[Anum_pg_authid_rolcanlogin - 1] = true;
791  }
792 
793  if (isreplication >= 0)
794  {
795  new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication > 0);
796  new_record_repl[Anum_pg_authid_rolreplication - 1] = true;
797  }
798 
799  if (dconnlimit)
800  {
801  new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
802  new_record_repl[Anum_pg_authid_rolconnlimit - 1] = true;
803  }
804 
805  /* password */
806  if (password)
807  {
808  char *shadow_pass;
809  char *logdetail;
810 
811  /* Like in CREATE USER, don't allow an empty password. */
812  if (password[0] == '\0' ||
813  plain_crypt_verify(rolename, password, "", &logdetail) == STATUS_OK)
814  {
815  ereport(NOTICE,
816  (errmsg("empty string is not a valid password, clearing password")));
817  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
818  }
819  else
820  {
821  /* Encrypt the password to the requested format. */
822  shadow_pass = encrypt_password(Password_encryption, rolename,
823  password);
824  new_record[Anum_pg_authid_rolpassword - 1] =
825  CStringGetTextDatum(shadow_pass);
826  }
827  new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
828  }
829 
830  /* unset password */
831  if (dpassword && dpassword->arg == NULL)
832  {
833  new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
834  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
835  }
836 
837  /* valid until */
838  new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
839  new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
840  new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = true;
841 
842  if (bypassrls >= 0)
843  {
844  new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls > 0);
845  new_record_repl[Anum_pg_authid_rolbypassrls - 1] = true;
846  }
847 
848  new_tuple = heap_modify_tuple(tuple, pg_authid_dsc, new_record,
849  new_record_nulls, new_record_repl);
850  CatalogTupleUpdate(pg_authid_rel, &tuple->t_self, new_tuple);
851 
853 
854  ReleaseSysCache(tuple);
855  heap_freetuple(new_tuple);
856 
857  /*
858  * Advance command counter so we can see new record; else tests in
859  * AddRoleMems may fail.
860  */
861  if (rolemembers)
863 
864  if (stmt->action == +1) /* add members to role */
865  AddRoleMems(rolename, roleid,
866  rolemembers, roleSpecsToIds(rolemembers),
867  GetUserId(), false);
868  else if (stmt->action == -1) /* drop members from role */
869  DelRoleMems(rolename, roleid,
870  rolemembers, roleSpecsToIds(rolemembers),
871  false);
872 
873  /*
874  * Close pg_authid, but keep lock till commit.
875  */
876  heap_close(pg_authid_rel, NoLock);
877 
878  return roleid;
879 }
#define NIL
Definition: pg_list.h:69
static char password[100]
Definition: streamutil.c:42
RoleSpec * role
Definition: parsenodes.h:2434
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:284
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:91
#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:858
#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:1373
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:1425
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 STATUS_OK
Definition: c.h:976
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:588
Node * arg
Definition: parsenodes.h:720
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, char **logdetail)
Definition: crypt.c:216
#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:1117
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1279
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#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:108
#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:1396
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
List * options
Definition: parsenodes.h:2435
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:383
#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:719
#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:794
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:1569
Oid AlterRoleSet ( AlterRoleSetStmt stmt)

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

887 {
888  HeapTuple roletuple;
889  Oid databaseid = InvalidOid;
890  Oid roleid = InvalidOid;
891 
892  if (stmt->role)
893  {
895  "Cannot alter reserved roles.");
896 
897  roletuple = get_rolespec_tuple(stmt->role);
898  roleid = HeapTupleGetOid(roletuple);
899 
900  /*
901  * Obtain a lock on the role and make sure it didn't go away in the
902  * meantime.
903  */
905 
906  /*
907  * To mess with a superuser you gotta be superuser; else you need
908  * createrole, or just want to change your own settings
909  */
910  if (((Form_pg_authid) GETSTRUCT(roletuple))->rolsuper)
911  {
912  if (!superuser())
913  ereport(ERROR,
914  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
915  errmsg("must be superuser to alter superusers")));
916  }
917  else
918  {
919  if (!have_createrole_privilege() &&
920  HeapTupleGetOid(roletuple) != GetUserId())
921  ereport(ERROR,
922  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
923  errmsg("permission denied")));
924  }
925 
926  ReleaseSysCache(roletuple);
927  }
928 
929  /* look up and lock the database, if specified */
930  if (stmt->database != NULL)
931  {
932  databaseid = get_database_oid(stmt->database, false);
934 
935  if (!stmt->role)
936  {
937  /*
938  * If no role is specified, then this is effectively the same as
939  * ALTER DATABASE ... SET, so use the same permission check.
940  */
941  if (!pg_database_ownercheck(databaseid, GetUserId()))
943  stmt->database);
944  }
945  }
946 
947  if (!stmt->role && !stmt->database)
948  {
949  /* Must be superuser to alter settings globally. */
950  if (!superuser())
951  ereport(ERROR,
952  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
953  errmsg("must be superuser to alter settings globally")));
954  }
955 
956  AlterSetting(databaseid, roleid, stmt->setstmt);
957 
958  return roleid;
959 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:284
#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:2442
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:987
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
#define ereport(elevel, rest)
Definition: elog.h:122
bool pg_database_ownercheck(Oid db_oid, Oid roleid)
Definition: aclchk.c:4964
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition: acl.c:5233
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
VariableSetStmt * setstmt
Definition: parsenodes.h:2444
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2009
#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, plain_crypt_verify(), RelationGetDescr, ReleaseSysCache(), CreateRoleStmt::role, roleSpecsToIds(), ROLESTMT_GROUP, ROLESTMT_ROLE, ROLESTMT_USER, RowExclusiveLock, STATUS_OK, 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  bool issuper = false; /* Make the user a superuser? */
84  bool inherit = true; /* Auto inherit privileges? */
85  bool createrole = false; /* Can this user create roles? */
86  bool createdb = false; /* Can the user create databases? */
87  bool canlogin = false; /* Can this user login? */
88  bool isreplication = false; /* Is this a replication role? */
89  bool bypassrls = false; /* Is this a row security enabled role? */
90  int connlimit = -1; /* maximum connections allowed */
91  List *addroleto = NIL; /* roles to make this a member of */
92  List *rolemembers = NIL; /* roles to be members of this role */
93  List *adminmembers = NIL; /* roles to be admins of this role */
94  char *validUntil = NULL; /* time the login is valid until */
95  Datum validUntil_datum; /* same, as timestamptz Datum */
96  bool validUntil_null;
97  DefElem *dpassword = NULL;
98  DefElem *dissuper = NULL;
99  DefElem *dinherit = NULL;
100  DefElem *dcreaterole = NULL;
101  DefElem *dcreatedb = NULL;
102  DefElem *dcanlogin = NULL;
103  DefElem *disreplication = NULL;
104  DefElem *dconnlimit = NULL;
105  DefElem *daddroleto = NULL;
106  DefElem *drolemembers = NULL;
107  DefElem *dadminmembers = NULL;
108  DefElem *dvalidUntil = NULL;
109  DefElem *dbypassRLS = NULL;
110 
111  /* The defaults can vary depending on the original statement type */
112  switch (stmt->stmt_type)
113  {
114  case ROLESTMT_ROLE:
115  break;
116  case ROLESTMT_USER:
117  canlogin = true;
118  /* may eventually want inherit to default to false here */
119  break;
120  case ROLESTMT_GROUP:
121  break;
122  }
123 
124  /* Extract options from the statement node tree */
125  foreach(option, stmt->options)
126  {
127  DefElem *defel = (DefElem *) lfirst(option);
128 
129  if (strcmp(defel->defname, "password") == 0)
130  {
131  if (dpassword)
132  ereport(ERROR,
133  (errcode(ERRCODE_SYNTAX_ERROR),
134  errmsg("conflicting or redundant options"),
135  parser_errposition(pstate, defel->location)));
136  dpassword = defel;
137  }
138  else if (strcmp(defel->defname, "sysid") == 0)
139  {
140  ereport(NOTICE,
141  (errmsg("SYSID can no longer be specified")));
142  }
143  else if (strcmp(defel->defname, "superuser") == 0)
144  {
145  if (dissuper)
146  ereport(ERROR,
147  (errcode(ERRCODE_SYNTAX_ERROR),
148  errmsg("conflicting or redundant options"),
149  parser_errposition(pstate, defel->location)));
150  dissuper = defel;
151  }
152  else if (strcmp(defel->defname, "inherit") == 0)
153  {
154  if (dinherit)
155  ereport(ERROR,
156  (errcode(ERRCODE_SYNTAX_ERROR),
157  errmsg("conflicting or redundant options"),
158  parser_errposition(pstate, defel->location)));
159  dinherit = defel;
160  }
161  else if (strcmp(defel->defname, "createrole") == 0)
162  {
163  if (dcreaterole)
164  ereport(ERROR,
165  (errcode(ERRCODE_SYNTAX_ERROR),
166  errmsg("conflicting or redundant options"),
167  parser_errposition(pstate, defel->location)));
168  dcreaterole = defel;
169  }
170  else if (strcmp(defel->defname, "createdb") == 0)
171  {
172  if (dcreatedb)
173  ereport(ERROR,
174  (errcode(ERRCODE_SYNTAX_ERROR),
175  errmsg("conflicting or redundant options"),
176  parser_errposition(pstate, defel->location)));
177  dcreatedb = defel;
178  }
179  else if (strcmp(defel->defname, "canlogin") == 0)
180  {
181  if (dcanlogin)
182  ereport(ERROR,
183  (errcode(ERRCODE_SYNTAX_ERROR),
184  errmsg("conflicting or redundant options"),
185  parser_errposition(pstate, defel->location)));
186  dcanlogin = defel;
187  }
188  else if (strcmp(defel->defname, "isreplication") == 0)
189  {
190  if (disreplication)
191  ereport(ERROR,
192  (errcode(ERRCODE_SYNTAX_ERROR),
193  errmsg("conflicting or redundant options"),
194  parser_errposition(pstate, defel->location)));
195  disreplication = defel;
196  }
197  else if (strcmp(defel->defname, "connectionlimit") == 0)
198  {
199  if (dconnlimit)
200  ereport(ERROR,
201  (errcode(ERRCODE_SYNTAX_ERROR),
202  errmsg("conflicting or redundant options"),
203  parser_errposition(pstate, defel->location)));
204  dconnlimit = defel;
205  }
206  else if (strcmp(defel->defname, "addroleto") == 0)
207  {
208  if (daddroleto)
209  ereport(ERROR,
210  (errcode(ERRCODE_SYNTAX_ERROR),
211  errmsg("conflicting or redundant options"),
212  parser_errposition(pstate, defel->location)));
213  daddroleto = defel;
214  }
215  else if (strcmp(defel->defname, "rolemembers") == 0)
216  {
217  if (drolemembers)
218  ereport(ERROR,
219  (errcode(ERRCODE_SYNTAX_ERROR),
220  errmsg("conflicting or redundant options"),
221  parser_errposition(pstate, defel->location)));
222  drolemembers = defel;
223  }
224  else if (strcmp(defel->defname, "adminmembers") == 0)
225  {
226  if (dadminmembers)
227  ereport(ERROR,
228  (errcode(ERRCODE_SYNTAX_ERROR),
229  errmsg("conflicting or redundant options"),
230  parser_errposition(pstate, defel->location)));
231  dadminmembers = defel;
232  }
233  else if (strcmp(defel->defname, "validUntil") == 0)
234  {
235  if (dvalidUntil)
236  ereport(ERROR,
237  (errcode(ERRCODE_SYNTAX_ERROR),
238  errmsg("conflicting or redundant options"),
239  parser_errposition(pstate, defel->location)));
240  dvalidUntil = defel;
241  }
242  else if (strcmp(defel->defname, "bypassrls") == 0)
243  {
244  if (dbypassRLS)
245  ereport(ERROR,
246  (errcode(ERRCODE_SYNTAX_ERROR),
247  errmsg("conflicting or redundant options"),
248  parser_errposition(pstate, defel->location)));
249  dbypassRLS = defel;
250  }
251  else
252  elog(ERROR, "option \"%s\" not recognized",
253  defel->defname);
254  }
255 
256  if (dpassword && dpassword->arg)
257  password = strVal(dpassword->arg);
258  if (dissuper)
259  issuper = intVal(dissuper->arg) != 0;
260  if (dinherit)
261  inherit = intVal(dinherit->arg) != 0;
262  if (dcreaterole)
263  createrole = intVal(dcreaterole->arg) != 0;
264  if (dcreatedb)
265  createdb = intVal(dcreatedb->arg) != 0;
266  if (dcanlogin)
267  canlogin = intVal(dcanlogin->arg) != 0;
268  if (disreplication)
269  isreplication = intVal(disreplication->arg) != 0;
270  if (dconnlimit)
271  {
272  connlimit = intVal(dconnlimit->arg);
273  if (connlimit < -1)
274  ereport(ERROR,
275  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
276  errmsg("invalid connection limit: %d", connlimit)));
277  }
278  if (daddroleto)
279  addroleto = (List *) daddroleto->arg;
280  if (drolemembers)
281  rolemembers = (List *) drolemembers->arg;
282  if (dadminmembers)
283  adminmembers = (List *) dadminmembers->arg;
284  if (dvalidUntil)
285  validUntil = strVal(dvalidUntil->arg);
286  if (dbypassRLS)
287  bypassrls = intVal(dbypassRLS->arg) != 0;
288 
289  /* Check some permissions first */
290  if (issuper)
291  {
292  if (!superuser())
293  ereport(ERROR,
294  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
295  errmsg("must be superuser to create superusers")));
296  }
297  else if (isreplication)
298  {
299  if (!superuser())
300  ereport(ERROR,
301  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
302  errmsg("must be superuser to create replication users")));
303  }
304  else if (bypassrls)
305  {
306  if (!superuser())
307  ereport(ERROR,
308  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
309  errmsg("must be superuser to change bypassrls attribute")));
310  }
311  else
312  {
314  ereport(ERROR,
315  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
316  errmsg("permission denied to create role")));
317  }
318 
319  /*
320  * Check that the user is not trying to create a role in the reserved
321  * "pg_" namespace.
322  */
323  if (IsReservedName(stmt->role))
324  ereport(ERROR,
325  (errcode(ERRCODE_RESERVED_NAME),
326  errmsg("role name \"%s\" is reserved",
327  stmt->role),
328  errdetail("Role names starting with \"pg_\" are reserved.")));
329 
330  /*
331  * Check the pg_authid relation to be certain the role doesn't already
332  * exist.
333  */
334  pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
335  pg_authid_dsc = RelationGetDescr(pg_authid_rel);
336 
337  if (OidIsValid(get_role_oid(stmt->role, true)))
338  ereport(ERROR,
340  errmsg("role \"%s\" already exists",
341  stmt->role)));
342 
343  /* Convert validuntil to internal form */
344  if (validUntil)
345  {
346  validUntil_datum = DirectFunctionCall3(timestamptz_in,
347  CStringGetDatum(validUntil),
349  Int32GetDatum(-1));
350  validUntil_null = false;
351  }
352  else
353  {
354  validUntil_datum = (Datum) 0;
355  validUntil_null = true;
356  }
357 
358  /*
359  * Call the password checking hook if there is one defined
360  */
361  if (check_password_hook && password)
362  (*check_password_hook) (stmt->role,
363  password,
364  get_password_type(password),
365  validUntil_datum,
366  validUntil_null);
367 
368  /*
369  * Build a tuple to insert
370  */
371  MemSet(new_record, 0, sizeof(new_record));
372  MemSet(new_record_nulls, false, sizeof(new_record_nulls));
373 
374  new_record[Anum_pg_authid_rolname - 1] =
376 
377  new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper);
378  new_record[Anum_pg_authid_rolinherit - 1] = BoolGetDatum(inherit);
379  new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole);
380  new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb);
381  new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin);
382  new_record[Anum_pg_authid_rolreplication - 1] = BoolGetDatum(isreplication);
383  new_record[Anum_pg_authid_rolconnlimit - 1] = Int32GetDatum(connlimit);
384 
385  if (password)
386  {
387  char *shadow_pass;
388  char *logdetail;
389 
390  /*
391  * Don't allow an empty password. Libpq treats an empty password the
392  * same as no password at all, and won't even try to authenticate. But
393  * other clients might, so allowing it would be confusing. By clearing
394  * the password when an empty string is specified, the account is
395  * consistently locked for all clients.
396  *
397  * Note that this only covers passwords stored in the database itself.
398  * There are also checks in the authentication code, to forbid an
399  * empty password from being used with authentication methods that
400  * fetch the password from an external system, like LDAP or PAM.
401  */
402  if (password[0] == '\0' ||
403  plain_crypt_verify(stmt->role, password, "", &logdetail) == STATUS_OK)
404  {
405  ereport(NOTICE,
406  (errmsg("empty string is not a valid password, clearing password")));
407  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
408  }
409  else
410  {
411  /* Encrypt the password to the requested format. */
412  shadow_pass = encrypt_password(Password_encryption, stmt->role,
413  password);
414  new_record[Anum_pg_authid_rolpassword - 1] =
415  CStringGetTextDatum(shadow_pass);
416  }
417  }
418  else
419  new_record_nulls[Anum_pg_authid_rolpassword - 1] = true;
420 
421  new_record[Anum_pg_authid_rolvaliduntil - 1] = validUntil_datum;
422  new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = validUntil_null;
423 
424  new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls);
425 
426  tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls);
427 
428  /*
429  * pg_largeobject_metadata contains pg_authid.oid's, so we use the
430  * binary-upgrade override.
431  */
432  if (IsBinaryUpgrade)
433  {
435  ereport(ERROR,
436  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
437  errmsg("pg_authid OID value not set when in binary upgrade mode")));
438 
441  }
442 
443  /*
444  * Insert new record in the pg_authid table
445  */
446  roleid = CatalogTupleInsert(pg_authid_rel, tuple);
447 
448  /*
449  * Advance command counter so we can see new record; else tests in
450  * AddRoleMems may fail.
451  */
452  if (addroleto || adminmembers || rolemembers)
454 
455  /*
456  * Add the new role to the specified existing roles.
457  */
458  foreach(item, addroleto)
459  {
460  RoleSpec *oldrole = lfirst(item);
461  HeapTuple oldroletup = get_rolespec_tuple(oldrole);
462  Oid oldroleid = HeapTupleGetOid(oldroletup);
463  char *oldrolename = NameStr(((Form_pg_authid) GETSTRUCT(oldroletup))->rolname);
464 
465  AddRoleMems(oldrolename, oldroleid,
466  list_make1(makeString(stmt->role)),
467  list_make1_oid(roleid),
468  GetUserId(), false);
469 
470  ReleaseSysCache(oldroletup);
471  }
472 
473  /*
474  * Add the specified members to this new role. adminmembers get the admin
475  * option, rolemembers don't.
476  */
477  AddRoleMems(stmt->role, roleid,
478  adminmembers, roleSpecsToIds(adminmembers),
479  GetUserId(), true);
480  AddRoleMems(stmt->role, roleid,
481  rolemembers, roleSpecsToIds(rolemembers),
482  GetUserId(), false);
483 
484  /* Post creation hook for new role */
486 
487  /*
488  * Close pg_authid, but keep lock till commit.
489  */
490  heap_close(pg_authid_rel, NoLock);
491 
492  return roleid;
493 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:69
static char password[100]
Definition: streamutil.c:42
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:428
Oid GetUserId(void)
Definition: miscinit.c:284
int Password_encryption
Definition: user.c:47
RoleStmtType stmt_type
Definition: parsenodes.h:2426
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:91
#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:858
#define Anum_pg_authid_rolpassword
Definition: pg_authid.h:88
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:695
#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:584
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:194
#define OidIsValid(objectId)
Definition: c.h:538
bool IsBinaryUpgrade
Definition: globals.c:102
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:139
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:1425
#define NoLock
Definition: lockdefs.h:34
#define Anum_pg_authid_rolsuper
Definition: pg_authid.h:80
int location
Definition: parsenodes.h:722
#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 STATUS_OK
Definition: c.h:976
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:588
Node * arg
Definition: parsenodes.h:720
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, char **logdetail)
Definition: crypt.c:216
#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:1117
#define list_make1_oid(x1)
Definition: pg_list.h:151
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#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:108
#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:1396
#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:111
#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:383
#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:719
#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:32
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 1333 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().

1334 {
1335  List *role_ids = roleSpecsToIds(stmt->roles);
1336  ListCell *cell;
1337 
1338  /* Check privileges */
1339  foreach(cell, role_ids)
1340  {
1341  Oid roleid = lfirst_oid(cell);
1342 
1343  if (!has_privs_of_role(GetUserId(), roleid))
1344  ereport(ERROR,
1345  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1346  errmsg("permission denied to drop objects")));
1347  }
1348 
1349  /* Ok, do it */
1350  shdepDropOwned(role_ids, stmt->behavior);
1351 }
void shdepDropOwned(List *roleids, DropBehavior behavior)
Definition: pg_shdepend.c:1163
Oid GetUserId(void)
Definition: miscinit.c:284
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:3315
#define ereport(elevel, rest)
Definition: elog.h:122
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1396
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 966 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().

967 {
968  Relation pg_authid_rel,
969  pg_auth_members_rel;
970  ListCell *item;
971 
973  ereport(ERROR,
974  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
975  errmsg("permission denied to drop role")));
976 
977  /*
978  * Scan the pg_authid relation to find the Oid of the role(s) to be
979  * deleted.
980  */
981  pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock);
982  pg_auth_members_rel = heap_open(AuthMemRelationId, RowExclusiveLock);
983 
984  foreach(item, stmt->roles)
985  {
986  RoleSpec *rolspec = lfirst(item);
987  char *role;
988  HeapTuple tuple,
989  tmp_tuple;
990  ScanKeyData scankey;
991  char *detail;
992  char *detail_log;
993  SysScanDesc sscan;
994  Oid roleid;
995 
996  if (rolspec->roletype != ROLESPEC_CSTRING)
997  ereport(ERROR,
998  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
999  errmsg("cannot use special role specifier in DROP ROLE")));
1000  role = rolspec->rolename;
1001 
1002  tuple = SearchSysCache1(AUTHNAME, PointerGetDatum(role));
1003  if (!HeapTupleIsValid(tuple))
1004  {
1005  if (!stmt->missing_ok)
1006  {
1007  ereport(ERROR,
1008  (errcode(ERRCODE_UNDEFINED_OBJECT),
1009  errmsg("role \"%s\" does not exist", role)));
1010  }
1011  else
1012  {
1013  ereport(NOTICE,
1014  (errmsg("role \"%s\" does not exist, skipping",
1015  role)));
1016  }
1017 
1018  continue;
1019  }
1020 
1021  roleid = HeapTupleGetOid(tuple);
1022 
1023  if (roleid == GetUserId())
1024  ereport(ERROR,
1025  (errcode(ERRCODE_OBJECT_IN_USE),
1026  errmsg("current user cannot be dropped")));
1027  if (roleid == GetOuterUserId())
1028  ereport(ERROR,
1029  (errcode(ERRCODE_OBJECT_IN_USE),
1030  errmsg("current user cannot be dropped")));
1031  if (roleid == GetSessionUserId())
1032  ereport(ERROR,
1033  (errcode(ERRCODE_OBJECT_IN_USE),
1034  errmsg("session user cannot be dropped")));
1035 
1036  /*
1037  * For safety's sake, we allow createrole holders to drop ordinary
1038  * roles but not superuser roles. This is mainly to avoid the
1039  * scenario where you accidentally drop the last superuser.
1040  */
1041  if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper &&
1042  !superuser())
1043  ereport(ERROR,
1044  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1045  errmsg("must be superuser to drop superusers")));
1046 
1047  /* DROP hook for the role being removed */
1049 
1050  /*
1051  * Lock the role, so nobody can add dependencies to her while we drop
1052  * her. We keep the lock until the end of transaction.
1053  */
1055 
1056  /* Check for pg_shdepend entries depending on this role */
1058  &detail, &detail_log))
1059  ereport(ERROR,
1060  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1061  errmsg("role \"%s\" cannot be dropped because some objects depend on it",
1062  role),
1063  errdetail_internal("%s", detail),
1064  errdetail_log("%s", detail_log)));
1065 
1066  /*
1067  * Remove the role from the pg_authid table
1068  */
1069  CatalogTupleDelete(pg_authid_rel, &tuple->t_self);
1070 
1071  ReleaseSysCache(tuple);
1072 
1073  /*
1074  * Remove role from the pg_auth_members table. We have to remove all
1075  * tuples that show it as either a role or a member.
1076  *
1077  * XXX what about grantor entries? Maybe we should do one heap scan.
1078  */
1079  ScanKeyInit(&scankey,
1081  BTEqualStrategyNumber, F_OIDEQ,
1082  ObjectIdGetDatum(roleid));
1083 
1084  sscan = systable_beginscan(pg_auth_members_rel, AuthMemRoleMemIndexId,
1085  true, NULL, 1, &scankey);
1086 
1087  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1088  {
1089  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1090  }
1091 
1092  systable_endscan(sscan);
1093 
1094  ScanKeyInit(&scankey,
1096  BTEqualStrategyNumber, F_OIDEQ,
1097  ObjectIdGetDatum(roleid));
1098 
1099  sscan = systable_beginscan(pg_auth_members_rel, AuthMemMemRoleIndexId,
1100  true, NULL, 1, &scankey);
1101 
1102  while (HeapTupleIsValid(tmp_tuple = systable_getnext(sscan)))
1103  {
1104  CatalogTupleDelete(pg_auth_members_rel, &tmp_tuple->t_self);
1105  }
1106 
1107  systable_endscan(sscan);
1108 
1109  /*
1110  * Remove any comments or security labels on this role.
1111  */
1114 
1115  /*
1116  * Remove settings for this role.
1117  */
1118  DropSetting(InvalidOid, roleid);
1119 
1120  /*
1121  * Advance command counter so that later iterations of this loop will
1122  * see the changes already made. This is essential if, for example,
1123  * we are trying to drop both a role and one of its direct members ---
1124  * we'll get an error if we try to delete the linking pg_auth_members
1125  * tuple twice. (We do not need a CCI between the two delete loops
1126  * above, because it's not allowed for a role to directly contain
1127  * itself.)
1128  */
1130  }
1131 
1132  /*
1133  * Now we can clean up; but keep locks until commit.
1134  */
1135  heap_close(pg_auth_members_rel, NoLock);
1136  heap_close(pg_authid_rel, NoLock);
1137 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Oid GetUserId(void)
Definition: miscinit.c:284
#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:2450
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:318
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:156
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:295
#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:1117
RoleSpecType roletype
Definition: parsenodes.h:327
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
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:373
#define AuthMemMemRoleIndexId
Definition: indexing.h:104
char * rolename
Definition: parsenodes.h:328
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition: seclabel.c:414
#define AccessExclusiveLock
Definition: lockdefs.h:45
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:522
#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 1274 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().

1275 {
1276  Relation pg_authid_rel;
1277  Oid grantor;
1278  List *grantee_ids;
1279  ListCell *item;
1280 
1281  if (stmt->grantor)
1282  grantor = get_rolespec_oid(stmt->grantor, false);
1283  else
1284  grantor = GetUserId();
1285 
1286  grantee_ids = roleSpecsToIds(stmt->grantee_roles);
1287 
1288  /* AccessShareLock is enough since we aren't modifying pg_authid */
1289  pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
1290 
1291  /*
1292  * Step through all of the granted roles and add/remove entries for the
1293  * grantees, or, if admin_opt is set, then just add/remove the admin
1294  * option.
1295  *
1296  * Note: Permissions checking is done by AddRoleMems/DelRoleMems
1297  */
1298  foreach(item, stmt->granted_roles)
1299  {
1300  AccessPriv *priv = (AccessPriv *) lfirst(item);
1301  char *rolename = priv->priv_name;
1302  Oid roleid;
1303 
1304  /* Must reject priv(columns) and ALL PRIVILEGES(columns) */
1305  if (rolename == NULL || priv->cols != NIL)
1306  ereport(ERROR,
1307  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1308  errmsg("column names cannot be included in GRANT/REVOKE ROLE")));
1309 
1310  roleid = get_role_oid(rolename, false);
1311  if (stmt->is_grant)
1312  AddRoleMems(rolename, roleid,
1313  stmt->grantee_roles, grantee_ids,
1314  grantor, stmt->admin_opt);
1315  else
1316  DelRoleMems(rolename, roleid,
1317  stmt->grantee_roles, grantee_ids,
1318  stmt->admin_opt);
1319  }
1320 
1321  /*
1322  * Close pg_authid, but keep lock till commit.
1323  */
1324  heap_close(pg_authid_rel, NoLock);
1325 }
#define NIL
Definition: pg_list.h:69
Oid GetUserId(void)
Definition: miscinit.c:284
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
List * granted_roles
Definition: parsenodes.h:1904
#define heap_close(r, l)
Definition: heapam.h:97
List * cols
Definition: parsenodes.h:1889
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:1425
#define NoLock
Definition: lockdefs.h:34
#define ereport(elevel, rest)
Definition: elog.h:122
RoleSpec * grantor
Definition: parsenodes.h:1908
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5129
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
List * roleSpecsToIds(List *memberNames)
Definition: user.c:1396
#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:1905
Definition: pg_list.h:45
char * priv_name
Definition: parsenodes.h:1888
static void DelRoleMems(const char *rolename, Oid roleid, List *memberSpecs, List *memberIds, bool admin_opt)
Definition: user.c:1569
void ReassignOwnedObjects ( ReassignOwnedStmt stmt)

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

1360 {
1361  List *role_ids = roleSpecsToIds(stmt->roles);
1362  ListCell *cell;
1363  Oid newrole;
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 reassign objects")));
1374  }
1375 
1376  /* Must have privileges on the receiving side too */
1377  newrole = get_rolespec_oid(stmt->newrole, false);
1378 
1379  if (!has_privs_of_role(GetUserId(), newrole))
1380  ereport(ERROR,
1381  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1382  errmsg("permission denied to reassign objects")));
1383 
1384  /* Ok, do it */
1385  shdepReassignOwned(role_ids, newrole);
1386 }
Oid GetUserId(void)
Definition: miscinit.c:284
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:1285
#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:1396
RoleSpec * newrole
Definition: parsenodes.h:3325
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 1143 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().

1144 {
1145  HeapTuple oldtuple,
1146  newtuple;
1147  TupleDesc dsc;
1148  Relation rel;
1149  Datum datum;
1150  bool isnull;
1151  Datum repl_val[Natts_pg_authid];
1152  bool repl_null[Natts_pg_authid];
1153  bool repl_repl[Natts_pg_authid];
1154  int i;
1155  Oid roleid;
1156  ObjectAddress address;
1157  Form_pg_authid authform;
1158 
1160  dsc = RelationGetDescr(rel);
1161 
1162  oldtuple = SearchSysCache1(AUTHNAME, CStringGetDatum(oldname));
1163  if (!HeapTupleIsValid(oldtuple))
1164  ereport(ERROR,
1165  (errcode(ERRCODE_UNDEFINED_OBJECT),
1166  errmsg("role \"%s\" does not exist", oldname)));
1167 
1168  /*
1169  * XXX Client applications probably store the session user somewhere, so
1170  * renaming it could cause confusion. On the other hand, there may not be
1171  * an actual problem besides a little confusion, so think about this and
1172  * decide. Same for SET ROLE ... we don't restrict renaming the current
1173  * effective userid, though.
1174  */
1175 
1176  roleid = HeapTupleGetOid(oldtuple);
1177  authform = (Form_pg_authid) GETSTRUCT(oldtuple);
1178 
1179  if (roleid == GetSessionUserId())
1180  ereport(ERROR,
1181  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1182  errmsg("session user cannot be renamed")));
1183  if (roleid == GetOuterUserId())
1184  ereport(ERROR,
1185  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1186  errmsg("current user cannot be renamed")));
1187 
1188  /*
1189  * Check that the user is not trying to rename a system role and not
1190  * trying to rename a role into the reserved "pg_" namespace.
1191  */
1192  if (IsReservedName(NameStr(authform->rolname)))
1193  ereport(ERROR,
1194  (errcode(ERRCODE_RESERVED_NAME),
1195  errmsg("role name \"%s\" is reserved",
1196  NameStr(authform->rolname)),
1197  errdetail("Role names starting with \"pg_\" are reserved.")));
1198 
1199  if (IsReservedName(newname))
1200  ereport(ERROR,
1201  (errcode(ERRCODE_RESERVED_NAME),
1202  errmsg("role name \"%s\" is reserved",
1203  newname),
1204  errdetail("Role names starting with \"pg_\" are reserved.")));
1205 
1206  /* make sure the new name doesn't exist */
1208  ereport(ERROR,
1210  errmsg("role \"%s\" already exists", newname)));
1211 
1212  /*
1213  * createrole is enough privilege unless you want to mess with a superuser
1214  */
1215  if (((Form_pg_authid) GETSTRUCT(oldtuple))->rolsuper)
1216  {
1217  if (!superuser())
1218  ereport(ERROR,
1219  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1220  errmsg("must be superuser to rename superusers")));
1221  }
1222  else
1223  {
1225  ereport(ERROR,
1226  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1227  errmsg("permission denied to rename role")));
1228  }
1229 
1230  /* OK, construct the modified tuple */
1231  for (i = 0; i < Natts_pg_authid; i++)
1232  repl_repl[i] = false;
1233 
1234  repl_repl[Anum_pg_authid_rolname - 1] = true;
1236  CStringGetDatum(newname));
1237  repl_null[Anum_pg_authid_rolname - 1] = false;
1238 
1239  datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull);
1240 
1241  if (!isnull && get_password_type(TextDatumGetCString(datum)) == PASSWORD_TYPE_MD5)
1242  {
1243  /* MD5 uses the username as salt, so just clear it on a rename */
1244  repl_repl[Anum_pg_authid_rolpassword - 1] = true;
1245  repl_null[Anum_pg_authid_rolpassword - 1] = true;
1246 
1247  ereport(NOTICE,
1248  (errmsg("MD5 password cleared because of role rename")));
1249  }
1250 
1251  newtuple = heap_modify_tuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
1252  CatalogTupleUpdate(rel, &oldtuple->t_self, newtuple);
1253 
1255 
1256  ObjectAddressSet(address, AuthIdRelationId, roleid);
1257 
1258  ReleaseSysCache(oldtuple);
1259 
1260  /*
1261  * Close pg_authid, but keep lock till commit.
1262  */
1263  heap_close(rel, NoLock);
1264 
1265  return address;
1266 }
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:46
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:428
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:91
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:584
unsigned int Oid
Definition: postgres_ext.h:31
bool IsReservedName(const char *name)
Definition: catalog.c:194
Oid GetSessionUserId(void)
Definition: miscinit.c:318
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#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:174
Oid GetOuterUserId(void)
Definition: miscinit.c:295
#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:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#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:794
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
#define Natts_pg_authid
Definition: pg_authid.h:78
List* roleSpecsToIds ( List memberNames)

Definition at line 1396 of file user.c.

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

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

1397 {
1398  List *result = NIL;
1399  ListCell *l;
1400 
1401  foreach(l, memberNames)
1402  {
1403  RoleSpec *rolespec = lfirst_node(RoleSpec, l);
1404  Oid roleid;
1405 
1406  roleid = get_rolespec_oid(rolespec, false);
1407  result = lappend_oid(result, roleid);
1408  }
1409  return result;
1410 }
#define NIL
Definition: pg_list.h:69
return result
Definition: formatting.c:1633
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define lfirst_node(type, lc)
Definition: pg_list.h:109
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5129
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(), CheckPWChallengeAuth(), and CreateRole().