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 object_aclcheck_ext (Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
 
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_attribute_aclcheck_all_ext (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
 
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)
 
void ReplaceRoleInInitPriv (Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
 
void RemoveRoleFromInitPriv (Oid roleid, Oid classid, Oid objid, int32 objsubid)
 
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:74

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 2700 of file aclchk.c.

2702 {
2703  switch (aclerr)
2704  {
2705  case ACLCHECK_OK:
2706  /* no error, so return to caller */
2707  break;
2708  case ACLCHECK_NO_PRIV:
2709  {
2710  const char *msg = "???";
2711 
2712  switch (objtype)
2713  {
2714  case OBJECT_AGGREGATE:
2715  msg = gettext_noop("permission denied for aggregate %s");
2716  break;
2717  case OBJECT_COLLATION:
2718  msg = gettext_noop("permission denied for collation %s");
2719  break;
2720  case OBJECT_COLUMN:
2721  msg = gettext_noop("permission denied for column %s");
2722  break;
2723  case OBJECT_CONVERSION:
2724  msg = gettext_noop("permission denied for conversion %s");
2725  break;
2726  case OBJECT_DATABASE:
2727  msg = gettext_noop("permission denied for database %s");
2728  break;
2729  case OBJECT_DOMAIN:
2730  msg = gettext_noop("permission denied for domain %s");
2731  break;
2732  case OBJECT_EVENT_TRIGGER:
2733  msg = gettext_noop("permission denied for event trigger %s");
2734  break;
2735  case OBJECT_EXTENSION:
2736  msg = gettext_noop("permission denied for extension %s");
2737  break;
2738  case OBJECT_FDW:
2739  msg = gettext_noop("permission denied for foreign-data wrapper %s");
2740  break;
2741  case OBJECT_FOREIGN_SERVER:
2742  msg = gettext_noop("permission denied for foreign server %s");
2743  break;
2744  case OBJECT_FOREIGN_TABLE:
2745  msg = gettext_noop("permission denied for foreign table %s");
2746  break;
2747  case OBJECT_FUNCTION:
2748  msg = gettext_noop("permission denied for function %s");
2749  break;
2750  case OBJECT_INDEX:
2751  msg = gettext_noop("permission denied for index %s");
2752  break;
2753  case OBJECT_LANGUAGE:
2754  msg = gettext_noop("permission denied for language %s");
2755  break;
2756  case OBJECT_LARGEOBJECT:
2757  msg = gettext_noop("permission denied for large object %s");
2758  break;
2759  case OBJECT_MATVIEW:
2760  msg = gettext_noop("permission denied for materialized view %s");
2761  break;
2762  case OBJECT_OPCLASS:
2763  msg = gettext_noop("permission denied for operator class %s");
2764  break;
2765  case OBJECT_OPERATOR:
2766  msg = gettext_noop("permission denied for operator %s");
2767  break;
2768  case OBJECT_OPFAMILY:
2769  msg = gettext_noop("permission denied for operator family %s");
2770  break;
2771  case OBJECT_PARAMETER_ACL:
2772  msg = gettext_noop("permission denied for parameter %s");
2773  break;
2774  case OBJECT_POLICY:
2775  msg = gettext_noop("permission denied for policy %s");
2776  break;
2777  case OBJECT_PROCEDURE:
2778  msg = gettext_noop("permission denied for procedure %s");
2779  break;
2780  case OBJECT_PUBLICATION:
2781  msg = gettext_noop("permission denied for publication %s");
2782  break;
2783  case OBJECT_ROUTINE:
2784  msg = gettext_noop("permission denied for routine %s");
2785  break;
2786  case OBJECT_SCHEMA:
2787  msg = gettext_noop("permission denied for schema %s");
2788  break;
2789  case OBJECT_SEQUENCE:
2790  msg = gettext_noop("permission denied for sequence %s");
2791  break;
2792  case OBJECT_STATISTIC_EXT:
2793  msg = gettext_noop("permission denied for statistics object %s");
2794  break;
2795  case OBJECT_SUBSCRIPTION:
2796  msg = gettext_noop("permission denied for subscription %s");
2797  break;
2798  case OBJECT_TABLE:
2799  msg = gettext_noop("permission denied for table %s");
2800  break;
2801  case OBJECT_TABLESPACE:
2802  msg = gettext_noop("permission denied for tablespace %s");
2803  break;
2805  msg = gettext_noop("permission denied for text search configuration %s");
2806  break;
2807  case OBJECT_TSDICTIONARY:
2808  msg = gettext_noop("permission denied for text search dictionary %s");
2809  break;
2810  case OBJECT_TYPE:
2811  msg = gettext_noop("permission denied for type %s");
2812  break;
2813  case OBJECT_VIEW:
2814  msg = gettext_noop("permission denied for view %s");
2815  break;
2816  /* these currently aren't used */
2817  case OBJECT_ACCESS_METHOD:
2818  case OBJECT_AMOP:
2819  case OBJECT_AMPROC:
2820  case OBJECT_ATTRIBUTE:
2821  case OBJECT_CAST:
2822  case OBJECT_DEFAULT:
2823  case OBJECT_DEFACL:
2824  case OBJECT_DOMCONSTRAINT:
2827  case OBJECT_ROLE:
2828  case OBJECT_RULE:
2829  case OBJECT_TABCONSTRAINT:
2830  case OBJECT_TRANSFORM:
2831  case OBJECT_TRIGGER:
2832  case OBJECT_TSPARSER:
2833  case OBJECT_TSTEMPLATE:
2834  case OBJECT_USER_MAPPING:
2835  elog(ERROR, "unsupported object type: %d", objtype);
2836  }
2837 
2838  ereport(ERROR,
2839  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2840  errmsg(msg, objectname)));
2841  break;
2842  }
2843  case ACLCHECK_NOT_OWNER:
2844  {
2845  const char *msg = "???";
2846 
2847  switch (objtype)
2848  {
2849  case OBJECT_AGGREGATE:
2850  msg = gettext_noop("must be owner of aggregate %s");
2851  break;
2852  case OBJECT_COLLATION:
2853  msg = gettext_noop("must be owner of collation %s");
2854  break;
2855  case OBJECT_CONVERSION:
2856  msg = gettext_noop("must be owner of conversion %s");
2857  break;
2858  case OBJECT_DATABASE:
2859  msg = gettext_noop("must be owner of database %s");
2860  break;
2861  case OBJECT_DOMAIN:
2862  msg = gettext_noop("must be owner of domain %s");
2863  break;
2864  case OBJECT_EVENT_TRIGGER:
2865  msg = gettext_noop("must be owner of event trigger %s");
2866  break;
2867  case OBJECT_EXTENSION:
2868  msg = gettext_noop("must be owner of extension %s");
2869  break;
2870  case OBJECT_FDW:
2871  msg = gettext_noop("must be owner of foreign-data wrapper %s");
2872  break;
2873  case OBJECT_FOREIGN_SERVER:
2874  msg = gettext_noop("must be owner of foreign server %s");
2875  break;
2876  case OBJECT_FOREIGN_TABLE:
2877  msg = gettext_noop("must be owner of foreign table %s");
2878  break;
2879  case OBJECT_FUNCTION:
2880  msg = gettext_noop("must be owner of function %s");
2881  break;
2882  case OBJECT_INDEX:
2883  msg = gettext_noop("must be owner of index %s");
2884  break;
2885  case OBJECT_LANGUAGE:
2886  msg = gettext_noop("must be owner of language %s");
2887  break;
2888  case OBJECT_LARGEOBJECT:
2889  msg = gettext_noop("must be owner of large object %s");
2890  break;
2891  case OBJECT_MATVIEW:
2892  msg = gettext_noop("must be owner of materialized view %s");
2893  break;
2894  case OBJECT_OPCLASS:
2895  msg = gettext_noop("must be owner of operator class %s");
2896  break;
2897  case OBJECT_OPERATOR:
2898  msg = gettext_noop("must be owner of operator %s");
2899  break;
2900  case OBJECT_OPFAMILY:
2901  msg = gettext_noop("must be owner of operator family %s");
2902  break;
2903  case OBJECT_PROCEDURE:
2904  msg = gettext_noop("must be owner of procedure %s");
2905  break;
2906  case OBJECT_PUBLICATION:
2907  msg = gettext_noop("must be owner of publication %s");
2908  break;
2909  case OBJECT_ROUTINE:
2910  msg = gettext_noop("must be owner of routine %s");
2911  break;
2912  case OBJECT_SEQUENCE:
2913  msg = gettext_noop("must be owner of sequence %s");
2914  break;
2915  case OBJECT_SUBSCRIPTION:
2916  msg = gettext_noop("must be owner of subscription %s");
2917  break;
2918  case OBJECT_TABLE:
2919  msg = gettext_noop("must be owner of table %s");
2920  break;
2921  case OBJECT_TYPE:
2922  msg = gettext_noop("must be owner of type %s");
2923  break;
2924  case OBJECT_VIEW:
2925  msg = gettext_noop("must be owner of view %s");
2926  break;
2927  case OBJECT_SCHEMA:
2928  msg = gettext_noop("must be owner of schema %s");
2929  break;
2930  case OBJECT_STATISTIC_EXT:
2931  msg = gettext_noop("must be owner of statistics object %s");
2932  break;
2933  case OBJECT_TABLESPACE:
2934  msg = gettext_noop("must be owner of tablespace %s");
2935  break;
2937  msg = gettext_noop("must be owner of text search configuration %s");
2938  break;
2939  case OBJECT_TSDICTIONARY:
2940  msg = gettext_noop("must be owner of text search dictionary %s");
2941  break;
2942 
2943  /*
2944  * Special cases: For these, the error message talks
2945  * about "relation", because that's where the
2946  * ownership is attached. See also
2947  * check_object_ownership().
2948  */
2949  case OBJECT_COLUMN:
2950  case OBJECT_POLICY:
2951  case OBJECT_RULE:
2952  case OBJECT_TABCONSTRAINT:
2953  case OBJECT_TRIGGER:
2954  msg = gettext_noop("must be owner of relation %s");
2955  break;
2956  /* these currently aren't used */
2957  case OBJECT_ACCESS_METHOD:
2958  case OBJECT_AMOP:
2959  case OBJECT_AMPROC:
2960  case OBJECT_ATTRIBUTE:
2961  case OBJECT_CAST:
2962  case OBJECT_DEFAULT:
2963  case OBJECT_DEFACL:
2964  case OBJECT_DOMCONSTRAINT:
2965  case OBJECT_PARAMETER_ACL:
2968  case OBJECT_ROLE:
2969  case OBJECT_TRANSFORM:
2970  case OBJECT_TSPARSER:
2971  case OBJECT_TSTEMPLATE:
2972  case OBJECT_USER_MAPPING:
2973  elog(ERROR, "unsupported object type: %d", objtype);
2974  }
2975 
2976  ereport(ERROR,
2977  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2978  errmsg(msg, objectname)));
2979  break;
2980  }
2981  default:
2982  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2983  break;
2984  }
2985 }
#define gettext_noop(x)
Definition: c.h:1196
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2275
@ OBJECT_FDW
Definition: parsenodes.h:2277
@ OBJECT_TSPARSER
Definition: parsenodes.h:2308
@ OBJECT_COLLATION
Definition: parsenodes.h:2268
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2311
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2261
@ OBJECT_OPCLASS
Definition: parsenodes.h:2285
@ OBJECT_DEFACL
Definition: parsenodes.h:2272
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2262
@ OBJECT_MATVIEW
Definition: parsenodes.h:2284
@ OBJECT_SCHEMA
Definition: parsenodes.h:2297
@ OBJECT_POLICY
Definition: parsenodes.h:2289
@ OBJECT_OPERATOR
Definition: parsenodes.h:2286
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2279
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2306
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2287
@ OBJECT_DOMAIN
Definition: parsenodes.h:2273
@ OBJECT_COLUMN
Definition: parsenodes.h:2267
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2303
@ OBJECT_ROLE
Definition: parsenodes.h:2294
@ OBJECT_ROUTINE
Definition: parsenodes.h:2295
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2283
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2292
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2290
@ OBJECT_EXTENSION
Definition: parsenodes.h:2276
@ OBJECT_INDEX
Definition: parsenodes.h:2281
@ OBJECT_DEFAULT
Definition: parsenodes.h:2271
@ OBJECT_DATABASE
Definition: parsenodes.h:2270
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2298
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2309
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2282
@ OBJECT_AMOP
Definition: parsenodes.h:2263
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2293
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2278
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2307
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2265
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2291
@ OBJECT_RULE
Definition: parsenodes.h:2296
@ OBJECT_CONVERSION
Definition: parsenodes.h:2269
@ OBJECT_AMPROC
Definition: parsenodes.h:2264
@ OBJECT_TABLE
Definition: parsenodes.h:2302
@ OBJECT_VIEW
Definition: parsenodes.h:2312
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2288
@ OBJECT_TYPE
Definition: parsenodes.h:2310
@ OBJECT_FUNCTION
Definition: parsenodes.h:2280
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2301
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2274
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2299
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2300
@ OBJECT_CAST
Definition: parsenodes.h:2266
@ OBJECT_TRIGGER
Definition: parsenodes.h:2305
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2304

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(), checkPartition(), 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(), ValidateOperatorReference(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

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

Definition at line 2989 of file aclchk.c.

2991 {
2992  switch (aclerr)
2993  {
2994  case ACLCHECK_OK:
2995  /* no error, so return to caller */
2996  break;
2997  case ACLCHECK_NO_PRIV:
2998  ereport(ERROR,
2999  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3000  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3001  colname, objectname)));
3002  break;
3003  case ACLCHECK_NOT_OWNER:
3004  /* relation msg is OK since columns don't have separate owners */
3005  aclcheck_error(aclerr, objtype, objectname);
3006  break;
3007  default:
3008  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3009  break;
3010  }
3011 }
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2700

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 460 of file acl.c.

461 {
462  Acl *result_acl;
463 
464  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
465 
466  memcpy(ACL_DAT(result_acl),
467  ACL_DAT(left_acl),
468  ACL_NUM(left_acl) * sizeof(AclItem));
469 
470  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
471  ACL_DAT(right_acl),
472  ACL_NUM(right_acl) * sizeof(AclItem));
473 
474  return result_acl;
475 }
static Acl * allocacl(int n)
Definition: acl.c:409
#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 440 of file acl.c.

441 {
442  Acl *result_acl;
443 
444  result_acl = allocacl(ACL_NUM(orig_acl));
445 
446  memcpy(ACL_DAT(result_acl),
447  ACL_DAT(orig_acl),
448  ACL_NUM(orig_acl) * sizeof(AclItem));
449 
450  return result_acl;
451 }

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 786 of file acl.c.

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

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 542 of file acl.c.

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

References ACL_DAT, and ACL_NUM.

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

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 528 of file acl.c.

529 {
530  if (acl != NULL && ACL_NUM(acl) > 1)
531  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
532 }
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:707
#define qsort(a, b, c, d)
Definition: port.h:453

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 1371 of file acl.c.

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

◆ aclmembers()

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

Definition at line 1523 of file acl.c.

1524 {
1525  Oid *list;
1526  const AclItem *acldat;
1527  int i,
1528  j;
1529 
1530  if (acl == NULL || ACL_NUM(acl) == 0)
1531  {
1532  *roleids = NULL;
1533  return 0;
1534  }
1535 
1536  check_acl(acl);
1537 
1538  /* Allocate the worst-case space requirement */
1539  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1540  acldat = ACL_DAT(acl);
1541 
1542  /*
1543  * Walk the ACL collecting mentioned RoleIds.
1544  */
1545  j = 0;
1546  for (i = 0; i < ACL_NUM(acl); i++)
1547  {
1548  const AclItem *ai = &acldat[i];
1549 
1550  if (ai->ai_grantee != ACL_ID_PUBLIC)
1551  list[j++] = ai->ai_grantee;
1552  /* grantor is currently never PUBLIC, but let's check anyway */
1553  if (ai->ai_grantor != ACL_ID_PUBLIC)
1554  list[j++] = ai->ai_grantor;
1555  }
1556 
1557  /* Sort the array */
1558  qsort(list, j, sizeof(Oid), oid_cmp);
1559 
1560  /*
1561  * We could repalloc the array down to minimum size, but it's hardly worth
1562  * it since it's only transient memory.
1563  */
1564  *roleids = list;
1565 
1566  /* Remove duplicates from the array */
1567  return qunique(list, j, sizeof(Oid), oid_cmp);
1568 }
int j
Definition: isn.c:74
void * palloc(Size size)
Definition: mcxt.c:1317
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:258
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(), recordExtensionInitPrivWorker(), RemoveRoleFromInitPriv(), ReplaceRoleInInitPriv(), and SetDefaultACL().

◆ aclmerge()

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

Definition at line 484 of file acl.c.

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

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 1102 of file acl.c.

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

◆ aclupdate()

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

Definition at line 975 of file acl.c.

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

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 5191 of file acl.c.

5192 {
5193  if (!member_can_set_role(member, role))
5194  ereport(ERROR,
5195  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5196  errmsg("must be able to SET ROLE \"%s\"",
5197  GetUserNameFromId(role, false))));
5198 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5168
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:980

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 5561 of file acl.c.

5562 {
5563  if (!role)
5564  return;
5565 
5566  if (role->roletype != ROLESPEC_CSTRING)
5567  return;
5568 
5569  if (IsReservedName(role->rolename))
5570  {
5571  if (detail_msg)
5572  ereport(ERROR,
5573  (errcode(ERRCODE_RESERVED_NAME),
5574  errmsg("role name \"%s\" is reserved",
5575  role->rolename),
5576  errdetail_internal("%s", detail_msg)));
5577  else
5578  ereport(ERROR,
5579  (errcode(ERRCODE_RESERVED_NAME),
5580  errmsg("role name \"%s\" is reserved",
5581  role->rolename)));
5582  }
5583 }
bool IsReservedName(const char *name)
Definition: catalog.c:238
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
@ ROLESPEC_CSTRING
Definition: parsenodes.h:394
RoleSpecType roletype
Definition: parsenodes.h:404
char * rolename
Definition: parsenodes.h:405

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 975 of file aclchk.c.

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

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

5421 {
5422  Oid oid;
5423 
5424  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5426  if (!OidIsValid(oid) && !missing_ok)
5427  ereport(ERROR,
5428  (errcode(ERRCODE_UNDEFINED_OBJECT),
5429  errmsg("role \"%s\" does not exist", rolname)));
5430  return oid;
5431 }
#define OidIsValid(objectId)
Definition: c.h:775
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:104

References 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(), shell_check_detail(), and worker_spi_launch().

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5539 of file acl.c.

5540 {
5541  HeapTuple tp;
5542  Form_pg_authid authForm;
5543  char *rolename;
5544 
5545  tp = get_rolespec_tuple(role);
5546  authForm = (Form_pg_authid) GETSTRUCT(tp);
5547  rolename = pstrdup(NameStr(authForm->rolname));
5548  ReleaseSysCache(tp);
5549 
5550  return rolename;
5551 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5493
#define NameStr(name)
Definition: c.h:746
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1696
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266

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 5454 of file acl.c.

5455 {
5456  Oid oid;
5457 
5458  switch (role->roletype)
5459  {
5460  case ROLESPEC_CSTRING:
5461  Assert(role->rolename);
5462  oid = get_role_oid(role->rolename, missing_ok);
5463  break;
5464 
5465  case ROLESPEC_CURRENT_ROLE:
5466  case ROLESPEC_CURRENT_USER:
5467  oid = GetUserId();
5468  break;
5469 
5470  case ROLESPEC_SESSION_USER:
5471  oid = GetSessionUserId();
5472  break;
5473 
5474  case ROLESPEC_PUBLIC:
5475  ereport(ERROR,
5476  (errcode(ERRCODE_UNDEFINED_OBJECT),
5477  errmsg("role \"%s\" does not exist", "public")));
5478  oid = InvalidOid; /* make compiler happy */
5479  break;
5480 
5481  default:
5482  elog(ERROR, "unexpected role type %d", role->roletype);
5483  }
5484 
5485  return oid;
5486 }
Oid GetSessionUserId(void)
Definition: miscinit.c:548
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:396
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:397
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:395
#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 5493 of file acl.c.

5494 {
5495  HeapTuple tuple;
5496 
5497  switch (role->roletype)
5498  {
5499  case ROLESPEC_CSTRING:
5500  Assert(role->rolename);
5501  tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5502  if (!HeapTupleIsValid(tuple))
5503  ereport(ERROR,
5504  (errcode(ERRCODE_UNDEFINED_OBJECT),
5505  errmsg("role \"%s\" does not exist", role->rolename)));
5506  break;
5507 
5508  case ROLESPEC_CURRENT_ROLE:
5509  case ROLESPEC_CURRENT_USER:
5510  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5511  if (!HeapTupleIsValid(tuple))
5512  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5513  break;
5514 
5515  case ROLESPEC_SESSION_USER:
5516  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetSessionUserId()));
5517  if (!HeapTupleIsValid(tuple))
5518  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5519  break;
5520 
5521  case ROLESPEC_PUBLIC:
5522  ereport(ERROR,
5523  (errcode(ERRCODE_UNDEFINED_OBJECT),
5524  errmsg("role \"%s\" does not exist", "public")));
5525  tuple = NULL; /* make compiler happy */
5526  break;
5527 
5528  default:
5529  elog(ERROR, "unexpected role type %d", role->roletype);
5530  }
5531 
5532  return tuple;
5533 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

References Assert, CStringGetDatum(), elog, ereport, errcode(), errmsg(), ERROR, GetSessionUserId(), GetUserId(), HeapTupleIsValid, ObjectIdGetDatum(), 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 4301 of file aclchk.c.

4302 {
4303  Acl *result;
4304  Acl *glob_acl;
4305  Acl *schema_acl;
4306  Acl *def_acl;
4307  char defaclobjtype;
4308 
4309  /*
4310  * Use NULL during bootstrap, since pg_default_acl probably isn't there
4311  * yet.
4312  */
4314  return NULL;
4315 
4316  /* Check if object type is supported in pg_default_acl */
4317  switch (objtype)
4318  {
4319  case OBJECT_TABLE:
4320  defaclobjtype = DEFACLOBJ_RELATION;
4321  break;
4322 
4323  case OBJECT_SEQUENCE:
4324  defaclobjtype = DEFACLOBJ_SEQUENCE;
4325  break;
4326 
4327  case OBJECT_FUNCTION:
4328  defaclobjtype = DEFACLOBJ_FUNCTION;
4329  break;
4330 
4331  case OBJECT_TYPE:
4332  defaclobjtype = DEFACLOBJ_TYPE;
4333  break;
4334 
4335  case OBJECT_SCHEMA:
4336  defaclobjtype = DEFACLOBJ_NAMESPACE;
4337  break;
4338 
4339  default:
4340  return NULL;
4341  }
4342 
4343  /* Look up the relevant pg_default_acl entries */
4344  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4345  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4346 
4347  /* Quick out if neither entry exists */
4348  if (glob_acl == NULL && schema_acl == NULL)
4349  return NULL;
4350 
4351  /* We need to know the hard-wired default value, too */
4352  def_acl = acldefault(objtype, ownerId);
4353 
4354  /* If there's no global entry, substitute the hard-wired default */
4355  if (glob_acl == NULL)
4356  glob_acl = def_acl;
4357 
4358  /* Merge in any per-schema privileges */
4359  result = aclmerge(glob_acl, schema_acl, ownerId);
4360 
4361  /*
4362  * For efficiency, we want to return NULL if the result equals default.
4363  * This requires sorting both arrays to get an accurate comparison.
4364  */
4365  aclitemsort(result);
4366  aclitemsort(def_acl);
4367  if (aclequal(result, def_acl))
4368  result = NULL;
4369 
4370  return result;
4371 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:542
void aclitemsort(Acl *acl)
Definition: acl.c:528
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:786
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:484
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4266
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:454

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 4242 of file aclchk.c.

4243 {
4244  bool result = false;
4245  HeapTuple utup;
4246 
4247  /* Superusers bypass all permission checking. */
4248  if (superuser_arg(roleid))
4249  return true;
4250 
4251  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4252  if (HeapTupleIsValid(utup))
4253  {
4254  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4255  ReleaseSysCache(utup);
4256  }
4257  return result;
4258 }
bool rolbypassrls
Definition: pg_authid.h:41
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

References 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 4223 of file aclchk.c.

4224 {
4225  bool result = false;
4226  HeapTuple utup;
4227 
4228  /* Superusers bypass all permission checking. */
4229  if (superuser_arg(roleid))
4230  return true;
4231 
4232  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4233  if (HeapTupleIsValid(utup))
4234  {
4235  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4236  ReleaseSysCache(utup);
4237  }
4238  return result;
4239 }
bool rolcreaterole
Definition: pg_authid.h:37

References 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 5134 of file acl.c.

5135 {
5136  /* Fast path for simple case */
5137  if (member == role)
5138  return true;
5139 
5140  /* Superusers have every privilege, so are part of every role */
5141  if (superuser_arg(member))
5142  return true;
5143 
5144  /*
5145  * Find all the roles that member has the privileges of, including
5146  * multi-level recursion, then see if target role is any one of them.
5147  */
5149  InvalidOid, NULL),
5150  role);
5151 }
@ ROLERECURSE_PRIVS
Definition: acl.c:75
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:5002
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722

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_ext(), 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 4890 of file acl.c.

4891 {
4893  {
4894  cached_db_hash =
4895  GetSysCacheHashValue1(DATABASEOID,
4897 
4898  /*
4899  * In normal mode, set a callback on any syscache invalidation of rows
4900  * of pg_auth_members (for roles_is_member_of()) pg_database (for
4901  * roles_is_member_of())
4902  */
4903  CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
4905  (Datum) 0);
4908  (Datum) 0);
4909  CacheRegisterSyscacheCallback(DATABASEOID,
4911  (Datum) 0);
4912  }
4913 }
static uint32 cached_db_hash
Definition: acl.c:80
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4920
Oid MyDatabaseId
Definition: globals.c:92
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1516
uintptr_t Datum
Definition: postgres.h:64
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:113

References cached_db_hash, CacheRegisterSyscacheCallback(), 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 5264 of file acl.c.

5265 {
5266  Oid admin_role;
5267 
5268  if (superuser_arg(member))
5269  return true;
5270 
5271  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5272  if (member == role)
5273  return false;
5274 
5275  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5276  return OidIsValid(admin_role);
5277 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:74

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 5214 of file acl.c.

5215 {
5216  /* Fast path for simple case */
5217  if (member == role)
5218  return true;
5219 
5220  /* Superusers have every privilege, so are part of every role */
5221  if (superuser_arg(member))
5222  return true;
5223 
5224  /*
5225  * Find all the roles that member is a member of, including multi-level
5226  * recursion, then see if target role is any one of them.
5227  */
5229  InvalidOid, NULL),
5230  role);
5231 }

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 5242 of file acl.c.

5243 {
5244  /* Fast path for simple case */
5245  if (member == role)
5246  return true;
5247 
5248  /*
5249  * Find all the roles that member is a member of, including multi-level
5250  * recursion, then see if target role is any one of them.
5251  */
5253  InvalidOid, NULL),
5254  role);
5255 }

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 431 of file acl.c.

432 {
433  return allocacl(0);
434 }

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5168 of file acl.c.

5169 {
5170  /* Fast path for simple case */
5171  if (member == role)
5172  return true;
5173 
5174  /* Superusers have every privilege, so can always SET ROLE */
5175  if (superuser_arg(member))
5176  return true;
5177 
5178  /*
5179  * Find all the roles that member can access via SET ROLE, including
5180  * multi-level recursion, then see if target role is any one of them.
5181  */
5183  InvalidOid, NULL),
5184  role);
5185 }
@ ROLERECURSE_SETROLE
Definition: acl.c:76

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

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

◆ object_aclcheck()

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

Definition at line 3888 of file aclchk.c.

3889 {
3890  return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3891 }
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3898
static PgChecksumMode mode
Definition: pg_checksums.c:56

References mode, and object_aclcheck_ext().

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterForeignServerOwner_internal(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTypeOwner(), 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_name(), has_database_privilege_name(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_name(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_name(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_name(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_name(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_name(), has_type_privilege_id_name(), has_type_privilege_name(), 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(), PrepareTempTablespaces(), preprocessNamespacePath(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), RenameSchema(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_aclcheck_ext()

◆ object_ownercheck()

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

Definition at line 4142 of file aclchk.c.

4143 {
4144  int cacheid;
4145  Oid ownerId;
4146 
4147  /* Superusers bypass all permission checking. */
4148  if (superuser_arg(roleid))
4149  return true;
4150 
4151  /* For large objects, the catalog to consult is pg_largeobject_metadata */
4152  if (classid == LargeObjectRelationId)
4153  classid = LargeObjectMetadataRelationId;
4154 
4155  cacheid = get_object_catcache_oid(classid);
4156  if (cacheid != -1)
4157  {
4158  /* we can get the object's tuple from the syscache */
4159  HeapTuple tuple;
4160 
4161  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4162  if (!HeapTupleIsValid(tuple))
4163  ereport(ERROR,
4164  (errcode(ERRCODE_UNDEFINED_OBJECT),
4165  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4166 
4167  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4168  tuple,
4169  get_object_attnum_owner(classid)));
4170  ReleaseSysCache(tuple);
4171  }
4172  else
4173  {
4174  /* for catalogs without an appropriate syscache */
4175  Relation rel;
4176  ScanKeyData entry[1];
4177  SysScanDesc scan;
4178  HeapTuple tuple;
4179  bool isnull;
4180 
4181  rel = table_open(classid, AccessShareLock);
4182 
4183  ScanKeyInit(&entry[0],
4184  get_object_attnum_oid(classid),
4185  BTEqualStrategyNumber, F_OIDEQ,
4186  ObjectIdGetDatum(objectid));
4187 
4188  scan = systable_beginscan(rel,
4189  get_object_oid_index(classid), true,
4190  NULL, 1, entry);
4191 
4192  tuple = systable_getnext(scan);
4193  if (!HeapTupleIsValid(tuple))
4194  ereport(ERROR,
4195  (errcode(ERRCODE_UNDEFINED_OBJECT),
4196  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4197 
4198  ownerId = DatumGetObjectId(heap_getattr(tuple,
4199  get_object_attnum_owner(classid),
4200  RelationGetDescr(rel),
4201  &isnull));
4202  Assert(!isnull);
4203 
4204  systable_endscan(scan);
4206  }
4207 
4208  return has_privs_of_role(roleid, ownerId);
4209 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
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:531
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:510
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(), checkPartition(), 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(), vacuum_is_permitted_for_relation(), and ValidateOperatorReference().

◆ pg_attribute_aclcheck()

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

Definition at line 3920 of file aclchk.c.

3922 {
3923  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3924 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3932
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 3962 of file aclchk.c.

3964 {
3965  return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3966 }
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3973

References mode, and pg_attribute_aclcheck_all_ext().

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

◆ pg_attribute_aclcheck_all_ext()

AclResult pg_attribute_aclcheck_all_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how,
bool is_missing 
)

Definition at line 3973 of file aclchk.c.

3976 {
3977  AclResult result;
3978  HeapTuple classTuple;
3979  Form_pg_class classForm;
3980  Oid ownerId;
3981  AttrNumber nattrs;
3982  AttrNumber curr_att;
3983 
3984  /*
3985  * Must fetch pg_class row to get owner ID and number of attributes.
3986  */
3987  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3988  if (!HeapTupleIsValid(classTuple))
3989  {
3990  if (is_missing != NULL)
3991  {
3992  /* return "no privileges" instead of throwing an error */
3993  *is_missing = true;
3994  return ACLCHECK_NO_PRIV;
3995  }
3996  else
3997  ereport(ERROR,
3999  errmsg("relation with OID %u does not exist",
4000  table_oid)));
4001  }
4002  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4003 
4004  ownerId = classForm->relowner;
4005  nattrs = classForm->relnatts;
4006 
4007  ReleaseSysCache(classTuple);
4008 
4009  /*
4010  * Initialize result in case there are no non-dropped columns. We want to
4011  * report failure in such cases for either value of 'how'.
4012  */
4013  result = ACLCHECK_NO_PRIV;
4014 
4015  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4016  {
4017  HeapTuple attTuple;
4018  Datum aclDatum;
4019  bool isNull;
4020  Acl *acl;
4021  AclMode attmask;
4022 
4023  attTuple = SearchSysCache2(ATTNUM,
4024  ObjectIdGetDatum(table_oid),
4025  Int16GetDatum(curr_att));
4026 
4027  /*
4028  * Lookup failure probably indicates that the table was just dropped,
4029  * but we'll treat it the same as a dropped column rather than
4030  * throwing error.
4031  */
4032  if (!HeapTupleIsValid(attTuple))
4033  continue;
4034 
4035  /* ignore dropped columns */
4036  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4037  {
4038  ReleaseSysCache(attTuple);
4039  continue;
4040  }
4041 
4042  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
4043  &isNull);
4044 
4045  /*
4046  * Here we hard-wire knowledge that the default ACL for a column
4047  * grants no privileges, so that we can fall out quickly in the very
4048  * common case where attacl is null.
4049  */
4050  if (isNull)
4051  attmask = 0;
4052  else
4053  {
4054  /* detoast column's ACL if necessary */
4055  acl = DatumGetAclP(aclDatum);
4056 
4057  attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4058 
4059  /* if we have a detoasted copy, free it */
4060  if ((Pointer) acl != DatumGetPointer(aclDatum))
4061  pfree(acl);
4062  }
4063 
4064  ReleaseSysCache(attTuple);
4065 
4066  if (attmask != 0)
4067  {
4068  result = ACLCHECK_OK;
4069  if (how == ACLMASK_ANY)
4070  break; /* succeed on any success */
4071  }
4072  else
4073  {
4074  result = ACLCHECK_NO_PRIV;
4075  if (how == ACLMASK_ALL)
4076  break; /* fail on any failure */
4077  }
4078  }
4079 
4080  return result;
4081 }
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1371
#define DatumGetAclP(X)
Definition: acl.h:120
int16 AttrNumber
Definition: attnum.h:21
char * Pointer
Definition: c.h:483
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:479
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:229

References ACLCHECK_NO_PRIV, ACLCHECK_OK, aclmask(), ACLMASK_ALL, ACLMASK_ANY, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttr().

Referenced by has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_name_id(), and pg_attribute_aclcheck_all().

◆ pg_attribute_aclcheck_ext()

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

Definition at line 3932 of file aclchk.c.

3934 {
3935  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3936  ACLMASK_ANY, is_missing) != 0)
3937  return ACLCHECK_OK;
3938  else
3939  return ACLCHECK_NO_PRIV;
3940 }
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3210

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()

◆ pg_class_aclcheck_ext()

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

Definition at line 4101 of file aclchk.c.

4103 {
4104  if (pg_class_aclmask_ext(table_oid, roleid, mode,
4105  ACLMASK_ANY, is_missing) != 0)
4106  return ACLCHECK_OK;
4107  else
4108  return ACLCHECK_NO_PRIV;
4109 }
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3334

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

Referenced by column_privilege_check(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_name_id(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_name_id(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_name_id(), and pg_class_aclcheck().

◆ pg_class_aclmask()

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

Definition at line 3324 of file aclchk.c.

3326 {
3327  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3328 }

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 4128 of file aclchk.c.

4130 {
4131  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4132  ACLMASK_ANY, snapshot) != 0)
4133  return ACLCHECK_OK;
4134  else
4135  return ACLCHECK_NO_PRIV;
4136 }
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3587

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

Referenced by inv_open().

◆ pg_parameter_aclcheck()

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

Definition at line 4116 of file aclchk.c.

4117 {
4118  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4119  return ACLCHECK_OK;
4120  else
4121  return ACLCHECK_NO_PRIV;
4122 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3464
const char * name

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

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

◆ recordDependencyOnNewAcl()

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

Definition at line 4377 of file aclchk.c.

4379 {
4380  int nmembers;
4381  Oid *members;
4382 
4383  /* Nothing to do if ACL is defaulted */
4384  if (acl == NULL)
4385  return;
4386 
4387  /* Extract roles mentioned in ACL */
4388  nmembers = aclmembers(acl, &members);
4389 
4390  /* Update the shared dependency ACL info */
4391  updateAclDependencies(classId, objectId, objsubId,
4392  ownerId,
4393  0, NULL,
4394  nmembers, members);
4395 }
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1523
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:491

References aclmembers(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4404 of file aclchk.c.

4405 {
4406  /*
4407  * pg_class / pg_attribute
4408  *
4409  * If this is a relation then we need to see if there are any sub-objects
4410  * (eg: columns) for it and, if so, be sure to call
4411  * recordExtensionInitPrivWorker() for each one.
4412  */
4413  if (classoid == RelationRelationId)
4414  {
4415  Form_pg_class pg_class_tuple;
4416  Datum aclDatum;
4417  bool isNull;
4418  HeapTuple tuple;
4419 
4420  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4421  if (!HeapTupleIsValid(tuple))
4422  elog(ERROR, "cache lookup failed for relation %u", objoid);
4423  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4424 
4425  /*
4426  * Indexes don't have permissions, neither do the pg_class rows for
4427  * composite types. (These cases are unreachable given the
4428  * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4429  */
4430  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4431  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4432  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4433  {
4434  ReleaseSysCache(tuple);
4435  return;
4436  }
4437 
4438  /*
4439  * If this isn't a sequence then it's possibly going to have
4440  * column-level ACLs associated with it.
4441  */
4442  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4443  {
4444  AttrNumber curr_att;
4445  AttrNumber nattrs = pg_class_tuple->relnatts;
4446 
4447  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4448  {
4449  HeapTuple attTuple;
4450  Datum attaclDatum;
4451 
4452  attTuple = SearchSysCache2(ATTNUM,
4453  ObjectIdGetDatum(objoid),
4454  Int16GetDatum(curr_att));
4455 
4456  if (!HeapTupleIsValid(attTuple))
4457  continue;
4458 
4459  /* ignore dropped columns */
4460  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4461  {
4462  ReleaseSysCache(attTuple);
4463  continue;
4464  }
4465 
4466  attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
4467  Anum_pg_attribute_attacl,
4468  &isNull);
4469 
4470  /* no need to do anything for a NULL ACL */
4471  if (isNull)
4472  {
4473  ReleaseSysCache(attTuple);
4474  continue;
4475  }
4476 
4477  recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4478  DatumGetAclP(attaclDatum));
4479 
4480  ReleaseSysCache(attTuple);
4481  }
4482  }
4483 
4484  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
4485  &isNull);
4486 
4487  /* Add the record, if any, for the top-level object */
4488  if (!isNull)
4489  recordExtensionInitPrivWorker(objoid, classoid, 0,
4490  DatumGetAclP(aclDatum));
4491 
4492  ReleaseSysCache(tuple);
4493  }
4494  else if (classoid == LargeObjectRelationId)
4495  {
4496  /* For large objects, we must consult pg_largeobject_metadata */
4497  Datum aclDatum;
4498  bool isNull;
4499  HeapTuple tuple;
4500  ScanKeyData entry[1];
4501  SysScanDesc scan;
4502  Relation relation;
4503 
4504  /*
4505  * Note: this is dead code, given that we don't allow large objects to
4506  * be made extension members. But it seems worth carrying in case
4507  * some future caller of this function has need for it.
4508  */
4509  relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock);
4510 
4511  /* There's no syscache for pg_largeobject_metadata */
4512  ScanKeyInit(&entry[0],
4513  Anum_pg_largeobject_metadata_oid,
4514  BTEqualStrategyNumber, F_OIDEQ,
4515  ObjectIdGetDatum(objoid));
4516 
4517  scan = systable_beginscan(relation,
4518  LargeObjectMetadataOidIndexId, true,
4519  NULL, 1, entry);
4520 
4521  tuple = systable_getnext(scan);
4522  if (!HeapTupleIsValid(tuple))
4523  elog(ERROR, "could not find tuple for large object %u", objoid);
4524 
4525  aclDatum = heap_getattr(tuple,
4526  Anum_pg_largeobject_metadata_lomacl,
4527  RelationGetDescr(relation), &isNull);
4528 
4529  /* Add the record, if any, for the top-level object */
4530  if (!isNull)
4531  recordExtensionInitPrivWorker(objoid, classoid, 0,
4532  DatumGetAclP(aclDatum));
4533 
4534  systable_endscan(scan);
4535  }
4536  /* This will error on unsupported classoid. */
4537  else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4538  {
4539  int cacheid;
4540  Datum aclDatum;
4541  bool isNull;
4542  HeapTuple tuple;
4543 
4544  cacheid = get_object_catcache_oid(classoid);
4545  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4546  if (!HeapTupleIsValid(tuple))
4547  elog(ERROR, "cache lookup failed for %s %u",
4548  get_object_class_descr(classoid), objoid);
4549 
4550  aclDatum = SysCacheGetAttr(cacheid, tuple,
4551  get_object_attnum_acl(classoid),
4552  &isNull);
4553 
4554  /* Add the record, if any, for the top-level object */
4555  if (!isNull)
4556  recordExtensionInitPrivWorker(objoid, classoid, 0,
4557  DatumGetAclP(aclDatum));
4558 
4559  ReleaseSysCache(tuple);
4560  }
4561 }
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition: aclchk.c:4680
#define InvalidAttrNumber
Definition: attnum.h:23
#define RowExclusiveLock
Definition: lockdefs.h:38
AttrNumber get_object_attnum_acl(Oid class_id)

References 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(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SearchSysCache2(), SysCacheGetAttr(), systable_beginscan(), systable_endscan(), systable_getnext(), and table_open().

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4568 of file aclchk.c.

4569 {
4570  /*
4571  * If this is a relation then we need to see if there are any sub-objects
4572  * (eg: columns) for it and, if so, be sure to call
4573  * recordExtensionInitPrivWorker() for each one.
4574  */
4575  if (classoid == RelationRelationId)
4576  {
4577  Form_pg_class pg_class_tuple;
4578  HeapTuple tuple;
4579 
4580  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4581  if (!HeapTupleIsValid(tuple))
4582  elog(ERROR, "cache lookup failed for relation %u", objoid);
4583  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4584 
4585  /*
4586  * Indexes don't have permissions, neither do the pg_class rows for
4587  * composite types. (These cases are unreachable given the
4588  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4589  */
4590  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4591  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4592  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4593  {
4594  ReleaseSysCache(tuple);
4595  return;
4596  }
4597 
4598  /*
4599  * If this isn't a sequence then it's possibly going to have
4600  * column-level ACLs associated with it.
4601  */
4602  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4603  {
4604  AttrNumber curr_att;
4605  AttrNumber nattrs = pg_class_tuple->relnatts;
4606 
4607  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4608  {
4609  HeapTuple attTuple;
4610 
4611  attTuple = SearchSysCache2(ATTNUM,
4612  ObjectIdGetDatum(objoid),
4613  Int16GetDatum(curr_att));
4614 
4615  if (!HeapTupleIsValid(attTuple))
4616  continue;
4617 
4618  /* when removing, remove all entries, even dropped columns */
4619 
4620  recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4621 
4622  ReleaseSysCache(attTuple);
4623  }
4624  }
4625 
4626  ReleaseSysCache(tuple);
4627  }
4628 
4629  /* Remove the record, if any, for the top-level object */
4630  recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4631 }

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

void RemoveRoleFromInitPriv ( Oid  roleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4917 of file aclchk.c.

4918 {
4919  Relation rel;
4920  ScanKeyData key[3];
4921  SysScanDesc scan;
4922  HeapTuple oldtuple;
4923  int cacheid;
4924  HeapTuple objtuple;
4925  Oid ownerId;
4926  Datum oldAclDatum;
4927  bool isNull;
4928  Acl *old_acl;
4929  Acl *new_acl;
4930  HeapTuple newtuple;
4931  int noldmembers;
4932  int nnewmembers;
4933  Oid *oldmembers;
4934  Oid *newmembers;
4935 
4936  /* Search for existing pg_init_privs entry for the target object. */
4937  rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4938 
4939  ScanKeyInit(&key[0],
4940  Anum_pg_init_privs_objoid,
4941  BTEqualStrategyNumber, F_OIDEQ,
4942  ObjectIdGetDatum(objid));
4943  ScanKeyInit(&key[1],
4944  Anum_pg_init_privs_classoid,
4945  BTEqualStrategyNumber, F_OIDEQ,
4946  ObjectIdGetDatum(classid));
4947  ScanKeyInit(&key[2],
4948  Anum_pg_init_privs_objsubid,
4949  BTEqualStrategyNumber, F_INT4EQ,
4950  Int32GetDatum(objsubid));
4951 
4952  scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4953  NULL, 3, key);
4954 
4955  /* There should exist only one entry or none. */
4956  oldtuple = systable_getnext(scan);
4957 
4958  if (!HeapTupleIsValid(oldtuple))
4959  {
4960  /*
4961  * Hmm, why are we here if there's no entry? But pack up and go away
4962  * quietly.
4963  */
4964  systable_endscan(scan);
4966  return;
4967  }
4968 
4969  /* Get a writable copy of the existing ACL. */
4970  oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4971  RelationGetDescr(rel), &isNull);
4972  Assert(!isNull);
4973  old_acl = DatumGetAclPCopy(oldAclDatum);
4974 
4975  /*
4976  * We need the members of both old and new ACLs so we can correct the
4977  * shared dependency information. Collect data before
4978  * merge_acl_with_grant throws away old_acl.
4979  */
4980  noldmembers = aclmembers(old_acl, &oldmembers);
4981 
4982  /* Must find out the owner's OID the hard way. */
4983  cacheid = get_object_catcache_oid(classid);
4984  objtuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objid));
4985  if (!HeapTupleIsValid(objtuple))
4986  elog(ERROR, "cache lookup failed for %s %u",
4987  get_object_class_descr(classid), objid);
4988 
4989  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4990  objtuple,
4991  get_object_attnum_owner(classid)));
4992  ReleaseSysCache(objtuple);
4993 
4994  /*
4995  * Generate new ACL. Grantor of rights is always the same as the owner.
4996  */
4997  if (old_acl != NULL)
4998  new_acl = merge_acl_with_grant(old_acl,
4999  false, /* is_grant */
5000  false, /* grant_option */
5001  DROP_RESTRICT,
5002  list_make1_oid(roleid),
5004  ownerId,
5005  ownerId);
5006  else
5007  new_acl = NULL; /* this case shouldn't happen, probably */
5008 
5009  /* If we end with an empty ACL, delete the pg_init_privs entry. */
5010  if (new_acl == NULL || ACL_NUM(new_acl) == 0)
5011  {
5012  CatalogTupleDelete(rel, &oldtuple->t_self);
5013  }
5014  else
5015  {
5016  Datum values[Natts_pg_init_privs] = {0};
5017  bool nulls[Natts_pg_init_privs] = {0};
5018  bool replaces[Natts_pg_init_privs] = {0};
5019 
5020  /* Update existing entry. */
5021  values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
5022  replaces[Anum_pg_init_privs_initprivs - 1] = true;
5023 
5024  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
5025  values, nulls, replaces);
5026  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
5027  }
5028 
5029  /*
5030  * Update the shared dependency ACL info.
5031  */
5032  nnewmembers = aclmembers(new_acl, &newmembers);
5033 
5034  updateInitAclDependencies(classid, objid, objsubid,
5035  noldmembers, oldmembers,
5036  nnewmembers, newmembers);
5037 
5038  systable_endscan(scan);
5039 
5040  /* prevent error when processing objects multiple times */
5042 
5044 }
#define ACLITEM_ALL_PRIV_BITS
Definition: acl.h:87
#define DatumGetAclPCopy(X)
Definition: acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition: aclchk.c:181
static Datum values[MAXATTR]
Definition: bootstrap.c:150
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1209
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
#define list_make1_oid(x1)
Definition: pg_list.h:242
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:512
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
ItemPointerData t_self
Definition: htup.h:65
void CommandCounterIncrement(void)
Definition: xact.c:1098

References ACL_NUM, ACLITEM_ALL_PRIV_BITS, aclmembers(), Assert, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, DatumGetObjectId(), DROP_RESTRICT, elog, ERROR, get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), sort-test::key, list_make1_oid, merge_acl_with_grant(), ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1465 of file aclchk.c.

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

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().

◆ ReplaceRoleInInitPriv()

void ReplaceRoleInInitPriv ( Oid  oldroleid,
Oid  newroleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4808 of file aclchk.c.

4810 {
4811  Relation rel;
4812  ScanKeyData key[3];
4813  SysScanDesc scan;
4814  HeapTuple oldtuple;
4815  Datum oldAclDatum;
4816  bool isNull;
4817  Acl *old_acl;
4818  Acl *new_acl;
4819  HeapTuple newtuple;
4820  int noldmembers;
4821  int nnewmembers;
4822  Oid *oldmembers;
4823  Oid *newmembers;
4824 
4825  /* Search for existing pg_init_privs entry for the target object. */
4826  rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4827 
4828  ScanKeyInit(&key[0],
4829  Anum_pg_init_privs_objoid,
4830  BTEqualStrategyNumber, F_OIDEQ,
4831  ObjectIdGetDatum(objid));
4832  ScanKeyInit(&key[1],
4833  Anum_pg_init_privs_classoid,
4834  BTEqualStrategyNumber, F_OIDEQ,
4835  ObjectIdGetDatum(classid));
4836  ScanKeyInit(&key[2],
4837  Anum_pg_init_privs_objsubid,
4838  BTEqualStrategyNumber, F_INT4EQ,
4839  Int32GetDatum(objsubid));
4840 
4841  scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4842  NULL, 3, key);
4843 
4844  /* There should exist only one entry or none. */
4845  oldtuple = systable_getnext(scan);
4846 
4847  if (!HeapTupleIsValid(oldtuple))
4848  {
4849  /*
4850  * Hmm, why are we here if there's no entry? But pack up and go away
4851  * quietly.
4852  */
4853  systable_endscan(scan);
4855  return;
4856  }
4857 
4858  /* Get a writable copy of the existing ACL. */
4859  oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4860  RelationGetDescr(rel), &isNull);
4861  Assert(!isNull);
4862  old_acl = DatumGetAclPCopy(oldAclDatum);
4863 
4864  /*
4865  * Generate new ACL. This usage of aclnewowner is a bit off-label when
4866  * oldroleid isn't the owner; but it does the job fine.
4867  */
4868  new_acl = aclnewowner(old_acl, oldroleid, newroleid);
4869 
4870  /*
4871  * If we end with an empty ACL, delete the pg_init_privs entry. (That
4872  * probably can't happen here, but we may as well cover the case.)
4873  */
4874  if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4875  {
4876  CatalogTupleDelete(rel, &oldtuple->t_self);
4877  }
4878  else
4879  {
4880  Datum values[Natts_pg_init_privs] = {0};
4881  bool nulls[Natts_pg_init_privs] = {0};
4882  bool replaces[Natts_pg_init_privs] = {0};
4883 
4884  /* Update existing entry. */
4885  values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4886  replaces[Anum_pg_init_privs_initprivs - 1] = true;
4887 
4888  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4889  values, nulls, replaces);
4890  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4891  }
4892 
4893  /*
4894  * Update the shared dependency ACL info.
4895  */
4896  noldmembers = aclmembers(old_acl, &oldmembers);
4897  nnewmembers = aclmembers(new_acl, &newmembers);
4898 
4899  updateInitAclDependencies(classid, objid, objsubid,
4900  noldmembers, oldmembers,
4901  nnewmembers, newmembers);
4902 
4903  systable_endscan(scan);
4904 
4905  /* prevent error when processing objects multiple times */
4907 
4909 }
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1102

References ACL_NUM, aclmembers(), aclnewowner(), Assert, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), sort-test::key, ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepReassignOwned_InitAcl().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5289 of file acl.c.

5290 {
5291  Oid admin_role;
5292 
5293  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5294  if (member == role)
5295  return InvalidOid;
5296 
5297  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5298  return admin_role;
5299 }

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 5344 of file acl.c.

5347 {
5348  AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5349  List *roles_list;
5350  int nrights;
5351  ListCell *l;
5352 
5353  /*
5354  * The object owner is always treated as having all grant options, so if
5355  * roleId is the owner it's easy. Also, if roleId is a superuser it's
5356  * easy: superusers are implicitly members of every role, so they act as
5357  * the object owner.
5358  */
5359  if (roleId == ownerId || superuser_arg(roleId))
5360  {
5361  *grantorId = ownerId;
5362  *grantOptions = needed_goptions;
5363  return;
5364  }
5365 
5366  /*
5367  * Otherwise we have to do a careful search to see if roleId has the
5368  * privileges of any suitable role. Note: we can hang onto the result of
5369  * roles_is_member_of() throughout this loop, because aclmask_direct()
5370  * doesn't query any role memberships.
5371  */
5372  roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5373  InvalidOid, NULL);
5374 
5375  /* initialize candidate result as default */
5376  *grantorId = roleId;
5377  *grantOptions = ACL_NO_RIGHTS;
5378  nrights = 0;
5379 
5380  foreach(l, roles_list)
5381  {
5382  Oid otherrole = lfirst_oid(l);
5383  AclMode otherprivs;
5384 
5385  otherprivs = aclmask_direct(acl, otherrole, ownerId,
5386  needed_goptions, ACLMASK_ALL);
5387  if (otherprivs == needed_goptions)
5388  {
5389  /* Found a suitable grantor */
5390  *grantorId = otherrole;
5391  *grantOptions = otherprivs;
5392  return;
5393  }
5394 
5395  /*
5396  * If it has just some of the needed privileges, remember best
5397  * candidate.
5398  */
5399  if (otherprivs != ACL_NO_RIGHTS)
5400  {
5401  int nnewrights = count_one_bits(otherprivs);
5402 
5403  if (nnewrights > nrights)
5404  {
5405  *grantorId = otherrole;
5406  *grantOptions = otherprivs;
5407  nrights = nnewrights;
5408  }
5409  }
5410  }
5411 }
static int count_one_bits(AclMode mask)
Definition: acl.c:5304
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1460
#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().