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

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

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

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:449

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

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

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

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

◆ aclupdate()

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

Definition at line 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:1279
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1199
#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 5185 of file acl.c.

5186 {
5187  if (!member_can_set_role(member, role))
5188  ereport(ERROR,
5189  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5190  errmsg("must be able to SET ROLE \"%s\"",
5191  GetUserNameFromId(role, false))));
5192 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5162
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 5555 of file acl.c.

5556 {
5557  if (!role)
5558  return;
5559 
5560  if (role->roletype != ROLESPEC_CSTRING)
5561  return;
5562 
5563  if (IsReservedName(role->rolename))
5564  {
5565  if (detail_msg)
5566  ereport(ERROR,
5567  (errcode(ERRCODE_RESERVED_NAME),
5568  errmsg("role name \"%s\" is reserved",
5569  role->rolename),
5570  errdetail_internal("%s", detail_msg)));
5571  else
5572  ereport(ERROR,
5573  (errcode(ERRCODE_RESERVED_NAME),
5574  errmsg("role name \"%s\" is reserved",
5575  role->rolename)));
5576  }
5577 }
bool IsReservedName(const char *name)
Definition: catalog.c:217
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:5448
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:2612
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1160
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2655
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 5414 of file acl.c.

5415 {
5416  Oid oid;
5417 
5418  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5420  if (!OidIsValid(oid) && !missing_ok)
5421  ereport(ERROR,
5422  (errcode(ERRCODE_UNDEFINED_OBJECT),
5423  errmsg("role \"%s\" does not exist", rolname)));
5424  return oid;
5425 }
#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 5533 of file acl.c.

5534 {
5535  HeapTuple tp;
5536  Form_pg_authid authForm;
5537  char *rolename;
5538 
5539  tp = get_rolespec_tuple(role);
5540  authForm = (Form_pg_authid) GETSTRUCT(tp);
5541  rolename = pstrdup(NameStr(authForm->rolname));
5542  ReleaseSysCache(tp);
5543 
5544  return rolename;
5545 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5487
#define NameStr(name)
Definition: c.h:746
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1695
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 5448 of file acl.c.

5449 {
5450  Oid oid;
5451 
5452  switch (role->roletype)
5453  {
5454  case ROLESPEC_CSTRING:
5455  Assert(role->rolename);
5456  oid = get_role_oid(role->rolename, missing_ok);
5457  break;
5458 
5459  case ROLESPEC_CURRENT_ROLE:
5460  case ROLESPEC_CURRENT_USER:
5461  oid = GetUserId();
5462  break;
5463 
5464  case ROLESPEC_SESSION_USER:
5465  oid = GetSessionUserId();
5466  break;
5467 
5468  case ROLESPEC_PUBLIC:
5469  ereport(ERROR,
5470  (errcode(ERRCODE_UNDEFINED_OBJECT),
5471  errmsg("role \"%s\" does not exist", "public")));
5472  oid = InvalidOid; /* make compiler happy */
5473  break;
5474 
5475  default:
5476  elog(ERROR, "unexpected role type %d", role->roletype);
5477  }
5478 
5479  return oid;
5480 }
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 5487 of file acl.c.

5488 {
5489  HeapTuple tuple;
5490 
5491  switch (role->roletype)
5492  {
5493  case ROLESPEC_CSTRING:
5494  Assert(role->rolename);
5495  tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5496  if (!HeapTupleIsValid(tuple))
5497  ereport(ERROR,
5498  (errcode(ERRCODE_UNDEFINED_OBJECT),
5499  errmsg("role \"%s\" does not exist", role->rolename)));
5500  break;
5501 
5502  case ROLESPEC_CURRENT_ROLE:
5503  case ROLESPEC_CURRENT_USER:
5504  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5505  if (!HeapTupleIsValid(tuple))
5506  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5507  break;
5508 
5509  case ROLESPEC_SESSION_USER:
5510  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetSessionUserId()));
5511  if (!HeapTupleIsValid(tuple))
5512  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5513  break;
5514 
5515  case ROLESPEC_PUBLIC:
5516  ereport(ERROR,
5517  (errcode(ERRCODE_UNDEFINED_OBJECT),
5518  errmsg("role \"%s\" does not exist", "public")));
5519  tuple = NULL; /* make compiler happy */
5520  break;
5521 
5522  default:
5523  elog(ERROR, "unexpected role type %d", role->roletype);
5524  }
5525 
5526  return tuple;
5527 }
#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 4303 of file aclchk.c.

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

4245 {
4246  bool result = false;
4247  HeapTuple utup;
4248 
4249  /* Superusers bypass all permission checking. */
4250  if (superuser_arg(roleid))
4251  return true;
4252 
4253  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4254  if (HeapTupleIsValid(utup))
4255  {
4256  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4257  ReleaseSysCache(utup);
4258  }
4259  return result;
4260 }
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 4225 of file aclchk.c.

4226 {
4227  bool result = false;
4228  HeapTuple utup;
4229 
4230  /* Superusers bypass all permission checking. */
4231  if (superuser_arg(roleid))
4232  return true;
4233 
4234  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4235  if (HeapTupleIsValid(utup))
4236  {
4237  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4238  ReleaseSysCache(utup);
4239  }
4240  return result;
4241 }
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 5128 of file acl.c.

5129 {
5130  /* Fast path for simple case */
5131  if (member == role)
5132  return true;
5133 
5134  /* Superusers have every privilege, so are part of every role */
5135  if (superuser_arg(member))
5136  return true;
5137 
5138  /*
5139  * Find all the roles that member has the privileges of, including
5140  * multi-level recursion, then see if target role is any one of them.
5141  */
5143  InvalidOid, NULL),
5144  role);
5145 }
@ 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:4996
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 4884 of file acl.c.

4885 {
4887  {
4888  cached_db_hash =
4889  GetSysCacheHashValue1(DATABASEOID,
4891 
4892  /*
4893  * In normal mode, set a callback on any syscache invalidation of rows
4894  * of pg_auth_members (for roles_is_member_of()) pg_database (for
4895  * roles_is_member_of())
4896  */
4897  CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
4899  (Datum) 0);
4902  (Datum) 0);
4903  CacheRegisterSyscacheCallback(DATABASEOID,
4905  (Datum) 0);
4906  }
4907 }
static uint32 cached_db_hash
Definition: acl.c:80
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4914
Oid MyDatabaseId
Definition: globals.c:91
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 5258 of file acl.c.

5259 {
5260  Oid admin_role;
5261 
5262  if (superuser_arg(member))
5263  return true;
5264 
5265  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5266  if (member == role)
5267  return false;
5268 
5269  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5270  return OidIsValid(admin_role);
5271 }
@ 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 5208 of file acl.c.

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

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

5237 {
5238  /* Fast path for simple case */
5239  if (member == role)
5240  return true;
5241 
5242  /*
5243  * Find all the roles that member is a member of, including multi-level
5244  * recursion, then see if target role is any one of them.
5245  */
5247  InvalidOid, NULL),
5248  role);
5249 }

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

5163 {
5164  /* Fast path for simple case */
5165  if (member == role)
5166  return true;
5167 
5168  /* Superusers have every privilege, so can always SET ROLE */
5169  if (superuser_arg(member))
5170  return true;
5171 
5172  /*
5173  * Find all the roles that member can access via SET ROLE, including
5174  * multi-level recursion, then see if target role is any one of them.
5175  */
5177  InvalidOid, NULL),
5178  role);
5179 }
@ 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 3890 of file aclchk.c.

3891 {
3892  return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3893 }
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3900
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 4144 of file aclchk.c.

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

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

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

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

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

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

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

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

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

3328 {
3329  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3330 }

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

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

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

4119 {
4120  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4121  return ACLCHECK_OK;
4122  else
4123  return ACLCHECK_NO_PRIV;
4124 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3466
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 4379 of file aclchk.c.

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

References aclmembers(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4406 of file aclchk.c.

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

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4579 of file aclchk.c.

4580 {
4581  Oid ownerId;
4582 
4583  /*
4584  * If this is a relation then we need to see if there are any sub-objects
4585  * (eg: columns) for it and, if so, be sure to call
4586  * recordExtensionInitPrivWorker() for each one.
4587  */
4588  if (classoid == RelationRelationId)
4589  {
4590  Form_pg_class pg_class_tuple;
4591  HeapTuple tuple;
4592 
4593  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4594  if (!HeapTupleIsValid(tuple))
4595  elog(ERROR, "cache lookup failed for relation %u", objoid);
4596  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4597  ownerId = pg_class_tuple->relowner;
4598 
4599  /*
4600  * Indexes don't have permissions, neither do the pg_class rows for
4601  * composite types. (These cases are unreachable given the
4602  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4603  */
4604  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4605  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4606  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4607  {
4608  ReleaseSysCache(tuple);
4609  return;
4610  }
4611 
4612  /*
4613  * If this isn't a sequence then it's possibly going to have
4614  * column-level ACLs associated with it.
4615  */
4616  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4617  {
4618  AttrNumber curr_att;
4619  AttrNumber nattrs = pg_class_tuple->relnatts;
4620 
4621  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4622  {
4623  HeapTuple attTuple;
4624 
4625  attTuple = SearchSysCache2(ATTNUM,
4626  ObjectIdGetDatum(objoid),
4627  Int16GetDatum(curr_att));
4628 
4629  if (!HeapTupleIsValid(attTuple))
4630  continue;
4631 
4632  /* when removing, remove all entries, even dropped columns */
4633 
4634  recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4635  ownerId, NULL);
4636 
4637  ReleaseSysCache(attTuple);
4638  }
4639  }
4640 
4641  ReleaseSysCache(tuple);
4642  }
4643  else
4644  {
4645  /* Must find out the owner's OID the hard way */
4646  AttrNumber ownerattnum;
4647  int cacheid;
4648  HeapTuple tuple;
4649 
4650  /*
4651  * If the object is of a kind that has no owner, it should not have
4652  * any pg_init_privs entry either.
4653  */
4654  ownerattnum = get_object_attnum_owner(classoid);
4655  if (ownerattnum == InvalidAttrNumber)
4656  return;
4657  cacheid = get_object_catcache_oid(classoid);
4658  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4659  if (!HeapTupleIsValid(tuple))
4660  elog(ERROR, "cache lookup failed for %s %u",
4661  get_object_class_descr(classoid), objoid);
4662 
4663  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4664  tuple,
4665  ownerattnum));
4666 
4667  ReleaseSysCache(tuple);
4668  }
4669 
4670  /* Remove the record, if any, for the top-level object */
4671  recordExtensionInitPrivWorker(objoid, classoid, 0, ownerId, NULL);
4672 }

References DatumGetObjectId(), elog, ERROR, get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), GETSTRUCT, HeapTupleIsValid, Int16GetDatum(), InvalidAttrNumber, ObjectIdGetDatum(), recordExtensionInitPrivWorker(), ReleaseSysCache(), SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttrNotNull().

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

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

Definition at line 4855 of file aclchk.c.

4856 {
4857  Relation rel;
4858  ScanKeyData key[3];
4859  SysScanDesc scan;
4860  HeapTuple oldtuple;
4861  int cacheid;
4862  HeapTuple objtuple;
4863  Oid ownerId;
4864  Datum oldAclDatum;
4865  bool isNull;
4866  Acl *old_acl;
4867  Acl *new_acl;
4868  HeapTuple newtuple;
4869  int noldmembers;
4870  int nnewmembers;
4871  Oid *oldmembers;
4872  Oid *newmembers;
4873 
4874  /* Search for existing pg_init_privs entry for the target object. */
4875  rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4876 
4877  ScanKeyInit(&key[0],
4878  Anum_pg_init_privs_objoid,
4879  BTEqualStrategyNumber, F_OIDEQ,
4880  ObjectIdGetDatum(objid));
4881  ScanKeyInit(&key[1],
4882  Anum_pg_init_privs_classoid,
4883  BTEqualStrategyNumber, F_OIDEQ,
4884  ObjectIdGetDatum(classid));
4885  ScanKeyInit(&key[2],
4886  Anum_pg_init_privs_objsubid,
4887  BTEqualStrategyNumber, F_INT4EQ,
4888  Int32GetDatum(objsubid));
4889 
4890  scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4891  NULL, 3, key);
4892 
4893  /* There should exist only one entry or none. */
4894  oldtuple = systable_getnext(scan);
4895 
4896  if (!HeapTupleIsValid(oldtuple))
4897  {
4898  /*
4899  * Hmm, why are we here if there's no entry? But pack up and go away
4900  * quietly.
4901  */
4902  systable_endscan(scan);
4904  return;
4905  }
4906 
4907  /* Get a writable copy of the existing ACL. */
4908  oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4909  RelationGetDescr(rel), &isNull);
4910  if (!isNull)
4911  old_acl = DatumGetAclPCopy(oldAclDatum);
4912  else
4913  old_acl = NULL; /* this case shouldn't happen, probably */
4914 
4915  /*
4916  * We need the members of both old and new ACLs so we can correct the
4917  * shared dependency information. Collect data before
4918  * merge_acl_with_grant throws away old_acl.
4919  */
4920  noldmembers = aclmembers(old_acl, &oldmembers);
4921 
4922  /* Must find out the owner's OID the hard way. */
4923  cacheid = get_object_catcache_oid(classid);
4924  objtuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objid));
4925  if (!HeapTupleIsValid(objtuple))
4926  elog(ERROR, "cache lookup failed for %s %u",
4927  get_object_class_descr(classid), objid);
4928 
4929  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4930  objtuple,
4931  get_object_attnum_owner(classid)));
4932  ReleaseSysCache(objtuple);
4933 
4934  /*
4935  * Generate new ACL. Grantor of rights is always the same as the owner.
4936  */
4937  if (old_acl != NULL)
4938  new_acl = merge_acl_with_grant(old_acl,
4939  false, /* is_grant */
4940  false, /* grant_option */
4941  DROP_RESTRICT,
4942  list_make1_oid(roleid),
4944  ownerId,
4945  ownerId);
4946  else
4947  new_acl = NULL; /* this case shouldn't happen, probably */
4948 
4949  /* If we end with an empty ACL, delete the pg_init_privs entry. */
4950  if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4951  {
4952  CatalogTupleDelete(rel, &oldtuple->t_self);
4953  }
4954  else
4955  {
4956  Datum values[Natts_pg_init_privs] = {0};
4957  bool nulls[Natts_pg_init_privs] = {0};
4958  bool replaces[Natts_pg_init_privs] = {0};
4959 
4960  /* Update existing entry. */
4961  values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4962  replaces[Anum_pg_init_privs_initprivs - 1] = true;
4963 
4964  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4965  values, nulls, replaces);
4966  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4967  }
4968 
4969  /*
4970  * Update the shared dependency ACL info.
4971  */
4972  nnewmembers = aclmembers(new_acl, &newmembers);
4973 
4974  updateInitAclDependencies(classid, objid, objsubid,
4975  ownerId,
4976  noldmembers, oldmembers,
4977  nnewmembers, newmembers);
4978 
4979  systable_endscan(scan);
4980 
4981  /* prevent error when processing objects multiple times */
4983 
4985 }
#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:152
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, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:506
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:1097

References ACL_NUM, ACLITEM_ALL_PRIV_BITS, aclmembers(), 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().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5283 of file acl.c.

5284 {
5285  Oid admin_role;
5286 
5287  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5288  if (member == role)
5289  return InvalidOid;
5290 
5291  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5292  return admin_role;
5293 }

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

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