PostgreSQL Source Code  git master
acl.h File Reference
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/snapshot.h"
Include dependency graph for acl.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

#define ACL_ID_PUBLIC   0 /* placeholder for id in a PUBLIC acl item */
 
#define ACLITEM_GET_PRIVS(item)   ((item).ai_privs & 0xFFFFFFFF)
 
#define ACLITEM_GET_GOPTIONS(item)   (((item).ai_privs >> 32) & 0xFFFFFFFF)
 
#define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
 
#define ACL_GRANT_OPTION_FOR(privs)   (((AclMode) (privs) & 0xFFFFFFFF) << 32)
 
#define ACL_OPTION_TO_PRIVS(privs)   (((AclMode) (privs) >> 32) & 0xFFFFFFFF)
 
#define ACLITEM_SET_PRIVS(item, privs)
 
#define ACLITEM_SET_GOPTIONS(item, goptions)
 
#define ACLITEM_SET_RIGHTS(item, rights)    ((item).ai_privs = (AclMode) (rights))
 
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
 
#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)
 
#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFFFFFF << 32)
 
#define ACL_NUM(ACL)   (ARR_DIMS(ACL)[0])
 
#define ACL_DAT(ACL)   ((AclItem *) ARR_DATA_PTR(ACL))
 
#define ACL_N_SIZE(N)   (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
 
#define ACL_SIZE(ACL)   ARR_SIZE(ACL)
 
#define DatumGetAclItemP(X)   ((AclItem *) DatumGetPointer(X))
 
#define PG_GETARG_ACLITEM_P(n)   DatumGetAclItemP(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ACLITEM_P(x)   PG_RETURN_POINTER(x)
 
#define DatumGetAclP(X)   ((Acl *) PG_DETOAST_DATUM(X))
 
#define DatumGetAclPCopy(X)   ((Acl *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_ACL_P(n)   DatumGetAclP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_ACL_P_COPY(n)   DatumGetAclPCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ACL_P(x)   PG_RETURN_POINTER(x)
 
#define ACL_MODECHG_ADD   1
 
#define ACL_MODECHG_DEL   2
 
#define ACL_MODECHG_EQL   3
 
#define ACL_INSERT_CHR   'a' /* formerly known as "append" */
 
#define ACL_SELECT_CHR   'r' /* formerly known as "read" */
 
#define ACL_UPDATE_CHR   'w' /* formerly known as "write" */
 
#define ACL_DELETE_CHR   'd'
 
#define ACL_TRUNCATE_CHR   'D' /* super-delete, as it were */
 
#define ACL_REFERENCES_CHR   'x'
 
#define ACL_TRIGGER_CHR   't'
 
#define ACL_EXECUTE_CHR   'X'
 
#define ACL_USAGE_CHR   'U'
 
#define ACL_CREATE_CHR   'C'
 
#define ACL_CREATE_TEMP_CHR   'T'
 
#define ACL_CONNECT_CHR   'c'
 
#define ACL_SET_CHR   's'
 
#define ACL_ALTER_SYSTEM_CHR   'A'
 
#define ACL_MAINTAIN_CHR   'm'
 
#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"
 
#define ACL_ALL_RIGHTS_COLUMN   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
 
#define ACL_ALL_RIGHTS_RELATION   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER|ACL_MAINTAIN)
 
#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
 
#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)
 
#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)
 
#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)
 

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

enum  AclMaskHow { ACLMASK_ALL , ACLMASK_ANY }
 
enum  AclResult { ACLCHECK_OK = 0 , ACLCHECK_NO_PRIV , ACLCHECK_NOT_OWNER }
 

Functions

Aclacldefault (ObjectType objtype, Oid ownerId)
 
Aclget_user_default_acl (ObjectType objtype, Oid ownerId, Oid nsp_oid)
 
void recordDependencyOnNewAcl (Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
 
Aclaclupdate (const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
 
Aclaclnewowner (const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
 
Aclmake_empty_acl (void)
 
Aclaclcopy (const Acl *orig_acl)
 
Aclaclconcat (const Acl *left_acl, const Acl *right_acl)
 
Aclaclmerge (const Acl *left_acl, const Acl *right_acl, Oid ownerId)
 
void aclitemsort (Acl *acl)
 
bool aclequal (const Acl *left_acl, const Acl *right_acl)
 
AclMode aclmask (const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
 
int aclmembers (const Acl *acl, Oid **roleids)
 
bool has_privs_of_role (Oid member, Oid role)
 
bool member_can_set_role (Oid member, Oid role)
 
void check_can_set_role (Oid member, Oid role)
 
bool is_member_of_role (Oid member, Oid role)
 
bool is_member_of_role_nosuper (Oid member, Oid role)
 
bool is_admin_of_role (Oid member, Oid role)
 
Oid select_best_admin (Oid member, Oid role)
 
Oid get_role_oid (const char *rolname, bool missing_ok)
 
Oid get_role_oid_or_public (const char *rolname)
 
Oid get_rolespec_oid (const RoleSpec *role, bool missing_ok)
 
void check_rolespec_name (const RoleSpec *role, const char *detail_msg)
 
HeapTuple get_rolespec_tuple (const RoleSpec *role)
 
char * get_rolespec_name (const RoleSpec *role)
 
void select_best_grantor (Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult object_aclcheck (Oid classid, Oid objectid, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_parameter_aclcheck (const char *name, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
bool object_ownercheck (Oid classid, Oid objectid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

#define ACL_ALL_RIGHTS_COLUMN   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 171 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

#define ACL_DAT (   ACL)    ((AclItem *) ARR_DATA_PTR(ACL))

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

#define ACL_GRANT_OPTION_FOR (   privs)    (((AclMode) (privs) & 0xFFFFFFFF) << 32)

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

#define ACL_ID_PUBLIC   0 /* placeholder for id in a PUBLIC acl item */

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

#define ACL_INSERT_CHR   'a' /* formerly known as "append" */

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

#define ACL_N_SIZE (   N)    (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))

Definition at line 110 of file acl.h.

◆ ACL_NUM

#define ACL_NUM (   ACL)    (ARR_DIMS(ACL)[0])

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

#define ACL_OPTION_TO_PRIVS (   privs)    (((AclMode) (privs) >> 32) & 0xFFFFFFFF)

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

#define ACL_SELECT_CHR   'r' /* formerly known as "read" */

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

#define ACL_TRUNCATE_CHR   'D' /* super-delete, as it were */

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

#define ACL_UPDATE_CHR   'w' /* formerly known as "write" */

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFFFFFF << 32)

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

#define ACLITEM_GET_GOPTIONS (   item)    (((item).ai_privs >> 32) & 0xFFFFFFFF)

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

#define ACLITEM_GET_PRIVS (   item)    ((item).ai_privs & 0xFFFFFFFF)

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

#define ACLITEM_GET_RIGHTS (   item)    ((item).ai_privs)

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

#define ACLITEM_SET_GOPTIONS (   item,
  goptions 
)
Value:
((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFFFFFF) << 32)) | \
(((AclMode) (goptions) & 0xFFFFFFFF) << 32))
uint64 AclMode
Definition: parsenodes.h:81

Definition at line 76 of file acl.h.

◆ ACLITEM_SET_PRIVS

#define ACLITEM_SET_PRIVS (   item,
  privs 
)
Value:
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFFFFFF)) | \
((AclMode) (privs) & 0xFFFFFFFF))

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

#define ACLITEM_SET_PRIVS_GOPTIONS (   item,
  privs,
  goptions 
)
Value:
((item).ai_privs = ((AclMode) (privs) & 0xFFFFFFFF) | \
(((AclMode) (goptions) & 0xFFFFFFFF) << 32))

Definition at line 82 of file acl.h.

◆ ACLITEM_SET_RIGHTS

#define ACLITEM_SET_RIGHTS (   item,
  rights 
)     ((item).ai_privs = (AclMode) (rights))

Definition at line 79 of file acl.h.

◆ DatumGetAclItemP

#define DatumGetAclItemP (   X)    ((AclItem *) DatumGetPointer(X))

Definition at line 116 of file acl.h.

◆ DatumGetAclP

#define DatumGetAclP (   X)    ((Acl *) PG_DETOAST_DATUM(X))

Definition at line 120 of file acl.h.

◆ DatumGetAclPCopy

#define DatumGetAclPCopy (   X)    ((Acl *) PG_DETOAST_DATUM_COPY(X))

Definition at line 121 of file acl.h.

◆ PG_GETARG_ACL_P

#define PG_GETARG_ACL_P (   n)    DatumGetAclP(PG_GETARG_DATUM(n))

Definition at line 122 of file acl.h.

◆ PG_GETARG_ACL_P_COPY

#define PG_GETARG_ACL_P_COPY (   n)    DatumGetAclPCopy(PG_GETARG_DATUM(n))

Definition at line 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

#define PG_GETARG_ACLITEM_P (   n)    DatumGetAclItemP(PG_GETARG_DATUM(n))

Definition at line 117 of file acl.h.

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 124 of file acl.h.

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 118 of file acl.h.

Typedef Documentation

◆ Acl

typedef struct ArrayType Acl

Definition at line 1 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 174 of file acl.h.

175 {
176  ACLMASK_ALL, /* normal case: compute all bits */
177  ACLMASK_ANY /* return when result is known nonzero */
178 } AclMaskHow;
AclMaskHow
Definition: acl.h:175
@ ACLMASK_ANY
Definition: acl.h:177
@ ACLMASK_ALL
Definition: acl.h:176

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 181 of file acl.h.

182 {
183  ACLCHECK_OK = 0,
186 } AclResult;
AclResult
Definition: acl.h:182
@ ACLCHECK_NO_PRIV
Definition: acl.h:184
@ ACLCHECK_OK
Definition: acl.h:183
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185

Function Documentation

◆ aclcheck_error()

void aclcheck_error ( AclResult  aclerr,
ObjectType  objtype,
const char *  objectname 
)

Definition at line 2673 of file aclchk.c.

2675 {
2676  switch (aclerr)
2677  {
2678  case ACLCHECK_OK:
2679  /* no error, so return to caller */
2680  break;
2681  case ACLCHECK_NO_PRIV:
2682  {
2683  const char *msg = "???";
2684 
2685  switch (objtype)
2686  {
2687  case OBJECT_AGGREGATE:
2688  msg = gettext_noop("permission denied for aggregate %s");
2689  break;
2690  case OBJECT_COLLATION:
2691  msg = gettext_noop("permission denied for collation %s");
2692  break;
2693  case OBJECT_COLUMN:
2694  msg = gettext_noop("permission denied for column %s");
2695  break;
2696  case OBJECT_CONVERSION:
2697  msg = gettext_noop("permission denied for conversion %s");
2698  break;
2699  case OBJECT_DATABASE:
2700  msg = gettext_noop("permission denied for database %s");
2701  break;
2702  case OBJECT_DOMAIN:
2703  msg = gettext_noop("permission denied for domain %s");
2704  break;
2705  case OBJECT_EVENT_TRIGGER:
2706  msg = gettext_noop("permission denied for event trigger %s");
2707  break;
2708  case OBJECT_EXTENSION:
2709  msg = gettext_noop("permission denied for extension %s");
2710  break;
2711  case OBJECT_FDW:
2712  msg = gettext_noop("permission denied for foreign-data wrapper %s");
2713  break;
2714  case OBJECT_FOREIGN_SERVER:
2715  msg = gettext_noop("permission denied for foreign server %s");
2716  break;
2717  case OBJECT_FOREIGN_TABLE:
2718  msg = gettext_noop("permission denied for foreign table %s");
2719  break;
2720  case OBJECT_FUNCTION:
2721  msg = gettext_noop("permission denied for function %s");
2722  break;
2723  case OBJECT_INDEX:
2724  msg = gettext_noop("permission denied for index %s");
2725  break;
2726  case OBJECT_LANGUAGE:
2727  msg = gettext_noop("permission denied for language %s");
2728  break;
2729  case OBJECT_LARGEOBJECT:
2730  msg = gettext_noop("permission denied for large object %s");
2731  break;
2732  case OBJECT_MATVIEW:
2733  msg = gettext_noop("permission denied for materialized view %s");
2734  break;
2735  case OBJECT_OPCLASS:
2736  msg = gettext_noop("permission denied for operator class %s");
2737  break;
2738  case OBJECT_OPERATOR:
2739  msg = gettext_noop("permission denied for operator %s");
2740  break;
2741  case OBJECT_OPFAMILY:
2742  msg = gettext_noop("permission denied for operator family %s");
2743  break;
2744  case OBJECT_PARAMETER_ACL:
2745  msg = gettext_noop("permission denied for parameter %s");
2746  break;
2747  case OBJECT_POLICY:
2748  msg = gettext_noop("permission denied for policy %s");
2749  break;
2750  case OBJECT_PROCEDURE:
2751  msg = gettext_noop("permission denied for procedure %s");
2752  break;
2753  case OBJECT_PUBLICATION:
2754  msg = gettext_noop("permission denied for publication %s");
2755  break;
2756  case OBJECT_ROUTINE:
2757  msg = gettext_noop("permission denied for routine %s");
2758  break;
2759  case OBJECT_SCHEMA:
2760  msg = gettext_noop("permission denied for schema %s");
2761  break;
2762  case OBJECT_SEQUENCE:
2763  msg = gettext_noop("permission denied for sequence %s");
2764  break;
2765  case OBJECT_STATISTIC_EXT:
2766  msg = gettext_noop("permission denied for statistics object %s");
2767  break;
2768  case OBJECT_SUBSCRIPTION:
2769  msg = gettext_noop("permission denied for subscription %s");
2770  break;
2771  case OBJECT_TABLE:
2772  msg = gettext_noop("permission denied for table %s");
2773  break;
2774  case OBJECT_TABLESPACE:
2775  msg = gettext_noop("permission denied for tablespace %s");
2776  break;
2778  msg = gettext_noop("permission denied for text search configuration %s");
2779  break;
2780  case OBJECT_TSDICTIONARY:
2781  msg = gettext_noop("permission denied for text search dictionary %s");
2782  break;
2783  case OBJECT_TYPE:
2784  msg = gettext_noop("permission denied for type %s");
2785  break;
2786  case OBJECT_VIEW:
2787  msg = gettext_noop("permission denied for view %s");
2788  break;
2789  /* these currently aren't used */
2790  case OBJECT_ACCESS_METHOD:
2791  case OBJECT_AMOP:
2792  case OBJECT_AMPROC:
2793  case OBJECT_ATTRIBUTE:
2794  case OBJECT_CAST:
2795  case OBJECT_DEFAULT:
2796  case OBJECT_DEFACL:
2797  case OBJECT_DOMCONSTRAINT:
2800  case OBJECT_ROLE:
2801  case OBJECT_RULE:
2802  case OBJECT_TABCONSTRAINT:
2803  case OBJECT_TRANSFORM:
2804  case OBJECT_TRIGGER:
2805  case OBJECT_TSPARSER:
2806  case OBJECT_TSTEMPLATE:
2807  case OBJECT_USER_MAPPING:
2808  elog(ERROR, "unsupported object type: %d", objtype);
2809  }
2810 
2811  ereport(ERROR,
2812  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2813  errmsg(msg, objectname)));
2814  break;
2815  }
2816  case ACLCHECK_NOT_OWNER:
2817  {
2818  const char *msg = "???";
2819 
2820  switch (objtype)
2821  {
2822  case OBJECT_AGGREGATE:
2823  msg = gettext_noop("must be owner of aggregate %s");
2824  break;
2825  case OBJECT_COLLATION:
2826  msg = gettext_noop("must be owner of collation %s");
2827  break;
2828  case OBJECT_CONVERSION:
2829  msg = gettext_noop("must be owner of conversion %s");
2830  break;
2831  case OBJECT_DATABASE:
2832  msg = gettext_noop("must be owner of database %s");
2833  break;
2834  case OBJECT_DOMAIN:
2835  msg = gettext_noop("must be owner of domain %s");
2836  break;
2837  case OBJECT_EVENT_TRIGGER:
2838  msg = gettext_noop("must be owner of event trigger %s");
2839  break;
2840  case OBJECT_EXTENSION:
2841  msg = gettext_noop("must be owner of extension %s");
2842  break;
2843  case OBJECT_FDW:
2844  msg = gettext_noop("must be owner of foreign-data wrapper %s");
2845  break;
2846  case OBJECT_FOREIGN_SERVER:
2847  msg = gettext_noop("must be owner of foreign server %s");
2848  break;
2849  case OBJECT_FOREIGN_TABLE:
2850  msg = gettext_noop("must be owner of foreign table %s");
2851  break;
2852  case OBJECT_FUNCTION:
2853  msg = gettext_noop("must be owner of function %s");
2854  break;
2855  case OBJECT_INDEX:
2856  msg = gettext_noop("must be owner of index %s");
2857  break;
2858  case OBJECT_LANGUAGE:
2859  msg = gettext_noop("must be owner of language %s");
2860  break;
2861  case OBJECT_LARGEOBJECT:
2862  msg = gettext_noop("must be owner of large object %s");
2863  break;
2864  case OBJECT_MATVIEW:
2865  msg = gettext_noop("must be owner of materialized view %s");
2866  break;
2867  case OBJECT_OPCLASS:
2868  msg = gettext_noop("must be owner of operator class %s");
2869  break;
2870  case OBJECT_OPERATOR:
2871  msg = gettext_noop("must be owner of operator %s");
2872  break;
2873  case OBJECT_OPFAMILY:
2874  msg = gettext_noop("must be owner of operator family %s");
2875  break;
2876  case OBJECT_PROCEDURE:
2877  msg = gettext_noop("must be owner of procedure %s");
2878  break;
2879  case OBJECT_PUBLICATION:
2880  msg = gettext_noop("must be owner of publication %s");
2881  break;
2882  case OBJECT_ROUTINE:
2883  msg = gettext_noop("must be owner of routine %s");
2884  break;
2885  case OBJECT_SEQUENCE:
2886  msg = gettext_noop("must be owner of sequence %s");
2887  break;
2888  case OBJECT_SUBSCRIPTION:
2889  msg = gettext_noop("must be owner of subscription %s");
2890  break;
2891  case OBJECT_TABLE:
2892  msg = gettext_noop("must be owner of table %s");
2893  break;
2894  case OBJECT_TYPE:
2895  msg = gettext_noop("must be owner of type %s");
2896  break;
2897  case OBJECT_VIEW:
2898  msg = gettext_noop("must be owner of view %s");
2899  break;
2900  case OBJECT_SCHEMA:
2901  msg = gettext_noop("must be owner of schema %s");
2902  break;
2903  case OBJECT_STATISTIC_EXT:
2904  msg = gettext_noop("must be owner of statistics object %s");
2905  break;
2906  case OBJECT_TABLESPACE:
2907  msg = gettext_noop("must be owner of tablespace %s");
2908  break;
2910  msg = gettext_noop("must be owner of text search configuration %s");
2911  break;
2912  case OBJECT_TSDICTIONARY:
2913  msg = gettext_noop("must be owner of text search dictionary %s");
2914  break;
2915 
2916  /*
2917  * Special cases: For these, the error message talks
2918  * about "relation", because that's where the
2919  * ownership is attached. See also
2920  * check_object_ownership().
2921  */
2922  case OBJECT_COLUMN:
2923  case OBJECT_POLICY:
2924  case OBJECT_RULE:
2925  case OBJECT_TABCONSTRAINT:
2926  case OBJECT_TRIGGER:
2927  msg = gettext_noop("must be owner of relation %s");
2928  break;
2929  /* these currently aren't used */
2930  case OBJECT_ACCESS_METHOD:
2931  case OBJECT_AMOP:
2932  case OBJECT_AMPROC:
2933  case OBJECT_ATTRIBUTE:
2934  case OBJECT_CAST:
2935  case OBJECT_DEFAULT:
2936  case OBJECT_DEFACL:
2937  case OBJECT_DOMCONSTRAINT:
2938  case OBJECT_PARAMETER_ACL:
2941  case OBJECT_ROLE:
2942  case OBJECT_TRANSFORM:
2943  case OBJECT_TSPARSER:
2944  case OBJECT_TSTEMPLATE:
2945  case OBJECT_USER_MAPPING:
2946  elog(ERROR, "unsupported object type: %d", objtype);
2947  }
2948 
2949  ereport(ERROR,
2950  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2951  errmsg(msg, objectname)));
2952  break;
2953  }
2954  default:
2955  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2956  break;
2957  }
2958 }
#define gettext_noop(x)
Definition: c.h:1186
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2096
@ OBJECT_FDW
Definition: parsenodes.h:2098
@ OBJECT_TSPARSER
Definition: parsenodes.h:2129
@ OBJECT_COLLATION
Definition: parsenodes.h:2089
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2132
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2082
@ OBJECT_OPCLASS
Definition: parsenodes.h:2106
@ OBJECT_DEFACL
Definition: parsenodes.h:2093
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2083
@ OBJECT_MATVIEW
Definition: parsenodes.h:2105
@ OBJECT_SCHEMA
Definition: parsenodes.h:2118
@ OBJECT_POLICY
Definition: parsenodes.h:2110
@ OBJECT_OPERATOR
Definition: parsenodes.h:2107
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2100
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2127
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2108
@ OBJECT_DOMAIN
Definition: parsenodes.h:2094
@ OBJECT_COLUMN
Definition: parsenodes.h:2088
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2124
@ OBJECT_ROLE
Definition: parsenodes.h:2115
@ OBJECT_ROUTINE
Definition: parsenodes.h:2116
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2104
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2113
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2111
@ OBJECT_EXTENSION
Definition: parsenodes.h:2097
@ OBJECT_INDEX
Definition: parsenodes.h:2102
@ OBJECT_DEFAULT
Definition: parsenodes.h:2092
@ OBJECT_DATABASE
Definition: parsenodes.h:2091
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2119
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2130
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2103
@ OBJECT_AMOP
Definition: parsenodes.h:2084
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2114
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2099
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2128
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2086
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2112
@ OBJECT_RULE
Definition: parsenodes.h:2117
@ OBJECT_CONVERSION
Definition: parsenodes.h:2090
@ OBJECT_AMPROC
Definition: parsenodes.h:2085
@ OBJECT_TABLE
Definition: parsenodes.h:2123
@ OBJECT_VIEW
Definition: parsenodes.h:2133
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2109
@ OBJECT_TYPE
Definition: parsenodes.h:2131
@ OBJECT_FUNCTION
Definition: parsenodes.h:2101
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2122
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2095
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2120
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2121
@ OBJECT_CAST
Definition: parsenodes.h:2087
@ OBJECT_TRIGGER
Definition: parsenodes.h:2126
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2125

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog(), ereport, errcode(), errmsg(), ERROR, gettext_noop, OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), currtid_internal(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecCheckPermissions(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), get_rel_from_relname(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_prewarm(), pgrowlocks(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackMaintainsTable(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

void aclcheck_error_col ( AclResult  aclerr,
ObjectType  objtype,
const char *  objectname,
const char *  colname 
)

Definition at line 2962 of file aclchk.c.

2964 {
2965  switch (aclerr)
2966  {
2967  case ACLCHECK_OK:
2968  /* no error, so return to caller */
2969  break;
2970  case ACLCHECK_NO_PRIV:
2971  ereport(ERROR,
2972  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2973  errmsg("permission denied for column \"%s\" of relation \"%s\"",
2974  colname, objectname)));
2975  break;
2976  case ACLCHECK_NOT_OWNER:
2977  /* relation msg is OK since columns don't have separate owners */
2978  aclcheck_error(aclerr, objtype, objectname);
2979  break;
2980  default:
2981  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2982  break;
2983  }
2984 }
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2673

References aclcheck_error(), ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog(), ereport, errcode(), errmsg(), and ERROR.

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

◆ aclconcat()

Acl* aclconcat ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 454 of file acl.c.

455 {
456  Acl *result_acl;
457 
458  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
459 
460  memcpy(ACL_DAT(result_acl),
461  ACL_DAT(left_acl),
462  ACL_NUM(left_acl) * sizeof(AclItem));
463 
464  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
465  ACL_DAT(right_acl),
466  ACL_NUM(right_acl) * sizeof(AclItem));
467 
468  return result_acl;
469 }
static Acl * allocacl(int n)
Definition: acl.c:403
#define ACL_DAT(ACL)
Definition: acl.h:109
#define ACL_NUM(ACL)
Definition: acl.h:108
Definition: acl.h:55

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl* aclcopy ( const Acl orig_acl)

Definition at line 434 of file acl.c.

435 {
436  Acl *result_acl;
437 
438  result_acl = allocacl(ACL_NUM(orig_acl));
439 
440  memcpy(ACL_DAT(result_acl),
441  ACL_DAT(orig_acl),
442  ACL_NUM(orig_acl) * sizeof(AclItem));
443 
444  return result_acl;
445 }

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by aclmerge(), ExecGrant_Relation(), and SetDefaultACL().

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 780 of file acl.c.

781 {
782  AclMode world_default;
783  AclMode owner_default;
784  int nacl;
785  Acl *acl;
786  AclItem *aip;
787 
788  switch (objtype)
789  {
790  case OBJECT_COLUMN:
791  /* by default, columns have no extra privileges */
792  world_default = ACL_NO_RIGHTS;
793  owner_default = ACL_NO_RIGHTS;
794  break;
795  case OBJECT_TABLE:
796  world_default = ACL_NO_RIGHTS;
797  owner_default = ACL_ALL_RIGHTS_RELATION;
798  break;
799  case OBJECT_SEQUENCE:
800  world_default = ACL_NO_RIGHTS;
801  owner_default = ACL_ALL_RIGHTS_SEQUENCE;
802  break;
803  case OBJECT_DATABASE:
804  /* for backwards compatibility, grant some rights by default */
805  world_default = ACL_CREATE_TEMP | ACL_CONNECT;
806  owner_default = ACL_ALL_RIGHTS_DATABASE;
807  break;
808  case OBJECT_FUNCTION:
809  /* Grant EXECUTE by default, for now */
810  world_default = ACL_EXECUTE;
811  owner_default = ACL_ALL_RIGHTS_FUNCTION;
812  break;
813  case OBJECT_LANGUAGE:
814  /* Grant USAGE by default, for now */
815  world_default = ACL_USAGE;
816  owner_default = ACL_ALL_RIGHTS_LANGUAGE;
817  break;
818  case OBJECT_LARGEOBJECT:
819  world_default = ACL_NO_RIGHTS;
820  owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
821  break;
822  case OBJECT_SCHEMA:
823  world_default = ACL_NO_RIGHTS;
824  owner_default = ACL_ALL_RIGHTS_SCHEMA;
825  break;
826  case OBJECT_TABLESPACE:
827  world_default = ACL_NO_RIGHTS;
828  owner_default = ACL_ALL_RIGHTS_TABLESPACE;
829  break;
830  case OBJECT_FDW:
831  world_default = ACL_NO_RIGHTS;
832  owner_default = ACL_ALL_RIGHTS_FDW;
833  break;
835  world_default = ACL_NO_RIGHTS;
836  owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
837  break;
838  case OBJECT_DOMAIN:
839  case OBJECT_TYPE:
840  world_default = ACL_USAGE;
841  owner_default = ACL_ALL_RIGHTS_TYPE;
842  break;
844  world_default = ACL_NO_RIGHTS;
845  owner_default = ACL_ALL_RIGHTS_PARAMETER_ACL;
846  break;
847  default:
848  elog(ERROR, "unrecognized object type: %d", (int) objtype);
849  world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
850  owner_default = ACL_NO_RIGHTS;
851  break;
852  }
853 
854  nacl = 0;
855  if (world_default != ACL_NO_RIGHTS)
856  nacl++;
857  if (owner_default != ACL_NO_RIGHTS)
858  nacl++;
859 
860  acl = allocacl(nacl);
861  aip = ACL_DAT(acl);
862 
863  if (world_default != ACL_NO_RIGHTS)
864  {
865  aip->ai_grantee = ACL_ID_PUBLIC;
866  aip->ai_grantor = ownerId;
867  ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
868  aip++;
869  }
870 
871  /*
872  * Note that the owner's entry shows all ordinary privileges but no grant
873  * options. This is because his grant options come "from the system" and
874  * not from his own efforts. (The SQL spec says that the owner's rights
875  * come from a "_SYSTEM" authid.) However, we do consider that the
876  * owner's ordinary privileges are self-granted; this lets him revoke
877  * them. We implement the owner's grant options without any explicit
878  * "_SYSTEM"-like ACL entry, by internally special-casing the owner
879  * wherever we are testing grant options.
880  */
881  if (owner_default != ACL_NO_RIGHTS)
882  {
883  aip->ai_grantee = ownerId;
884  aip->ai_grantor = ownerId;
885  ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
886  }
887 
888  return acl;
889 }
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:164
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:170
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition: acl.h:168
#define ACL_ALL_RIGHTS_SCHEMA
Definition: acl.h:169
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:161
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:162
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:165
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:166
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:171
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:163
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:160
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:167
#define ACL_CREATE_TEMP
Definition: parsenodes.h:93
#define ACL_USAGE
Definition: parsenodes.h:91
#define ACL_NO_RIGHTS
Definition: parsenodes.h:99
#define ACL_CONNECT
Definition: parsenodes.h:94
#define ACL_EXECUTE
Definition: parsenodes.h:90
Oid ai_grantee
Definition: acl.h:56
Oid ai_grantor
Definition: acl.h:57

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog(), ERROR, OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

Referenced by acldefault_sql(), buildDefaultACLCommands(), dumpACL(), dumpRoleGUCPrivs(), dumpTable(), dumpTablespaces(), ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), get_user_default_acl(), object_aclmask(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask(), and SetDefaultACL().

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 536 of file acl.c.

537 {
538  /* Check for cases where one or both are empty/null */
539  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
540  {
541  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
542  return true;
543  else
544  return false;
545  }
546  else
547  {
548  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
549  return false;
550  }
551 
552  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
553  return false;
554 
555  if (memcmp(ACL_DAT(left_acl),
556  ACL_DAT(right_acl),
557  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
558  return true;
559 
560  return false;
561 }

References ACL_DAT, and ACL_NUM.

Referenced by ExecGrant_Parameter(), get_user_default_acl(), and SetDefaultACL().

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 522 of file acl.c.

523 {
524  if (acl != NULL && ACL_NUM(acl) > 1)
525  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
526 }
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:701
#define qsort(a, b, c, d)
Definition: port.h:445

References ACL_DAT, ACL_NUM, aclitemComparator(), and qsort.

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclmask()

AclMode aclmask ( const Acl acl,
Oid  roleid,
Oid  ownerId,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 1359 of file acl.c.

1361 {
1362  AclMode result;
1364  AclItem *aidat;
1365  int i,
1366  num;
1367 
1368  /*
1369  * Null ACL should not happen, since caller should have inserted
1370  * appropriate default
1371  */
1372  if (acl == NULL)
1373  elog(ERROR, "null ACL");
1374 
1375  check_acl(acl);
1376 
1377  /* Quick exit for mask == 0 */
1378  if (mask == 0)
1379  return 0;
1380 
1381  result = 0;
1382 
1383  /* Owner always implicitly has all grant options */
1384  if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1385  has_privs_of_role(roleid, ownerId))
1386  {
1387  result = mask & ACLITEM_ALL_GOPTION_BITS;
1388  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1389  return result;
1390  }
1391 
1392  num = ACL_NUM(acl);
1393  aidat = ACL_DAT(acl);
1394 
1395  /*
1396  * Check privileges granted directly to roleid or to public
1397  */
1398  for (i = 0; i < num; i++)
1399  {
1400  AclItem *aidata = &aidat[i];
1401 
1402  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1403  aidata->ai_grantee == roleid)
1404  {
1405  result |= aidata->ai_privs & mask;
1406  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1407  return result;
1408  }
1409  }
1410 
1411  /*
1412  * Check privileges granted indirectly via role memberships. We do this in
1413  * a separate pass to minimize expensive indirect membership tests. In
1414  * particular, it's worth testing whether a given ACL entry grants any
1415  * privileges still of interest before we perform the has_privs_of_role
1416  * test.
1417  */
1418  remaining = mask & ~result;
1419  for (i = 0; i < num; i++)
1420  {
1421  AclItem *aidata = &aidat[i];
1422 
1423  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1424  aidata->ai_grantee == roleid)
1425  continue; /* already checked it */
1426 
1427  if ((aidata->ai_privs & remaining) &&
1428  has_privs_of_role(roleid, aidata->ai_grantee))
1429  {
1430  result |= aidata->ai_privs & mask;
1431  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1432  return result;
1433  remaining = mask & ~result;
1434  }
1435  }
1436 
1437  return result;
1438 }
static void check_acl(const Acl *acl)
Definition: acl.c:567
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4969
#define ACLITEM_ALL_GOPTION_BITS
Definition: acl.h:88
int remaining
Definition: informix.c:667
int i
Definition: isn.c:73
AclMode ai_privs
Definition: acl.h:58

References ACL_DAT, ACL_ID_PUBLIC, ACL_NUM, ACLITEM_ALL_GOPTION_BITS, ACLMASK_ALL, AclItem::ai_grantee, AclItem::ai_privs, check_acl(), elog(), ERROR, has_privs_of_role(), i, and remaining.

Referenced by check_circularity(), LockTableAclCheck(), object_aclmask(), pg_attribute_aclmask_ext(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask(), and recursive_revoke().

◆ aclmembers()

int aclmembers ( const Acl acl,
Oid **  roleids 
)

Definition at line 1511 of file acl.c.

1512 {
1513  Oid *list;
1514  const AclItem *acldat;
1515  int i,
1516  j;
1517 
1518  if (acl == NULL || ACL_NUM(acl) == 0)
1519  {
1520  *roleids = NULL;
1521  return 0;
1522  }
1523 
1524  check_acl(acl);
1525 
1526  /* Allocate the worst-case space requirement */
1527  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1528  acldat = ACL_DAT(acl);
1529 
1530  /*
1531  * Walk the ACL collecting mentioned RoleIds.
1532  */
1533  j = 0;
1534  for (i = 0; i < ACL_NUM(acl); i++)
1535  {
1536  const AclItem *ai = &acldat[i];
1537 
1538  if (ai->ai_grantee != ACL_ID_PUBLIC)
1539  list[j++] = ai->ai_grantee;
1540  /* grantor is currently never PUBLIC, but let's check anyway */
1541  if (ai->ai_grantor != ACL_ID_PUBLIC)
1542  list[j++] = ai->ai_grantor;
1543  }
1544 
1545  /* Sort the array */
1546  qsort(list, j, sizeof(Oid), oid_cmp);
1547 
1548  /*
1549  * We could repalloc the array down to minimum size, but it's hardly worth
1550  * it since it's only transient memory.
1551  */
1552  *roleids = list;
1553 
1554  /* Remove duplicates from the array */
1555  return qunique(list, j, sizeof(Oid), oid_cmp);
1556 }
int j
Definition: isn.c:74
void * palloc(Size size)
Definition: mcxt.c:1210
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:257
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21

References ACL_DAT, ACL_ID_PUBLIC, ACL_NUM, AclItem::ai_grantee, AclItem::ai_grantor, check_acl(), i, j, sort-test::list, oid_cmp(), palloc(), qsort, and qunique().

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), recordDependencyOnNewAcl(), and SetDefaultACL().

◆ aclmerge()

Acl* aclmerge ( const Acl left_acl,
const Acl right_acl,
Oid  ownerId 
)

Definition at line 478 of file acl.c.

479 {
480  Acl *result_acl;
481  AclItem *aip;
482  int i,
483  num;
484 
485  /* Check for cases where one or both are empty/null */
486  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
487  {
488  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
489  return NULL;
490  else
491  return aclcopy(right_acl);
492  }
493  else
494  {
495  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
496  return aclcopy(left_acl);
497  }
498 
499  /* Merge them the hard way, one item at a time */
500  result_acl = aclcopy(left_acl);
501 
502  aip = ACL_DAT(right_acl);
503  num = ACL_NUM(right_acl);
504 
505  for (i = 0; i < num; i++, aip++)
506  {
507  Acl *tmp_acl;
508 
509  tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
510  ownerId, DROP_RESTRICT);
511  pfree(result_acl);
512  result_acl = tmp_acl;
513  }
514 
515  return result_acl;
516 }
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:969
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:434
#define ACL_MODECHG_ADD
Definition: acl.h:129
void pfree(void *pointer)
Definition: mcxt.c:1436
@ DROP_RESTRICT
Definition: parsenodes.h:2155

References ACL_DAT, ACL_MODECHG_ADD, ACL_NUM, aclcopy(), aclupdate(), DROP_RESTRICT, i, and pfree().

Referenced by get_user_default_acl().

◆ aclnewowner()

Acl* aclnewowner ( const Acl old_acl,
Oid  oldOwnerId,
Oid  newOwnerId 
)

Definition at line 1090 of file acl.c.

1091 {
1092  Acl *new_acl;
1093  AclItem *new_aip;
1094  AclItem *old_aip;
1095  AclItem *dst_aip;
1096  AclItem *src_aip;
1097  AclItem *targ_aip;
1098  bool newpresent = false;
1099  int dst,
1100  src,
1101  targ,
1102  num;
1103 
1104  check_acl(old_acl);
1105 
1106  /*
1107  * Make a copy of the given ACL, substituting new owner ID for old
1108  * wherever it appears as either grantor or grantee. Also note if the new
1109  * owner ID is already present.
1110  */
1111  num = ACL_NUM(old_acl);
1112  old_aip = ACL_DAT(old_acl);
1113  new_acl = allocacl(num);
1114  new_aip = ACL_DAT(new_acl);
1115  memcpy(new_aip, old_aip, num * sizeof(AclItem));
1116  for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1117  {
1118  if (dst_aip->ai_grantor == oldOwnerId)
1119  dst_aip->ai_grantor = newOwnerId;
1120  else if (dst_aip->ai_grantor == newOwnerId)
1121  newpresent = true;
1122  if (dst_aip->ai_grantee == oldOwnerId)
1123  dst_aip->ai_grantee = newOwnerId;
1124  else if (dst_aip->ai_grantee == newOwnerId)
1125  newpresent = true;
1126  }
1127 
1128  /*
1129  * If the old ACL contained any references to the new owner, then we may
1130  * now have generated an ACL containing duplicate entries. Find them and
1131  * merge them so that there are not duplicates. (This is relatively
1132  * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1133  * be the normal case.)
1134  *
1135  * To simplify deletion of duplicate entries, we temporarily leave them in
1136  * the array but set their privilege masks to zero; when we reach such an
1137  * entry it's just skipped. (Thus, a side effect of this code will be to
1138  * remove privilege-free entries, should there be any in the input.) dst
1139  * is the next output slot, targ is the currently considered input slot
1140  * (always >= dst), and src scans entries to the right of targ looking for
1141  * duplicates. Once an entry has been emitted to dst it is known
1142  * duplicate-free and need not be considered anymore.
1143  */
1144  if (newpresent)
1145  {
1146  dst = 0;
1147  for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1148  {
1149  /* ignore if deleted in an earlier pass */
1150  if (ACLITEM_GET_RIGHTS(*targ_aip) == ACL_NO_RIGHTS)
1151  continue;
1152  /* find and merge any duplicates */
1153  for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1154  src++, src_aip++)
1155  {
1156  if (ACLITEM_GET_RIGHTS(*src_aip) == ACL_NO_RIGHTS)
1157  continue;
1158  if (aclitem_match(targ_aip, src_aip))
1159  {
1160  ACLITEM_SET_RIGHTS(*targ_aip,
1161  ACLITEM_GET_RIGHTS(*targ_aip) |
1162  ACLITEM_GET_RIGHTS(*src_aip));
1163  /* mark the duplicate deleted */
1164  ACLITEM_SET_RIGHTS(*src_aip, ACL_NO_RIGHTS);
1165  }
1166  }
1167  /* and emit to output */
1168  new_aip[dst] = *targ_aip;
1169  dst++;
1170  }
1171  /* Adjust array size to be 'dst' items */
1172  ARR_DIMS(new_acl)[0] = dst;
1173  SET_VARSIZE(new_acl, ACL_N_SIZE(dst));
1174  }
1175 
1176  return new_acl;
1177 }
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition: acl.c:690
#define ACL_N_SIZE(N)
Definition: acl.h:110
#define ACLITEM_GET_RIGHTS(item)
Definition: acl.h:68
#define ACLITEM_SET_RIGHTS(item, rights)
Definition: acl.h:79
#define ARR_DIMS(a)
Definition: array.h:287
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References ACL_DAT, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), ARR_DIMS, check_acl(), and SET_VARSIZE.

Referenced by AlterDatabaseOwner(), AlterForeignDataWrapperOwner_internal(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterSchemaOwner_internal(), AlterTypeOwnerInternal(), ATExecChangeOwner(), and change_owner_fix_column_acls().

◆ aclupdate()

Acl* aclupdate ( const Acl old_acl,
const AclItem mod_aip,
int  modechg,
Oid  ownerId,
DropBehavior  behavior 
)

Definition at line 969 of file acl.c.

971 {
972  Acl *new_acl = NULL;
973  AclItem *old_aip,
974  *new_aip = NULL;
975  AclMode old_rights,
976  old_goptions,
977  new_rights,
978  new_goptions;
979  int dst,
980  num;
981 
982  /* Caller probably already checked old_acl, but be safe */
983  check_acl(old_acl);
984 
985  /* If granting grant options, check for circularity */
986  if (modechg != ACL_MODECHG_DEL &&
987  ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS)
988  check_circularity(old_acl, mod_aip, ownerId);
989 
990  num = ACL_NUM(old_acl);
991  old_aip = ACL_DAT(old_acl);
992 
993  /*
994  * Search the ACL for an existing entry for this grantee and grantor. If
995  * one exists, just modify the entry in-place (well, in the same position,
996  * since we actually return a copy); otherwise, insert the new entry at
997  * the end.
998  */
999 
1000  for (dst = 0; dst < num; ++dst)
1001  {
1002  if (aclitem_match(mod_aip, old_aip + dst))
1003  {
1004  /* found a match, so modify existing item */
1005  new_acl = allocacl(num);
1006  new_aip = ACL_DAT(new_acl);
1007  memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
1008  break;
1009  }
1010  }
1011 
1012  if (dst == num)
1013  {
1014  /* need to append a new item */
1015  new_acl = allocacl(num + 1);
1016  new_aip = ACL_DAT(new_acl);
1017  memcpy(new_aip, old_aip, num * sizeof(AclItem));
1018 
1019  /* initialize the new entry with no permissions */
1020  new_aip[dst].ai_grantee = mod_aip->ai_grantee;
1021  new_aip[dst].ai_grantor = mod_aip->ai_grantor;
1022  ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
1024  num++; /* set num to the size of new_acl */
1025  }
1026 
1027  old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1028  old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1029 
1030  /* apply the specified permissions change */
1031  switch (modechg)
1032  {
1033  case ACL_MODECHG_ADD:
1034  ACLITEM_SET_RIGHTS(new_aip[dst],
1035  old_rights | ACLITEM_GET_RIGHTS(*mod_aip));
1036  break;
1037  case ACL_MODECHG_DEL:
1038  ACLITEM_SET_RIGHTS(new_aip[dst],
1039  old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
1040  break;
1041  case ACL_MODECHG_EQL:
1042  ACLITEM_SET_RIGHTS(new_aip[dst],
1043  ACLITEM_GET_RIGHTS(*mod_aip));
1044  break;
1045  }
1046 
1047  new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1048  new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1049 
1050  /*
1051  * If the adjusted entry has no permissions, delete it from the list.
1052  */
1053  if (new_rights == ACL_NO_RIGHTS)
1054  {
1055  memmove(new_aip + dst,
1056  new_aip + dst + 1,
1057  (num - dst - 1) * sizeof(AclItem));
1058  /* Adjust array size to be 'num - 1' items */
1059  ARR_DIMS(new_acl)[0] = num - 1;
1060  SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1061  }
1062 
1063  /*
1064  * Remove abandoned privileges (cascading revoke). Currently we can only
1065  * handle this when the grantee is not PUBLIC.
1066  */
1067  if ((old_goptions & ~new_goptions) != 0)
1068  {
1069  Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1070  new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1071  (old_goptions & ~new_goptions),
1072  ownerId, behavior);
1073  }
1074 
1075  return new_acl;
1076 }
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition: acl.c:1273
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1193
#define ACL_SIZE(ACL)
Definition: acl.h:111
#define ACL_MODECHG_DEL
Definition: acl.h:130
#define ACLITEM_GET_GOPTIONS(item)
Definition: acl.h:67
#define ACL_MODECHG_EQL
Definition: acl.h:131
Assert(fmt[strlen(fmt) - 1] !='\n')

References ACL_DAT, ACL_ID_PUBLIC, ACL_MODECHG_ADD, ACL_MODECHG_DEL, ACL_MODECHG_EQL, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACL_SIZE, ACLITEM_GET_GOPTIONS, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_PRIVS_GOPTIONS, ACLITEM_SET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), ARR_DIMS, Assert(), check_acl(), check_circularity(), recursive_revoke(), and SET_VARSIZE.

Referenced by aclmerge(), check_circularity(), merge_acl_with_grant(), and recursive_revoke().

◆ check_can_set_role()

void check_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5026 of file acl.c.

5027 {
5028  if (!member_can_set_role(member, role))
5029  ereport(ERROR,
5030  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5031  errmsg("must be able to SET ROLE \"%s\"",
5032  GetUserNameFromId(role, false))));
5033 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5003
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:984

References ereport, errcode(), errmsg(), ERROR, GetUserNameFromId(), and member_can_set_role().

Referenced by AlterDatabaseOwner(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTypeOwner(), ATExecChangeOwner(), createdb(), and CreateSchemaCommand().

◆ check_rolespec_name()

void check_rolespec_name ( const RoleSpec role,
const char *  detail_msg 
)

Definition at line 5396 of file acl.c.

5397 {
5398  if (!role)
5399  return;
5400 
5401  if (role->roletype != ROLESPEC_CSTRING)
5402  return;
5403 
5404  if (IsReservedName(role->rolename))
5405  {
5406  if (detail_msg)
5407  ereport(ERROR,
5408  (errcode(ERRCODE_RESERVED_NAME),
5409  errmsg("role name \"%s\" is reserved",
5410  role->rolename),
5411  errdetail_internal("%s", detail_msg)));
5412  else
5413  ereport(ERROR,
5414  (errcode(ERRCODE_RESERVED_NAME),
5415  errmsg("role name \"%s\" is reserved",
5416  role->rolename)));
5417  }
5418 }
bool IsReservedName(const char *name)
Definition: catalog.c:219
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1229
@ ROLESPEC_CSTRING
Definition: parsenodes.h:392
RoleSpecType roletype
Definition: parsenodes.h:402
char * rolename
Definition: parsenodes.h:403

References ereport, errcode(), errdetail_internal(), errmsg(), ERROR, IsReservedName(), RoleSpec::rolename, ROLESPEC_CSTRING, and RoleSpec::roletype.

Referenced by AlterRole(), and AlterRoleSet().

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

Definition at line 966 of file aclchk.c.

967 {
968  GrantStmt *action = stmt->action;
969  InternalDefaultACL iacls;
970  ListCell *cell;
971  List *rolespecs = NIL;
972  List *nspnames = NIL;
973  DefElem *drolespecs = NULL;
974  DefElem *dnspnames = NULL;
975  AclMode all_privileges;
976  const char *errormsg;
977 
978  /* Deconstruct the "options" part of the statement */
979  foreach(cell, stmt->options)
980  {
981  DefElem *defel = (DefElem *) lfirst(cell);
982 
983  if (strcmp(defel->defname, "schemas") == 0)
984  {
985  if (dnspnames)
986  errorConflictingDefElem(defel, pstate);
987  dnspnames = defel;
988  }
989  else if (strcmp(defel->defname, "roles") == 0)
990  {
991  if (drolespecs)
992  errorConflictingDefElem(defel, pstate);
993  drolespecs = defel;
994  }
995  else
996  elog(ERROR, "option \"%s\" not recognized", defel->defname);
997  }
998 
999  if (dnspnames)
1000  nspnames = (List *) dnspnames->arg;
1001  if (drolespecs)
1002  rolespecs = (List *) drolespecs->arg;
1003 
1004  /* Prepare the InternalDefaultACL representation of the statement */
1005  /* roleid to be filled below */
1006  /* nspid to be filled in SetDefaultACLsInSchemas */
1007  iacls.is_grant = action->is_grant;
1008  iacls.objtype = action->objtype;
1009  /* all_privs to be filled below */
1010  /* privileges to be filled below */
1011  iacls.grantees = NIL; /* filled below */
1012  iacls.grant_option = action->grant_option;
1013  iacls.behavior = action->behavior;
1014 
1015  /*
1016  * Convert the RoleSpec list into an Oid list. Note that at this point we
1017  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
1018  * there shouldn't be any additional work needed to support this case.
1019  */
1020  foreach(cell, action->grantees)
1021  {
1022  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
1023  Oid grantee_uid;
1024 
1025  switch (grantee->roletype)
1026  {
1027  case ROLESPEC_PUBLIC:
1028  grantee_uid = ACL_ID_PUBLIC;
1029  break;
1030  default:
1031  grantee_uid = get_rolespec_oid(grantee, false);
1032  break;
1033  }
1034  iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
1035  }
1036 
1037  /*
1038  * Convert action->privileges, a list of privilege strings, into an
1039  * AclMode bitmask.
1040  */
1041  switch (action->objtype)
1042  {
1043  case OBJECT_TABLE:
1044  all_privileges = ACL_ALL_RIGHTS_RELATION;
1045  errormsg = gettext_noop("invalid privilege type %s for relation");
1046  break;
1047  case OBJECT_SEQUENCE:
1048  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
1049  errormsg = gettext_noop("invalid privilege type %s for sequence");
1050  break;
1051  case OBJECT_FUNCTION:
1052  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1053  errormsg = gettext_noop("invalid privilege type %s for function");
1054  break;
1055  case OBJECT_PROCEDURE:
1056  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1057  errormsg = gettext_noop("invalid privilege type %s for procedure");
1058  break;
1059  case OBJECT_ROUTINE:
1060  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1061  errormsg = gettext_noop("invalid privilege type %s for routine");
1062  break;
1063  case OBJECT_TYPE:
1064  all_privileges = ACL_ALL_RIGHTS_TYPE;
1065  errormsg = gettext_noop("invalid privilege type %s for type");
1066  break;
1067  case OBJECT_SCHEMA:
1068  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
1069  errormsg = gettext_noop("invalid privilege type %s for schema");
1070  break;
1071  default:
1072  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1073  (int) action->objtype);
1074  /* keep compiler quiet */
1075  all_privileges = ACL_NO_RIGHTS;
1076  errormsg = NULL;
1077  }
1078 
1079  if (action->privileges == NIL)
1080  {
1081  iacls.all_privs = true;
1082 
1083  /*
1084  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1085  * depending on the object type
1086  */
1087  iacls.privileges = ACL_NO_RIGHTS;
1088  }
1089  else
1090  {
1091  iacls.all_privs = false;
1092  iacls.privileges = ACL_NO_RIGHTS;
1093 
1094  foreach(cell, action->privileges)
1095  {
1096  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1097  AclMode priv;
1098 
1099  if (privnode->cols)
1100  ereport(ERROR,
1101  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1102  errmsg("default privileges cannot be set for columns")));
1103 
1104  if (privnode->priv_name == NULL) /* parser mistake? */
1105  elog(ERROR, "AccessPriv node must specify privilege");
1106  priv = string_to_privilege(privnode->priv_name);
1107 
1108  if (priv & ~((AclMode) all_privileges))
1109  ereport(ERROR,
1110  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1111  errmsg(errormsg, privilege_to_string(priv))));
1112 
1113  iacls.privileges |= priv;
1114  }
1115  }
1116 
1117  if (rolespecs == NIL)
1118  {
1119  /* Set permissions for myself */
1120  iacls.roleid = GetUserId();
1121 
1122  SetDefaultACLsInSchemas(&iacls, nspnames);
1123  }
1124  else
1125  {
1126  /* Look up the role OIDs and do permissions checks */
1127  ListCell *rolecell;
1128 
1129  foreach(rolecell, rolespecs)
1130  {
1131  RoleSpec *rolespec = lfirst(rolecell);
1132 
1133  iacls.roleid = get_rolespec_oid(rolespec, false);
1134 
1135  if (!has_privs_of_role(GetUserId(), iacls.roleid))
1136  ereport(ERROR,
1137  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1138  errmsg("permission denied to change default privileges")));
1139 
1140  SetDefaultACLsInSchemas(&iacls, nspnames);
1141  }
1142  }
1143 }
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5289
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:2583
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1151
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2626
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:385
#define stmt
Definition: indent_codes.h:59
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
Oid GetUserId(void)
Definition: miscinit.c:510
@ ROLESPEC_PUBLIC
Definition: parsenodes.h:396
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
char * priv_name
Definition: parsenodes.h:2366
List * cols
Definition: parsenodes.h:2367
char * defname
Definition: parsenodes.h:810
Node * arg
Definition: parsenodes.h:811
bool grant_option
Definition: aclchk.c:96
AclMode privileges
Definition: aclchk.c:94
List * grantees
Definition: aclchk.c:95
DropBehavior behavior
Definition: aclchk.c:97
ObjectType objtype
Definition: aclchk.c:92
Definition: pg_list.h:54

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, generate_unaccent_rules::action, InternalDefaultACL::all_privs, DefElem::arg, InternalDefaultACL::behavior, AccessPriv::cols, DefElem::defname, elog(), ereport, errcode(), errmsg(), ERROR, errorConflictingDefElem(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalDefaultACL::grant_option, InternalDefaultACL::grantees, has_privs_of_role(), if(), InternalDefaultACL::is_grant, lappend_oid(), lfirst, NIL, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, InternalDefaultACL::objtype, AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, InternalDefaultACL::roleid, ROLESPEC_PUBLIC, RoleSpec::roletype, SetDefaultACLsInSchemas(), stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 382 of file aclchk.c.

383 {
384  InternalGrant istmt;
385  ListCell *cell;
386  const char *errormsg;
387  AclMode all_privileges;
388 
389  if (stmt->grantor)
390  {
391  Oid grantor;
392 
393  grantor = get_rolespec_oid(stmt->grantor, false);
394 
395  /*
396  * Currently, this clause is only for SQL compatibility, not very
397  * interesting otherwise.
398  */
399  if (grantor != GetUserId())
400  ereport(ERROR,
401  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
402  errmsg("grantor must be current user")));
403  }
404 
405  /*
406  * Turn the regular GrantStmt into the InternalGrant form.
407  */
408  istmt.is_grant = stmt->is_grant;
409  istmt.objtype = stmt->objtype;
410 
411  /* Collect the OIDs of the target objects */
412  switch (stmt->targtype)
413  {
414  case ACL_TARGET_OBJECT:
415  istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects,
416  stmt->is_grant);
417  break;
419  istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
420  break;
421  /* ACL_TARGET_DEFAULTS should not be seen here */
422  default:
423  elog(ERROR, "unrecognized GrantStmt.targtype: %d",
424  (int) stmt->targtype);
425  }
426 
427  /* all_privs to be filled below */
428  /* privileges to be filled below */
429  istmt.col_privs = NIL; /* may get filled below */
430  istmt.grantees = NIL; /* filled below */
431  istmt.grant_option = stmt->grant_option;
432  istmt.behavior = stmt->behavior;
433 
434  /*
435  * Convert the RoleSpec list into an Oid list. Note that at this point we
436  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
437  * there shouldn't be any additional work needed to support this case.
438  */
439  foreach(cell, stmt->grantees)
440  {
441  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
442  Oid grantee_uid;
443 
444  switch (grantee->roletype)
445  {
446  case ROLESPEC_PUBLIC:
447  grantee_uid = ACL_ID_PUBLIC;
448  break;
449  default:
450  grantee_uid = get_rolespec_oid(grantee, false);
451  break;
452  }
453  istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
454  }
455 
456  /*
457  * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
458  * bitmask. Note: objtype can't be OBJECT_COLUMN.
459  */
460  switch (stmt->objtype)
461  {
462  case OBJECT_TABLE:
463 
464  /*
465  * Because this might be a sequence, we test both relation and
466  * sequence bits, and later do a more limited test when we know
467  * the object type.
468  */
470  errormsg = gettext_noop("invalid privilege type %s for relation");
471  break;
472  case OBJECT_SEQUENCE:
473  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
474  errormsg = gettext_noop("invalid privilege type %s for sequence");
475  break;
476  case OBJECT_DATABASE:
477  all_privileges = ACL_ALL_RIGHTS_DATABASE;
478  errormsg = gettext_noop("invalid privilege type %s for database");
479  break;
480  case OBJECT_DOMAIN:
481  all_privileges = ACL_ALL_RIGHTS_TYPE;
482  errormsg = gettext_noop("invalid privilege type %s for domain");
483  break;
484  case OBJECT_FUNCTION:
485  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
486  errormsg = gettext_noop("invalid privilege type %s for function");
487  break;
488  case OBJECT_LANGUAGE:
489  all_privileges = ACL_ALL_RIGHTS_LANGUAGE;
490  errormsg = gettext_noop("invalid privilege type %s for language");
491  break;
492  case OBJECT_LARGEOBJECT:
493  all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
494  errormsg = gettext_noop("invalid privilege type %s for large object");
495  break;
496  case OBJECT_SCHEMA:
497  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
498  errormsg = gettext_noop("invalid privilege type %s for schema");
499  break;
500  case OBJECT_PROCEDURE:
501  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
502  errormsg = gettext_noop("invalid privilege type %s for procedure");
503  break;
504  case OBJECT_ROUTINE:
505  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
506  errormsg = gettext_noop("invalid privilege type %s for routine");
507  break;
508  case OBJECT_TABLESPACE:
509  all_privileges = ACL_ALL_RIGHTS_TABLESPACE;
510  errormsg = gettext_noop("invalid privilege type %s for tablespace");
511  break;
512  case OBJECT_TYPE:
513  all_privileges = ACL_ALL_RIGHTS_TYPE;
514  errormsg = gettext_noop("invalid privilege type %s for type");
515  break;
516  case OBJECT_FDW:
517  all_privileges = ACL_ALL_RIGHTS_FDW;
518  errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
519  break;
521  all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER;
522  errormsg = gettext_noop("invalid privilege type %s for foreign server");
523  break;
525  all_privileges = ACL_ALL_RIGHTS_PARAMETER_ACL;
526  errormsg = gettext_noop("invalid privilege type %s for parameter");
527  break;
528  default:
529  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
530  (int) stmt->objtype);
531  /* keep compiler quiet */
532  all_privileges = ACL_NO_RIGHTS;
533  errormsg = NULL;
534  }
535 
536  if (stmt->privileges == NIL)
537  {
538  istmt.all_privs = true;
539 
540  /*
541  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
542  * depending on the object type
543  */
544  istmt.privileges = ACL_NO_RIGHTS;
545  }
546  else
547  {
548  istmt.all_privs = false;
549  istmt.privileges = ACL_NO_RIGHTS;
550 
551  foreach(cell, stmt->privileges)
552  {
553  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
554  AclMode priv;
555 
556  /*
557  * If it's a column-level specification, we just set it aside in
558  * col_privs for the moment; but insist it's for a relation.
559  */
560  if (privnode->cols)
561  {
562  if (stmt->objtype != OBJECT_TABLE)
563  ereport(ERROR,
564  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
565  errmsg("column privileges are only valid for relations")));
566  istmt.col_privs = lappend(istmt.col_privs, privnode);
567  continue;
568  }
569 
570  if (privnode->priv_name == NULL) /* parser mistake? */
571  elog(ERROR, "AccessPriv node must specify privilege or columns");
572  priv = string_to_privilege(privnode->priv_name);
573 
574  if (priv & ~((AclMode) all_privileges))
575  ereport(ERROR,
576  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
577  errmsg(errormsg, privilege_to_string(priv))));
578 
579  istmt.privileges |= priv;
580  }
581  }
582 
583  ExecGrantStmt_oids(&istmt);
584 }
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition: aclchk.c:592
static List * objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
Definition: aclchk.c:659
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition: aclchk.c:839
List * lappend(List *list, void *datum)
Definition: list.c:338
@ ACL_TARGET_OBJECT
Definition: parsenodes.h:2309
@ ACL_TARGET_ALL_IN_SCHEMA
Definition: parsenodes.h:2310
DropBehavior behavior
AclMode privileges
ObjectType objtype

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, AccessPriv::cols, elog(), ereport, errcode(), errmsg(), ERROR, ExecGrantStmt_oids(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, AccessPriv::priv_name, privilege_to_string(), InternalGrant::privileges, ROLESPEC_PUBLIC, RoleSpec::roletype, stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char *  rolname,
bool  missing_ok 
)

Definition at line 5255 of file acl.c.

5256 {
5257  Oid oid;
5258 
5259  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5261  if (!OidIsValid(oid) && !missing_ok)
5262  ereport(ERROR,
5263  (errcode(ERRCODE_UNDEFINED_OBJECT),
5264  errmsg("role \"%s\" does not exist", rolname)));
5265  return oid;
5266 }
#define OidIsValid(objectId)
Definition: c.h:759
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
@ AUTHNAME
Definition: syscache.h:44
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:200

References AUTHNAME, CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, OidIsValid, and rolname.

Referenced by aclparse(), check_hba(), check_ident_usermap(), createdb(), CreateRole(), get_object_address_unqualified(), get_role_oid_or_public(), get_rolespec_oid(), GrantRole(), is_member(), pg_has_role_id_name(), pg_has_role_name(), pg_has_role_name_id(), pg_has_role_name_name(), regrolein(), and shell_check_detail().

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5374 of file acl.c.

5375 {
5376  HeapTuple tp;
5377  Form_pg_authid authForm;
5378  char *rolename;
5379 
5380  tp = get_rolespec_tuple(role);
5381  authForm = (Form_pg_authid) GETSTRUCT(tp);
5382  rolename = pstrdup(NameStr(authForm->rolname));
5383  ReleaseSysCache(tp);
5384 
5385  return rolename;
5386 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5328
#define NameStr(name)
Definition: c.h:730
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1624
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:866

References get_rolespec_tuple(), GETSTRUCT, NameStr, pstrdup(), and ReleaseSysCache().

Referenced by AddRoleMems(), and DelRoleMems().

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

Definition at line 5289 of file acl.c.

5290 {
5291  Oid oid;
5292 
5293  switch (role->roletype)
5294  {
5295  case ROLESPEC_CSTRING:
5296  Assert(role->rolename);
5297  oid = get_role_oid(role->rolename, missing_ok);
5298  break;
5299 
5300  case ROLESPEC_CURRENT_ROLE:
5301  case ROLESPEC_CURRENT_USER:
5302  oid = GetUserId();
5303  break;
5304 
5305  case ROLESPEC_SESSION_USER:
5306  oid = GetSessionUserId();
5307  break;
5308 
5309  case ROLESPEC_PUBLIC:
5310  ereport(ERROR,
5311  (errcode(ERRCODE_UNDEFINED_OBJECT),
5312  errmsg("role \"%s\" does not exist", "public")));
5313  oid = InvalidOid; /* make compiler happy */
5314  break;
5315 
5316  default:
5317  elog(ERROR, "unexpected role type %d", role->roletype);
5318  }
5319 
5320  return oid;
5321 }
Oid GetSessionUserId(void)
Definition: miscinit.c:544
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:394
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:395
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:393
#define InvalidOid
Definition: postgres_ext.h:36

References Assert(), elog(), ereport, errcode(), errmsg(), ERROR, get_role_oid(), GetSessionUserId(), GetUserId(), InvalidOid, RoleSpec::rolename, ROLESPEC_CSTRING, ROLESPEC_CURRENT_ROLE, ROLESPEC_CURRENT_USER, ROLESPEC_PUBLIC, ROLESPEC_SESSION_USER, and RoleSpec::roletype.

Referenced by AlterUserMapping(), ATExecCmd(), CreateSchemaCommand(), CreateTableSpace(), CreateUserMapping(), ExecAlterDefaultPrivilegesStmt(), ExecAlterOwnerStmt(), ExecuteGrantStmt(), GrantRole(), policy_role_list_to_array(), ReassignOwnedObjects(), RemoveUserMapping(), and roleSpecsToIds().

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

Definition at line 5328 of file acl.c.

5329 {
5330  HeapTuple tuple;
5331 
5332  switch (role->roletype)
5333  {
5334  case ROLESPEC_CSTRING:
5335  Assert(role->rolename);
5337  if (!HeapTupleIsValid(tuple))
5338  ereport(ERROR,
5339  (errcode(ERRCODE_UNDEFINED_OBJECT),
5340  errmsg("role \"%s\" does not exist", role->rolename)));
5341  break;
5342 
5343  case ROLESPEC_CURRENT_ROLE:
5344  case ROLESPEC_CURRENT_USER:
5345  tuple = SearchSysCache1(AUTHOID, GetUserId());
5346  if (!HeapTupleIsValid(tuple))
5347  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5348  break;
5349 
5350  case ROLESPEC_SESSION_USER:
5352  if (!HeapTupleIsValid(tuple))
5353  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5354  break;
5355 
5356  case ROLESPEC_PUBLIC:
5357  ereport(ERROR,
5358  (errcode(ERRCODE_UNDEFINED_OBJECT),
5359  errmsg("role \"%s\" does not exist", "public")));
5360  tuple = NULL; /* make compiler happy */
5361  break;
5362 
5363  default:
5364  elog(ERROR, "unexpected role type %d", role->roletype);
5365  }
5366 
5367  return tuple;
5368 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:818
@ AUTHOID
Definition: syscache.h:45

References Assert(), AUTHNAME, AUTHOID, CStringGetDatum(), elog(), ereport, errcode(), errmsg(), ERROR, GetSessionUserId(), GetUserId(), HeapTupleIsValid, RoleSpec::rolename, ROLESPEC_CSTRING, ROLESPEC_CURRENT_ROLE, ROLESPEC_CURRENT_USER, ROLESPEC_PUBLIC, ROLESPEC_SESSION_USER, RoleSpec::roletype, and SearchSysCache1().

Referenced by AlterRole(), AlterRoleSet(), CreateRole(), and get_rolespec_name().

◆ get_user_default_acl()

Acl* get_user_default_acl ( ObjectType  objtype,
Oid  ownerId,
Oid  nsp_oid 
)

Definition at line 4131 of file aclchk.c.

4132 {
4133  Acl *result;
4134  Acl *glob_acl;
4135  Acl *schema_acl;
4136  Acl *def_acl;
4137  char defaclobjtype;
4138 
4139  /*
4140  * Use NULL during bootstrap, since pg_default_acl probably isn't there
4141  * yet.
4142  */
4144  return NULL;
4145 
4146  /* Check if object type is supported in pg_default_acl */
4147  switch (objtype)
4148  {
4149  case OBJECT_TABLE:
4150  defaclobjtype = DEFACLOBJ_RELATION;
4151  break;
4152 
4153  case OBJECT_SEQUENCE:
4154  defaclobjtype = DEFACLOBJ_SEQUENCE;
4155  break;
4156 
4157  case OBJECT_FUNCTION:
4158  defaclobjtype = DEFACLOBJ_FUNCTION;
4159  break;
4160 
4161  case OBJECT_TYPE:
4162  defaclobjtype = DEFACLOBJ_TYPE;
4163  break;
4164 
4165  case OBJECT_SCHEMA:
4166  defaclobjtype = DEFACLOBJ_NAMESPACE;
4167  break;
4168 
4169  default:
4170  return NULL;
4171  }
4172 
4173  /* Look up the relevant pg_default_acl entries */
4174  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4175  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4176 
4177  /* Quick out if neither entry exists */
4178  if (glob_acl == NULL && schema_acl == NULL)
4179  return NULL;
4180 
4181  /* We need to know the hard-wired default value, too */
4182  def_acl = acldefault(objtype, ownerId);
4183 
4184  /* If there's no global entry, substitute the hard-wired default */
4185  if (glob_acl == NULL)
4186  glob_acl = def_acl;
4187 
4188  /* Merge in any per-schema privileges */
4189  result = aclmerge(glob_acl, schema_acl, ownerId);
4190 
4191  /*
4192  * For efficiency, we want to return NULL if the result equals default.
4193  * This requires sorting both arrays to get an accurate comparison.
4194  */
4195  aclitemsort(result);
4196  aclitemsort(def_acl);
4197  if (aclequal(result, def_acl))
4198  result = NULL;
4199 
4200  return result;
4201 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:536
void aclitemsort(Acl *acl)
Definition: acl.c:522
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:780
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:478
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4096
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:405

References acldefault(), aclequal(), aclitemsort(), aclmerge(), get_default_acl_internal(), InvalidOid, IsBootstrapProcessingMode, OBJECT_FUNCTION, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, and OBJECT_TYPE.

Referenced by heap_create_with_catalog(), NamespaceCreate(), ProcedureCreate(), and TypeCreate().

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 4072 of file aclchk.c.

4073 {
4074  bool result = false;
4075  HeapTuple utup;
4076 
4077  /* Superusers bypass all permission checking. */
4078  if (superuser_arg(roleid))
4079  return true;
4080 
4081  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4082  if (HeapTupleIsValid(utup))
4083  {
4084  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4085  ReleaseSysCache(utup);
4086  }
4087  return result;
4088 }
bool rolbypassrls
Definition: pg_authid.h:41
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

References AUTHOID, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), rolbypassrls, SearchSysCache1(), and superuser_arg().

Referenced by AlterRole(), check_enable_rls(), CreateRole(), and RI_Initial_Check().

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4053 of file aclchk.c.

4054 {
4055  bool result = false;
4056  HeapTuple utup;
4057 
4058  /* Superusers bypass all permission checking. */
4059  if (superuser_arg(roleid))
4060  return true;
4061 
4062  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4063  if (HeapTupleIsValid(utup))
4064  {
4065  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4066  ReleaseSysCache(utup);
4067  }
4068  return result;
4069 }
bool rolcreaterole
Definition: pg_authid.h:37

References AUTHOID, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), rolcreaterole, SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership(), CreateRole(), and have_createrole_privilege().

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4969 of file acl.c.

4970 {
4971  /* Fast path for simple case */
4972  if (member == role)
4973  return true;
4974 
4975  /* Superusers have every privilege, so are part of every role */
4976  if (superuser_arg(member))
4977  return true;
4978 
4979  /*
4980  * Find all the roles that member has the privileges of, including
4981  * multi-level recursion, then see if target role is any one of them.
4982  */
4984  InvalidOid, NULL),
4985  role);
4986 }
@ ROLERECURSE_PRIVS
Definition: acl.c:76
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:4844
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721

References InvalidOid, list_member_oid(), ROLERECURSE_PRIVS, roles_is_member_of(), and superuser_arg().

Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), bbsink_server_new(), calculate_database_size(), calculate_tablespace_size(), check_role_for_policy(), check_role_grantor(), ConfigOptionIsVisible(), convert_and_check_filename(), CreateSubscription(), DoCopy(), DropOwnedObjects(), ExecAlterDefaultPrivilegesStmt(), file_fdw_validator(), GetConfigOptionValues(), InitPostgres(), object_ownercheck(), pg_class_aclmask_ext(), pg_namespace_aclmask(), pg_role_aclcheck(), pg_signal_backend(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), ReassignOwnedObjects(), ReindexMultipleTables(), shell_check_detail(), standard_ProcessUtility(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4779 of file acl.c.

4780 {
4782  {
4783  cached_db_hash =
4786 
4787  /*
4788  * In normal mode, set a callback on any syscache invalidation of rows
4789  * of pg_auth_members (for roles_is_member_of()) pg_database (for
4790  * roles_is_member_of())
4791  */
4794  (Datum) 0);
4797  (Datum) 0);
4800  (Datum) 0);
4801  }
4802 }
static uint32 cached_db_hash
Definition: acl.c:81
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4809
Oid MyDatabaseId
Definition: globals.c:89
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
uintptr_t Datum
Definition: postgres.h:64
@ AUTHMEMROLEMEM
Definition: syscache.h:43
@ DATABASEOID
Definition: syscache.h:55
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:209

References AUTHMEMROLEMEM, AUTHOID, cached_db_hash, CacheRegisterSyscacheCallback(), DATABASEOID, GetSysCacheHashValue1, IsBootstrapProcessingMode, MyDatabaseId, ObjectIdGetDatum(), and RoleMembershipCacheCallback().

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 5099 of file acl.c.

5100 {
5101  Oid admin_role;
5102 
5103  if (superuser_arg(member))
5104  return true;
5105 
5106  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5107  if (member == role)
5108  return false;
5109 
5110  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5111  return OidIsValid(admin_role);
5112 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:75

References OidIsValid, ROLERECURSE_MEMBERS, roles_is_member_of(), and superuser_arg().

Referenced by AlterRole(), AlterRoleSet(), check_object_ownership(), check_role_membership_authorization(), DropRole(), pg_role_aclcheck(), and RenameRole().

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 5049 of file acl.c.

5050 {
5051  /* Fast path for simple case */
5052  if (member == role)
5053  return true;
5054 
5055  /* Superusers have every privilege, so are part of every role */
5056  if (superuser_arg(member))
5057  return true;
5058 
5059  /*
5060  * Find all the roles that member is a member of, including multi-level
5061  * recursion, then see if target role is any one of them.
5062  */
5064  InvalidOid, NULL),
5065  role);
5066 }

References InvalidOid, list_member_oid(), ROLERECURSE_MEMBERS, roles_is_member_of(), and superuser_arg().

Referenced by pg_role_aclcheck().

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)

Definition at line 5077 of file acl.c.

5078 {
5079  /* Fast path for simple case */
5080  if (member == role)
5081  return true;
5082 
5083  /*
5084  * Find all the roles that member is a member of, including multi-level
5085  * recursion, then see if target role is any one of them.
5086  */
5088  InvalidOid, NULL),
5089  role);
5090 }

References InvalidOid, list_member_oid(), ROLERECURSE_MEMBERS, and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

◆ make_empty_acl()

Acl* make_empty_acl ( void  )

Definition at line 425 of file acl.c.

426 {
427  return allocacl(0);
428 }

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5003 of file acl.c.

5004 {
5005  /* Fast path for simple case */
5006  if (member == role)
5007  return true;
5008 
5009  /* Superusers have every privilege, so can always SET ROLE */
5010  if (superuser_arg(member))
5011  return true;
5012 
5013  /*
5014  * Find all the roles that member can access via SET ROLE, including
5015  * multi-level recursion, then see if target role is any one of them.
5016  */
5018  InvalidOid, NULL),
5019  role);
5020 }
@ ROLERECURSE_SETROLE
Definition: acl.c:77

References InvalidOid, list_member_oid(), ROLERECURSE_SETROLE, roles_is_member_of(), and superuser_arg().

Referenced by check_can_set_role(), check_role(), and pg_role_aclcheck().

◆ object_aclcheck()

AclResult object_aclcheck ( Oid  classid,
Oid  objectid,
Oid  roleid,
AclMode  mode 
)

Definition at line 3775 of file aclchk.c.

3776 {
3777  if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
3778  return ACLCHECK_OK;
3779  else
3780  return ACLCHECK_NO_PRIV;
3781 }
static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3069
static PgChecksumMode mode
Definition: pg_checksums.c:65

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, and object_aclmask().

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterForeignServerOwner_internal(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTypeOwner(), ATExecAddColumn(), ATExecChangeOwner(), ATPrepAlterColumnType(), ATPrepSetTableSpace(), BuildDescForRelation(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_temp_tablespaces(), CheckFunctionValidatorAccess(), CheckMyDatabase(), compute_return_type(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreatePublication(), CreateSchemaCommand(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), extension_is_trusted(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), HandleFunctionRequest(), has_database_privilege_id(), has_database_privilege_id_id(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_id(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id(), has_foreign_data_wrapper_privilege_id_id(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_id(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id(), has_function_privilege_id_id(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_id(), has_function_privilege_name_name(), has_language_privilege_id(), has_language_privilege_id_id(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_id(), has_language_privilege_name_name(), has_schema_privilege_id(), has_schema_privilege_id_id(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_id(), has_schema_privilege_name_name(), has_server_privilege_id(), has_server_privilege_id_id(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_id(), has_server_privilege_name_name(), has_tablespace_privilege_id(), has_tablespace_privilege_id_id(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_id(), has_tablespace_privilege_name_name(), has_type_privilege_id(), has_type_privilege_id_id(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_id(), has_type_privilege_name_name(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), InitTempTableNamespace(), inline_function(), inline_set_returning_function(), interpret_function_parameter_list(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), movedb(), pg_namespace_aclmask(), PrepareTempTablespaces(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), recomputeNamespacePath(), ReindexMultipleInternal(), RenameSchema(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_ownercheck()

bool object_ownercheck ( Oid  classid,
Oid  objectid,
Oid  roleid 
)

Definition at line 3976 of file aclchk.c.

3977 {
3978  int cacheid;
3979  Oid ownerId;
3980 
3981  /* Superusers bypass all permission checking. */
3982  if (superuser_arg(roleid))
3983  return true;
3984 
3985  cacheid = get_object_catcache_oid(classid);
3986  if (cacheid != -1)
3987  {
3988  HeapTuple tuple;
3989 
3990  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
3991  if (!HeapTupleIsValid(tuple))
3992  ereport(ERROR,
3993  (errcode(ERRCODE_UNDEFINED_OBJECT),
3994  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
3995 
3996  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
3997  tuple,
3998  get_object_attnum_owner(classid)));
3999  ReleaseSysCache(tuple);
4000  }
4001  else
4002  {
4003  /* for catalogs without an appropriate syscache */
4004 
4005  Relation rel;
4006  ScanKeyData entry[1];
4007  SysScanDesc scan;
4008  HeapTuple tuple;
4009  bool isnull;
4010 
4011  rel = table_open(classid, AccessShareLock);
4012 
4013  ScanKeyInit(&entry[0],
4014  get_object_attnum_oid(classid),
4015  BTEqualStrategyNumber, F_OIDEQ,
4016  ObjectIdGetDatum(objectid));
4017 
4018  scan = systable_beginscan(rel,
4019  get_object_oid_index(classid), true,
4020  NULL, 1, entry);
4021 
4022  tuple = systable_getnext(scan);
4023  if (!HeapTupleIsValid(tuple))
4024  ereport(ERROR,
4025  (errcode(ERRCODE_UNDEFINED_OBJECT),
4026  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4027 
4028  ownerId = DatumGetObjectId(heap_getattr(tuple,
4029  get_object_attnum_owner(classid),
4030  RelationGetDescr(rel),
4031  &isnull));
4032  Assert(!isnull);
4033 
4034  systable_endscan(scan);
4036  }
4037 
4038  return has_privs_of_role(roleid, ownerId);
4039 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define AccessShareLock
Definition: lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
int get_object_catcache_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)
const char * get_object_class_descr(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
#define RelationGetDescr(relation)
Definition: rel.h:529
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:1110
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, Assert(), BTEqualStrategyNumber, DatumGetObjectId(), ereport, errcode(), errmsg(), ERROR, get_object_attnum_oid(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), get_object_oid_index(), has_privs_of_role(), heap_getattr(), HeapTupleIsValid, ObjectIdGetDatum(), RelationGetDescr, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), superuser_arg(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterType(), AlterTypeNamespace_oid(), AlterTypeOwner(), ATExecChangeOwner(), ATSimplePermissions(), be_lo_unlink(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), CreateCast(), createdb(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), DefineOpClass(), DefineQueryRewrite(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecuteTruncateGuts(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), movedb(), OperatorCreate(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), user_mapping_ddl_aclcheck(), and vacuum_is_permitted_for_relation().

◆ pg_attribute_aclcheck()

AclResult pg_attribute_aclcheck ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mode 
)

Definition at line 3794 of file aclchk.c.

3796 {
3797  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3798 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3808
int16 attnum
Definition: pg_attribute.h:74

References attnum, mode, and pg_attribute_aclcheck_ext().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), examine_simple_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), ri_ReportViolation(), and statext_is_compatible_clause().

◆ pg_attribute_aclcheck_all()

AclResult pg_attribute_aclcheck_all ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how 
)

Definition at line 3838 of file aclchk.c.

3840 {
3841  AclResult result;
3842  HeapTuple classTuple;
3843  Form_pg_class classForm;
3844  AttrNumber nattrs;
3845  AttrNumber curr_att;
3846 
3847  /*
3848  * Must fetch pg_class row to check number of attributes. As in
3849  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
3850  * throwing an error if we get any unexpected lookup errors.
3851  */
3852  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3853  if (!HeapTupleIsValid(classTuple))
3854  return ACLCHECK_NO_PRIV;
3855  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3856 
3857  nattrs = classForm->relnatts;
3858 
3859  ReleaseSysCache(classTuple);
3860 
3861  /*
3862  * Initialize result in case there are no non-dropped columns. We want to
3863  * report failure in such cases for either value of 'how'.
3864  */
3865  result = ACLCHECK_NO_PRIV;
3866 
3867  for (curr_att = 1; curr_att <= nattrs; curr_att++)
3868  {
3869  HeapTuple attTuple;
3870  AclMode attmask;
3871 
3872  attTuple = SearchSysCache2(ATTNUM,
3873  ObjectIdGetDatum(table_oid),
3874  Int16GetDatum(curr_att));
3875  if (!HeapTupleIsValid(attTuple))
3876  continue;
3877 
3878  /* ignore dropped columns */
3879  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
3880  {
3881  ReleaseSysCache(attTuple);
3882  continue;
3883  }
3884 
3885  /*
3886  * Here we hard-wire knowledge that the default ACL for a column
3887  * grants no privileges, so that we can fall out quickly in the very
3888  * common case where attacl is null.
3889  */
3890  if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
3891  attmask = 0;
3892  else
3893  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
3894  mode, ACLMASK_ANY);
3895 
3896  ReleaseSysCache(attTuple);
3897 
3898  if (attmask != 0)
3899  {
3900  result = ACLCHECK_OK;
3901  if (how == ACLMASK_ANY)
3902  break; /* succeed on any success */
3903  }
3904  else
3905  {
3906  result = ACLCHECK_NO_PRIV;
3907  if (how == ACLMASK_ALL)
3908  break; /* fail on any failure */
3909  }
3910  }
3911 
3912  return result;
3913 }
static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3148
int16 AttrNumber
Definition: attnum.h:21
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:829
@ ATTNUM
Definition: syscache.h:41
@ RELOID
Definition: syscache.h:89

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ALL, ACLMASK_ANY, ATTNUM, GETSTRUCT, heap_attisnull(), HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pg_attribute_aclmask(), ReleaseSysCache(), RELOID, SearchSysCache1(), and SearchSysCache2().

Referenced by ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), and statext_is_compatible_clause().

◆ pg_attribute_aclcheck_ext()

AclResult pg_attribute_aclcheck_ext ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mode,
bool is_missing 
)

Definition at line 3808 of file aclchk.c.

3810 {
3811  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3812  ACLMASK_ANY, is_missing) != 0)
3813  return ACLCHECK_OK;
3814  else
3815  return ACLCHECK_NO_PRIV;
3816 }
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3162

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, attnum, mode, and pg_attribute_aclmask_ext().

Referenced by column_privilege_check(), and pg_attribute_aclcheck().

◆ pg_class_aclcheck()

AclResult pg_class_aclcheck ( Oid  table_oid,
Oid  roleid,
AclMode  mode 
)

Definition at line 3923 of file aclchk.c.

3924 {
3925  return pg_class_aclcheck_ext(table_oid, roleid, mode, NULL);
3926 }
AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3935

References mode, and pg_class_aclcheck_ext().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), cluster_is_permitted_for_relation(), CreateTriggerFiringOn(), currtid_internal(), currval_oid(), do_setval(), examine_simple_variable(), examine_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), get_rel_from_relname(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), has_partition_ancestor_privs(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), lastval(), LockTableAclCheck(), LogicalRepSyncTableStart(), nextval_internal(), pg_prewarm(), pg_sequence_last_value(), pg_sequence_parameters(), pgrowlocks(), RangeVarCallbackForReindexIndex(), RangeVarCallbackMaintainsTable(), ReindexMultipleTables(), ri_ReportViolation(), statext_is_compatible_clause(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), and vacuum_is_permitted_for_relation().

◆ pg_class_aclcheck_ext()

AclResult pg_class_aclcheck_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
bool is_missing 
)

Definition at line 3935 of file aclchk.c.

3937 {
3938  if (pg_class_aclmask_ext(table_oid, roleid, mode,
3939  ACLMASK_ANY, is_missing) != 0)
3940  return ACLCHECK_OK;
3941  else
3942  return ACLCHECK_NO_PRIV;
3943 }
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3280

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, and pg_class_aclmask_ext().

Referenced by column_privilege_check(), and pg_class_aclcheck().

◆ pg_class_aclmask()

AclMode pg_class_aclmask ( Oid  table_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3267 of file aclchk.c.

3269 {
3270  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3271 }

References pg_class_aclmask_ext().

Referenced by ExecCheckOneRelPerms(), and pg_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

AclResult pg_largeobject_aclcheck_snapshot ( Oid  lobj_oid,
Oid  roleid,
AclMode  mode,
Snapshot  snapshot 
)

Definition at line 3962 of file aclchk.c.

3964 {
3965  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
3966  ACLMASK_ANY, snapshot) != 0)
3967  return ACLCHECK_OK;
3968  else
3969  return ACLCHECK_NO_PRIV;
3970 }
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3533

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, and pg_largeobject_aclmask_snapshot().

Referenced by be_lo_put(), and inv_open().

◆ pg_parameter_aclcheck()

AclResult pg_parameter_aclcheck ( const char *  name,
Oid  roleid,
AclMode  mode 
)

Definition at line 3950 of file aclchk.c.

3951 {
3952  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
3953  return ACLCHECK_OK;
3954  else
3955  return ACLCHECK_NO_PRIV;
3956 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3410
const char * name
Definition: encode.c:571

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, name, and pg_parameter_aclmask().

Referenced by AlterSystemSetConfigFile(), has_param_priv_byname(), set_config_option_ext(), and validate_option_array_item().

◆ recordDependencyOnNewAcl()

void recordDependencyOnNewAcl ( Oid  classId,
Oid  objectId,
int32  objsubId,
Oid  ownerId,
Acl acl 
)

Definition at line 4207 of file aclchk.c.

4209 {
4210  int nmembers;
4211  Oid *members;
4212 
4213  /* Nothing to do if ACL is defaulted */
4214  if (acl == NULL)
4215  return;
4216 
4217  /* Extract roles mentioned in ACL */
4218  nmembers = aclmembers(acl, &members);
4219 
4220  /* Update the shared dependency ACL info */
4221  updateAclDependencies(classId, objectId, objsubId,
4222  ownerId,
4223  0, NULL,
4224  nmembers, members);
4225 }
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1511
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:482

References aclmembers(), and updateAclDependencies().

Referenced by GenerateTypeDependencies(), heap_create_with_catalog(), NamespaceCreate(), and ProcedureCreate().

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4234 of file aclchk.c.

4235 {
4236  /*
4237  * pg_class / pg_attribute
4238  *
4239  * If this is a relation then we need to see if there are any sub-objects
4240  * (eg: columns) for it and, if so, be sure to call
4241  * recordExtensionInitPrivWorker() for each one.
4242  */
4243  if (classoid == RelationRelationId)
4244  {
4245  Form_pg_class pg_class_tuple;
4246  Datum aclDatum;
4247  bool isNull;
4248  HeapTuple tuple;
4249 
4250  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4251  if (!HeapTupleIsValid(tuple))
4252  elog(ERROR, "cache lookup failed for relation %u", objoid);
4253  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4254 
4255  /*
4256  * Indexes don't have permissions, neither do the pg_class rows for
4257  * composite types. (These cases are unreachable given the
4258  * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4259  */
4260  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4261  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4262  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4263  {
4264  ReleaseSysCache(tuple);
4265  return;
4266  }
4267 
4268  /*
4269  * If this isn't a sequence then it's possibly going to have
4270  * column-level ACLs associated with it.
4271  */
4272  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4273  {
4274  AttrNumber curr_att;
4275  AttrNumber nattrs = pg_class_tuple->relnatts;
4276 
4277  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4278  {
4279  HeapTuple attTuple;
4280  Datum attaclDatum;
4281 
4282  attTuple = SearchSysCache2(ATTNUM,
4283  ObjectIdGetDatum(objoid),
4284  Int16GetDatum(curr_att));
4285 
4286  if (!HeapTupleIsValid(attTuple))
4287  continue;
4288 
4289  /* ignore dropped columns */
4290  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4291  {
4292  ReleaseSysCache(attTuple);
4293  continue;
4294  }
4295 
4296  attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
4297  Anum_pg_attribute_attacl,
4298  &isNull);
4299 
4300  /* no need to do anything for a NULL ACL */
4301  if (isNull)
4302  {
4303  ReleaseSysCache(attTuple);
4304  continue;
4305  }
4306 
4307  recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4308  DatumGetAclP(attaclDatum));
4309 
4310  ReleaseSysCache(attTuple);
4311  }
4312  }
4313 
4314  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
4315  &isNull);
4316 
4317  /* Add the record, if any, for the top-level object */
4318  if (!isNull)
4319  recordExtensionInitPrivWorker(objoid, classoid, 0,
4320  DatumGetAclP(aclDatum));
4321 
4322  ReleaseSysCache(tuple);
4323  }
4324  /* pg_largeobject_metadata */
4325  else if (classoid == LargeObjectMetadataRelationId)
4326  {
4327  Datum aclDatum;
4328  bool isNull;
4329  HeapTuple tuple;
4330  ScanKeyData entry[1];
4331  SysScanDesc scan;
4332  Relation relation;
4333 
4334  /*
4335  * Note: this is dead code, given that we don't allow large objects to
4336  * be made extension members. But it seems worth carrying in case
4337  * some future caller of this function has need for it.
4338  */
4339  relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock);
4340 
4341  /* There's no syscache for pg_largeobject_metadata */
4342  ScanKeyInit(&entry[0],
4343  Anum_pg_largeobject_metadata_oid,
4344  BTEqualStrategyNumber, F_OIDEQ,
4345  ObjectIdGetDatum(objoid));
4346 
4347  scan = systable_beginscan(relation,
4348  LargeObjectMetadataOidIndexId, true,
4349  NULL, 1, entry);
4350 
4351  tuple = systable_getnext(scan);
4352  if (!HeapTupleIsValid(tuple))
4353  elog(ERROR, "could not find tuple for large object %u", objoid);
4354 
4355  aclDatum = heap_getattr(tuple,
4356  Anum_pg_largeobject_metadata_lomacl,
4357  RelationGetDescr(relation), &isNull);
4358 
4359  /* Add the record, if any, for the top-level object */
4360  if (!isNull)
4361  recordExtensionInitPrivWorker(objoid, classoid, 0,
4362  DatumGetAclP(aclDatum));
4363 
4364  systable_endscan(scan);
4365  }
4366  /* This will error on unsupported classoid. */
4367  else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4368  {
4369  Datum aclDatum;
4370  bool isNull;
4371  HeapTuple tuple;
4372 
4373  tuple = SearchSysCache1(get_object_catcache_oid(classoid),
4374  ObjectIdGetDatum(objoid));
4375  if (!HeapTupleIsValid(tuple))
4376  elog(ERROR, "cache lookup failed for %s %u",
4377  get_object_class_descr(classoid), objoid);
4378 
4379  aclDatum = SysCacheGetAttr(get_object_catcache_oid(classoid), tuple,
4380  get_object_attnum_acl(classoid),
4381  &isNull);
4382 
4383  /* Add the record, if any, for the top-level object */
4384  if (!isNull)
4385  recordExtensionInitPrivWorker(objoid, classoid, 0,
4386  DatumGetAclP(aclDatum));
4387 
4388  ReleaseSysCache(tuple);
4389  }
4390 }
#define DatumGetAclP(X)
Definition: acl.h:120
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition: aclchk.c:4509
#define InvalidAttrNumber
Definition: attnum.h:23
#define RowExclusiveLock
Definition: lockdefs.h:38
AttrNumber get_object_attnum_acl(Oid class_id)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1079

References ATTNUM, BTEqualStrategyNumber, DatumGetAclP, elog(), ERROR, get_object_attnum_acl(), get_object_catcache_oid(), get_object_class_descr(), GETSTRUCT, heap_getattr(), HeapTupleIsValid, Int16GetDatum(), InvalidAttrNumber, ObjectIdGetDatum(), recordExtensionInitPrivWorker(), RelationGetDescr, ReleaseSysCache(), RELOID, RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SearchSysCache2(), SysCacheGetAttr(), systable_beginscan(), systable_endscan(), systable_getnext(), and table_open().

Referenced by ExecAlterExtensionContentsStmt().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4397 of file aclchk.c.

4398 {
4399  /*
4400  * If this is a relation then we need to see if there are any sub-objects
4401  * (eg: columns) for it and, if so, be sure to call
4402  * recordExtensionInitPrivWorker() for each one.
4403  */
4404  if (classoid == RelationRelationId)
4405  {
4406  Form_pg_class pg_class_tuple;
4407  HeapTuple tuple;
4408 
4409  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4410  if (!HeapTupleIsValid(tuple))
4411  elog(ERROR, "cache lookup failed for relation %u", objoid);
4412  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4413 
4414  /*
4415  * Indexes don't have permissions, neither do the pg_class rows for
4416  * composite types. (These cases are unreachable given the
4417  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4418  */
4419  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4420  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4421  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4422  {
4423  ReleaseSysCache(tuple);
4424  return;
4425  }
4426 
4427  /*
4428  * If this isn't a sequence then it's possibly going to have
4429  * column-level ACLs associated with it.
4430  */
4431  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4432  {
4433  AttrNumber curr_att;
4434  AttrNumber nattrs = pg_class_tuple->relnatts;
4435 
4436  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4437  {
4438  HeapTuple attTuple;
4439 
4440  attTuple = SearchSysCache2(ATTNUM,
4441  ObjectIdGetDatum(objoid),
4442  Int16GetDatum(curr_att));
4443 
4444  if (!HeapTupleIsValid(attTuple))
4445  continue;
4446 
4447  /* when removing, remove all entries, even dropped columns */
4448 
4449  recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4450 
4451  ReleaseSysCache(attTuple);
4452  }
4453  }
4454 
4455  ReleaseSysCache(tuple);
4456  }
4457 
4458  /* Remove the record, if any, for the top-level object */
4459  recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4460 }

References ATTNUM, elog(), ERROR, GETSTRUCT, HeapTupleIsValid, Int16GetDatum(), ObjectIdGetDatum(), recordExtensionInitPrivWorker(), ReleaseSysCache(), RELOID, SearchSysCache1(), and SearchSysCache2().

Referenced by ExecAlterExtensionContentsStmt().

◆ RemoveRoleFromObjectACL()

void RemoveRoleFromObjectACL ( Oid  roleid,
Oid  classid,
Oid  objid 
)

Definition at line 1444 of file aclchk.c.

1445 {
1446  if (classid == DefaultAclRelationId)
1447  {
1448  InternalDefaultACL iacls;
1449  Form_pg_default_acl pg_default_acl_tuple;
1450  Relation rel;
1451  ScanKeyData skey[1];
1452  SysScanDesc scan;
1453  HeapTuple tuple;
1454 
1455  /* first fetch info needed by SetDefaultACL */
1456  rel = table_open(DefaultAclRelationId, AccessShareLock);
1457 
1458  ScanKeyInit(&skey[0],
1459  Anum_pg_default_acl_oid,
1460  BTEqualStrategyNumber, F_OIDEQ,
1461  ObjectIdGetDatum(objid));
1462 
1463  scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1464  NULL, 1, skey);
1465 
1466  tuple = systable_getnext(scan);
1467 
1468  if (!HeapTupleIsValid(tuple))
1469  elog(ERROR, "could not find tuple for default ACL %u", objid);
1470 
1471  pg_default_acl_tuple = (Form_pg_default_acl) GETSTRUCT(tuple);
1472 
1473  iacls.roleid = pg_default_acl_tuple->defaclrole;
1474  iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1475 
1476  switch (pg_default_acl_tuple->defaclobjtype)
1477  {
1478  case DEFACLOBJ_RELATION:
1479  iacls.objtype = OBJECT_TABLE;
1480  break;
1481  case DEFACLOBJ_SEQUENCE:
1482  iacls.objtype = OBJECT_SEQUENCE;
1483  break;
1484  case DEFACLOBJ_FUNCTION:
1485  iacls.objtype = OBJECT_FUNCTION;
1486  break;
1487  case DEFACLOBJ_TYPE:
1488  iacls.objtype = OBJECT_TYPE;
1489  break;
1490  case DEFACLOBJ_NAMESPACE:
1491  iacls.objtype = OBJECT_SCHEMA;
1492  break;
1493  default:
1494  /* Shouldn't get here */
1495  elog(ERROR, "unexpected default ACL type: %d",
1496  (int) pg_default_acl_tuple->defaclobjtype);
1497  break;
1498  }
1499 
1500  systable_endscan(scan);
1502 
1503  iacls.is_grant = false;
1504  iacls.all_privs = true;
1505  iacls.privileges = ACL_NO_RIGHTS;
1506  iacls.grantees = list_make1_oid(roleid);
1507  iacls.grant_option = false;
1508  iacls.behavior = DROP_CASCADE;
1509 
1510  /* Do it */
1511  SetDefaultACL(&iacls);
1512  }
1513  else
1514  {
1515  InternalGrant istmt;
1516 
1517  switch (classid)
1518  {
1519  case RelationRelationId:
1520  /* it's OK to use TABLE for a sequence */
1521  istmt.objtype = OBJECT_TABLE;
1522  break;
1523  case DatabaseRelationId:
1524  istmt.objtype = OBJECT_DATABASE;
1525  break;
1526  case TypeRelationId:
1527  istmt.objtype = OBJECT_TYPE;
1528  break;
1529  case ProcedureRelationId:
1530  istmt.objtype = OBJECT_ROUTINE;
1531  break;
1532  case LanguageRelationId:
1533  istmt.objtype = OBJECT_LANGUAGE;
1534  break;
1535  case LargeObjectRelationId:
1536  istmt.objtype = OBJECT_LARGEOBJECT;
1537  break;
1538  case NamespaceRelationId:
1539  istmt.objtype = OBJECT_SCHEMA;
1540  break;
1541  case TableSpaceRelationId:
1542  istmt.objtype = OBJECT_TABLESPACE;
1543  break;
1544  case ForeignServerRelationId:
1546  break;
1547  case ForeignDataWrapperRelationId:
1548  istmt.objtype = OBJECT_FDW;
1549  break;
1550  case ParameterAclRelationId:
1551  istmt.objtype = OBJECT_PARAMETER_ACL;
1552  break;
1553  default:
1554  elog(ERROR, "unexpected object class %u", classid);
1555  break;
1556  }
1557  istmt.is_grant = false;
1558  istmt.objects = list_make1_oid(objid);
1559  istmt.all_privs = true;
1560  istmt.privileges = ACL_NO_RIGHTS;
1561  istmt.col_privs = NIL;
1562  istmt.grantees = list_make1_oid(roleid);
1563  istmt.grant_option = false;
1564  istmt.behavior = DROP_CASCADE;
1565 
1566  ExecGrantStmt_oids(&istmt);
1567  }
1568 }
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition: aclchk.c:1193
@ DROP_CASCADE
Definition: parsenodes.h:2156
FormData_pg_default_acl * Form_pg_default_acl
#define list_make1_oid(x1)
Definition: pg_list.h:242

References AccessShareLock, ACL_NO_RIGHTS, InternalDefaultACL::all_privs, InternalGrant::all_privs, InternalDefaultACL::behavior, InternalGrant::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DROP_CASCADE, elog(), ERROR, ExecGrantStmt_oids(), GETSTRUCT, InternalDefaultACL::grant_option, InternalGrant::grant_option, InternalDefaultACL::grantees, InternalGrant::grantees, HeapTupleIsValid, InternalDefaultACL::is_grant, InternalGrant::is_grant, list_make1_oid, NIL, InternalDefaultACL::nspid, OBJECT_DATABASE, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, ObjectIdGetDatum(), InternalGrant::objects, InternalDefaultACL::objtype, InternalGrant::objtype, InternalDefaultACL::privileges, InternalGrant::privileges, InternalDefaultACL::roleid, ScanKeyInit(), SetDefaultACL(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by shdepDropOwned().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5124 of file acl.c.

5125 {
5126  Oid admin_role;
5127 
5128  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5129  if (member == role)
5130  return InvalidOid;
5131 
5132  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5133  return admin_role;
5134 }

References InvalidOid, ROLERECURSE_PRIVS, and roles_is_member_of().

Referenced by check_role_grantor().

◆ select_best_grantor()

void select_best_grantor ( Oid  roleId,
AclMode  privileges,
const Acl acl,
Oid  ownerId,
Oid grantorId,
AclMode grantOptions 
)

Definition at line 5179 of file acl.c.

5182 {
5183  AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5184  List *roles_list;
5185  int nrights;
5186  ListCell *l;
5187 
5188  /*
5189  * The object owner is always treated as having all grant options, so if
5190  * roleId is the owner it's easy. Also, if roleId is a superuser it's
5191  * easy: superusers are implicitly members of every role, so they act as
5192  * the object owner.
5193  */
5194  if (roleId == ownerId || superuser_arg(roleId))
5195  {
5196  *grantorId = ownerId;
5197  *grantOptions = needed_goptions;
5198  return;
5199  }
5200 
5201  /*
5202  * Otherwise we have to do a careful search to see if roleId has the
5203  * privileges of any suitable role. Note: we can hang onto the result of
5204  * roles_is_member_of() throughout this loop, because aclmask_direct()
5205  * doesn't query any role memberships.
5206  */
5207  roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5208  InvalidOid, NULL);
5209 
5210  /* initialize candidate result as default */
5211  *grantorId = roleId;
5212  *grantOptions = ACL_NO_RIGHTS;
5213  nrights = 0;
5214 
5215  foreach(l, roles_list)
5216  {
5217  Oid otherrole = lfirst_oid(l);
5218  AclMode otherprivs;
5219 
5220  otherprivs = aclmask_direct(acl, otherrole, ownerId,
5221  needed_goptions, ACLMASK_ALL);
5222  if (otherprivs == needed_goptions)
5223  {
5224  /* Found a suitable grantor */
5225  *grantorId = otherrole;
5226  *grantOptions = otherprivs;
5227  return;
5228  }
5229 
5230  /*
5231  * If it has just some of the needed privileges, remember best
5232  * candidate.
5233  */
5234  if (otherprivs != ACL_NO_RIGHTS)
5235  {
5236  int nnewrights = count_one_bits(otherprivs);
5237 
5238  if (nnewrights > nrights)
5239  {
5240  *grantorId = otherrole;
5241  *grantOptions = otherprivs;
5242  nrights = nnewrights;
5243  }
5244  }
5245  }
5246 }
static int count_one_bits(AclMode mask)
Definition: acl.c:5139
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1448
#define ACL_GRANT_OPTION_FOR(privs)
Definition: acl.h:70
#define lfirst_oid(lc)
Definition: pg_list.h:174

References ACL_GRANT_OPTION_FOR, ACL_NO_RIGHTS, ACLMASK_ALL, aclmask_direct(), count_one_bits(), InvalidOid, lfirst_oid, ROLERECURSE_PRIVS, roles_is_member_of(), and superuser_arg().

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), and ExecGrant_Relation().