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_ALL_RIGHTS_STR   "arwdDxtXUCTcsA"
 
#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)
 
#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)
 
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 158 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsA"

Definition at line 153 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 170 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_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 173 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 180 of file acl.h.

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

Function Documentation

◆ aclcheck_error()

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

Definition at line 2695 of file aclchk.c.

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

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

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

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

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

452 {
453  Acl *result_acl;
454 
455  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
456 
457  memcpy(ACL_DAT(result_acl),
458  ACL_DAT(left_acl),
459  ACL_NUM(left_acl) * sizeof(AclItem));
460 
461  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
462  ACL_DAT(right_acl),
463  ACL_NUM(right_acl) * sizeof(AclItem));
464 
465  return result_acl;
466 }
static Acl * allocacl(int n)
Definition: acl.c:400
#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 431 of file acl.c.

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

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 777 of file acl.c.

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

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

References ACL_DAT, and ACL_NUM.

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

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 519 of file acl.c.

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

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

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclmask()

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

Definition at line 1356 of file acl.c.

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

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

Referenced by check_circularity(), LockTableAclCheck(), object_aclmask_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 1508 of file acl.c.

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

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

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

◆ aclmerge()

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

Definition at line 475 of file acl.c.

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

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

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

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

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

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

◆ check_can_set_role()

void check_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5117 of file acl.c.

5118 {
5119  if (!member_can_set_role(member, role))
5120  ereport(ERROR,
5121  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5122  errmsg("must be able to SET ROLE \"%s\"",
5123  GetUserNameFromId(role, false))));
5124 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5094
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:973

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

5488 {
5489  if (!role)
5490  return;
5491 
5492  if (role->roletype != ROLESPEC_CSTRING)
5493  return;
5494 
5495  if (IsReservedName(role->rolename))
5496  {
5497  if (detail_msg)
5498  ereport(ERROR,
5499  (errcode(ERRCODE_RESERVED_NAME),
5500  errmsg("role name \"%s\" is reserved",
5501  role->rolename),
5502  errdetail_internal("%s", detail_msg)));
5503  else
5504  ereport(ERROR,
5505  (errcode(ERRCODE_RESERVED_NAME),
5506  errmsg("role name \"%s\" is reserved",
5507  role->rolename)));
5508  }
5509 }
bool IsReservedName(const char *name)
Definition: catalog.c:219
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1229
@ ROLESPEC_CSTRING
Definition: parsenodes.h:384
RoleSpecType roletype
Definition: parsenodes.h:394
char * rolename
Definition: parsenodes.h:395

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

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

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

5347 {
5348  Oid oid;
5349 
5350  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5352  if (!OidIsValid(oid) && !missing_ok)
5353  ereport(ERROR,
5354  (errcode(ERRCODE_UNDEFINED_OBJECT),
5355  errmsg("role \"%s\" does not exist", rolname)));
5356  return oid;
5357 }
#define OidIsValid(objectId)
Definition: c.h:764
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
@ AUTHNAME
Definition: syscache.h:44
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:200

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

Referenced by aclparse(), check_hba(), check_ident_usermap(), createdb(), CreateRole(), get_object_address_unqualified(), get_role_oid_or_public(), get_rolespec_oid(), GrantRole(), is_member(), pg_has_role_id_name(), pg_has_role_name(), pg_has_role_name_id(), pg_has_role_name_name(), regrolein(), 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 5465 of file acl.c.

5466 {
5467  HeapTuple tp;
5468  Form_pg_authid authForm;
5469  char *rolename;
5470 
5471  tp = get_rolespec_tuple(role);
5472  authForm = (Form_pg_authid) GETSTRUCT(tp);
5473  rolename = pstrdup(NameStr(authForm->rolname));
5474  ReleaseSysCache(tp);
5475 
5476  return rolename;
5477 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5419
#define NameStr(name)
Definition: c.h:735
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1644
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868

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

5381 {
5382  Oid oid;
5383 
5384  switch (role->roletype)
5385  {
5386  case ROLESPEC_CSTRING:
5387  Assert(role->rolename);
5388  oid = get_role_oid(role->rolename, missing_ok);
5389  break;
5390 
5391  case ROLESPEC_CURRENT_ROLE:
5392  case ROLESPEC_CURRENT_USER:
5393  oid = GetUserId();
5394  break;
5395 
5396  case ROLESPEC_SESSION_USER:
5397  oid = GetSessionUserId();
5398  break;
5399 
5400  case ROLESPEC_PUBLIC:
5401  ereport(ERROR,
5402  (errcode(ERRCODE_UNDEFINED_OBJECT),
5403  errmsg("role \"%s\" does not exist", "public")));
5404  oid = InvalidOid; /* make compiler happy */
5405  break;
5406 
5407  default:
5408  elog(ERROR, "unexpected role type %d", role->roletype);
5409  }
5410 
5411  return oid;
5412 }
Oid GetSessionUserId(void)
Definition: miscinit.c:542
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:386
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:387
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:385
#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 5419 of file acl.c.

5420 {
5421  HeapTuple tuple;
5422 
5423  switch (role->roletype)
5424  {
5425  case ROLESPEC_CSTRING:
5426  Assert(role->rolename);
5428  if (!HeapTupleIsValid(tuple))
5429  ereport(ERROR,
5430  (errcode(ERRCODE_UNDEFINED_OBJECT),
5431  errmsg("role \"%s\" does not exist", role->rolename)));
5432  break;
5433 
5434  case ROLESPEC_CURRENT_ROLE:
5435  case ROLESPEC_CURRENT_USER:
5437  if (!HeapTupleIsValid(tuple))
5438  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5439  break;
5440 
5441  case ROLESPEC_SESSION_USER:
5443  if (!HeapTupleIsValid(tuple))
5444  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5445  break;
5446 
5447  case ROLESPEC_PUBLIC:
5448  ereport(ERROR,
5449  (errcode(ERRCODE_UNDEFINED_OBJECT),
5450  errmsg("role \"%s\" does not exist", "public")));
5451  tuple = NULL; /* make compiler happy */
5452  break;
5453 
5454  default:
5455  elog(ERROR, "unexpected role type %d", role->roletype);
5456  }
5457 
5458  return tuple;
5459 }
#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:820
@ AUTHOID
Definition: syscache.h:45

References Assert(), AUTHNAME, AUTHOID, 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 4252 of file aclchk.c.

4253 {
4254  Acl *result;
4255  Acl *glob_acl;
4256  Acl *schema_acl;
4257  Acl *def_acl;
4258  char defaclobjtype;
4259 
4260  /*
4261  * Use NULL during bootstrap, since pg_default_acl probably isn't there
4262  * yet.
4263  */
4265  return NULL;
4266 
4267  /* Check if object type is supported in pg_default_acl */
4268  switch (objtype)
4269  {
4270  case OBJECT_TABLE:
4271  defaclobjtype = DEFACLOBJ_RELATION;
4272  break;
4273 
4274  case OBJECT_SEQUENCE:
4275  defaclobjtype = DEFACLOBJ_SEQUENCE;
4276  break;
4277 
4278  case OBJECT_FUNCTION:
4279  defaclobjtype = DEFACLOBJ_FUNCTION;
4280  break;
4281 
4282  case OBJECT_TYPE:
4283  defaclobjtype = DEFACLOBJ_TYPE;
4284  break;
4285 
4286  case OBJECT_SCHEMA:
4287  defaclobjtype = DEFACLOBJ_NAMESPACE;
4288  break;
4289 
4290  default:
4291  return NULL;
4292  }
4293 
4294  /* Look up the relevant pg_default_acl entries */
4295  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4296  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4297 
4298  /* Quick out if neither entry exists */
4299  if (glob_acl == NULL && schema_acl == NULL)
4300  return NULL;
4301 
4302  /* We need to know the hard-wired default value, too */
4303  def_acl = acldefault(objtype, ownerId);
4304 
4305  /* If there's no global entry, substitute the hard-wired default */
4306  if (glob_acl == NULL)
4307  glob_acl = def_acl;
4308 
4309  /* Merge in any per-schema privileges */
4310  result = aclmerge(glob_acl, schema_acl, ownerId);
4311 
4312  /*
4313  * For efficiency, we want to return NULL if the result equals default.
4314  * This requires sorting both arrays to get an accurate comparison.
4315  */
4316  aclitemsort(result);
4317  aclitemsort(def_acl);
4318  if (aclequal(result, def_acl))
4319  result = NULL;
4320 
4321  return result;
4322 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:533
void aclitemsort(Acl *acl)
Definition: acl.c:519
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:777
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:475
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4217
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:417

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

4194 {
4195  bool result = false;
4196  HeapTuple utup;
4197 
4198  /* Superusers bypass all permission checking. */
4199  if (superuser_arg(roleid))
4200  return true;
4201 
4202  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4203  if (HeapTupleIsValid(utup))
4204  {
4205  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4206  ReleaseSysCache(utup);
4207  }
4208  return result;
4209 }
bool rolbypassrls
Definition: pg_authid.h:41
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

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

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

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4174 of file aclchk.c.

4175 {
4176  bool result = false;
4177  HeapTuple utup;
4178 
4179  /* Superusers bypass all permission checking. */
4180  if (superuser_arg(roleid))
4181  return true;
4182 
4183  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4184  if (HeapTupleIsValid(utup))
4185  {
4186  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4187  ReleaseSysCache(utup);
4188  }
4189  return result;
4190 }
bool rolcreaterole
Definition: pg_authid.h:37

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 5060 of file acl.c.

5061 {
5062  /* Fast path for simple case */
5063  if (member == role)
5064  return true;
5065 
5066  /* Superusers have every privilege, so are part of every role */
5067  if (superuser_arg(member))
5068  return true;
5069 
5070  /*
5071  * Find all the roles that member has the privileges of, including
5072  * multi-level recursion, then see if target role is any one of them.
5073  */
5075  InvalidOid, NULL),
5076  role);
5077 }
@ ROLERECURSE_PRIVS
Definition: acl.c:76
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:4935
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721

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

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

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4870 of file acl.c.

4871 {
4873  {
4874  cached_db_hash =
4877 
4878  /*
4879  * In normal mode, set a callback on any syscache invalidation of rows
4880  * of pg_auth_members (for roles_is_member_of()) pg_database (for
4881  * roles_is_member_of())
4882  */
4885  (Datum) 0);
4888  (Datum) 0);
4891  (Datum) 0);
4892  }
4893 }
static uint32 cached_db_hash
Definition: acl.c:81
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4900
Oid MyDatabaseId
Definition: globals.c:89
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1518
uintptr_t Datum
Definition: postgres.h:64
@ AUTHMEMROLEMEM
Definition: syscache.h:43
@ DATABASEOID
Definition: syscache.h:55
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:209

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 5190 of file acl.c.

5191 {
5192  Oid admin_role;
5193 
5194  if (superuser_arg(member))
5195  return true;
5196 
5197  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5198  if (member == role)
5199  return false;
5200 
5201  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5202  return OidIsValid(admin_role);
5203 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:75

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

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

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 5140 of file acl.c.

5141 {
5142  /* Fast path for simple case */
5143  if (member == role)
5144  return true;
5145 
5146  /* Superusers have every privilege, so are part of every role */
5147  if (superuser_arg(member))
5148  return true;
5149 
5150  /*
5151  * Find all the roles that member is a member of, including multi-level
5152  * recursion, then see if target role is any one of them.
5153  */
5155  InvalidOid, NULL),
5156  role);
5157 }

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

5169 {
5170  /* Fast path for simple case */
5171  if (member == role)
5172  return true;
5173 
5174  /*
5175  * Find all the roles that member is a member of, including multi-level
5176  * recursion, then see if target role is any one of them.
5177  */
5179  InvalidOid, NULL),
5180  role);
5181 }

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

423 {
424  return allocacl(0);
425 }

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5094 of file acl.c.

5095 {
5096  /* Fast path for simple case */
5097  if (member == role)
5098  return true;
5099 
5100  /* Superusers have every privilege, so can always SET ROLE */
5101  if (superuser_arg(member))
5102  return true;
5103 
5104  /*
5105  * Find all the roles that member can access via SET ROLE, including
5106  * multi-level recursion, then see if target role is any one of them.
5107  */
5109  InvalidOid, NULL),
5110  role);
5111 }
@ ROLERECURSE_SETROLE
Definition: acl.c:77

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

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

◆ object_aclcheck()

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

Definition at line 3843 of file aclchk.c.

3844 {
3845  return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3846 }
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3853
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(), ATExecAddColumn(), ATExecChangeOwner(), ATPrepAlterColumnType(), ATPrepSetTableSpace(), BuildDescForRelation(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_temp_tablespaces(), CheckFunctionValidatorAccess(), CheckMyDatabase(), compute_return_type(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreatePublication(), CreateSchemaCommand(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), extension_is_trusted(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), HandleFunctionRequest(), has_database_privilege_id_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 4097 of file aclchk.c.

4098 {
4099  int cacheid;
4100  Oid ownerId;
4101 
4102  /* Superusers bypass all permission checking. */
4103  if (superuser_arg(roleid))
4104  return true;
4105 
4106  cacheid = get_object_catcache_oid(classid);
4107  if (cacheid != -1)
4108  {
4109  HeapTuple tuple;
4110 
4111  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4112  if (!HeapTupleIsValid(tuple))
4113  ereport(ERROR,
4114  (errcode(ERRCODE_UNDEFINED_OBJECT),
4115  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4116 
4117  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4118  tuple,
4119  get_object_attnum_owner(classid)));
4120  ReleaseSysCache(tuple);
4121  }
4122  else
4123  {
4124  /* for catalogs without an appropriate syscache */
4125 
4126  Relation rel;
4127  ScanKeyData entry[1];
4128  SysScanDesc scan;
4129  HeapTuple tuple;
4130  bool isnull;
4131 
4132  rel = table_open(classid, AccessShareLock);
4133 
4134  ScanKeyInit(&entry[0],
4135  get_object_attnum_oid(classid),
4136  BTEqualStrategyNumber, F_OIDEQ,
4137  ObjectIdGetDatum(objectid));
4138 
4139  scan = systable_beginscan(rel,
4140  get_object_oid_index(classid), true,
4141  NULL, 1, entry);
4142 
4143  tuple = systable_getnext(scan);
4144  if (!HeapTupleIsValid(tuple))
4145  ereport(ERROR,
4146  (errcode(ERRCODE_UNDEFINED_OBJECT),
4147  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4148 
4149  ownerId = DatumGetObjectId(heap_getattr(tuple,
4150  get_object_attnum_owner(classid),
4151  RelationGetDescr(rel),
4152  &isnull));
4153  Assert(!isnull);
4154 
4155  systable_endscan(scan);
4157  }
4158 
4159  return has_privs_of_role(roleid, ownerId);
4160 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define AccessShareLock
Definition: lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
int get_object_catcache_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)
const char * get_object_class_descr(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
#define RelationGetDescr(relation)
Definition: rel.h:530
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:1112
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(), cluster_rel(), CreateCast(), createdb(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), DefineOpClass(), DefineQueryRewrite(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecuteTruncateGuts(), get_tables_to_cluster(), get_tables_to_cluster_partitioned(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), movedb(), OperatorCreate(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), user_mapping_ddl_aclcheck(), vacuum_is_relation_owner(), and ValidateOperatorReference().

◆ pg_attribute_aclcheck()

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

Definition at line 3875 of file aclchk.c.

3877 {
3878  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3879 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3887
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 3917 of file aclchk.c.

3919 {
3920  return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3921 }
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3928

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

3931 {
3932  AclResult result;
3933  HeapTuple classTuple;
3934  Form_pg_class classForm;
3935  Oid ownerId;
3936  AttrNumber nattrs;
3937  AttrNumber curr_att;
3938 
3939  /*
3940  * Must fetch pg_class row to get owner ID and number of attributes.
3941  */
3942  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3943  if (!HeapTupleIsValid(classTuple))
3944  {
3945  if (is_missing != NULL)
3946  {
3947  /* return "no privileges" instead of throwing an error */
3948  *is_missing = true;
3949  return ACLCHECK_NO_PRIV;
3950  }
3951  else
3952  ereport(ERROR,
3954  errmsg("relation with OID %u does not exist",
3955  table_oid)));
3956  }
3957  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3958 
3959  ownerId = classForm->relowner;
3960  nattrs = classForm->relnatts;
3961 
3962  ReleaseSysCache(classTuple);
3963 
3964  /*
3965  * Initialize result in case there are no non-dropped columns. We want to
3966  * report failure in such cases for either value of 'how'.
3967  */
3968  result = ACLCHECK_NO_PRIV;
3969 
3970  for (curr_att = 1; curr_att <= nattrs; curr_att++)
3971  {
3972  HeapTuple attTuple;
3973  Datum aclDatum;
3974  bool isNull;
3975  Acl *acl;
3976  AclMode attmask;
3977 
3978  attTuple = SearchSysCache2(ATTNUM,
3979  ObjectIdGetDatum(table_oid),
3980  Int16GetDatum(curr_att));
3981 
3982  /*
3983  * Lookup failure probably indicates that the table was just dropped,
3984  * but we'll treat it the same as a dropped column rather than
3985  * throwing error.
3986  */
3987  if (!HeapTupleIsValid(attTuple))
3988  continue;
3989 
3990  /* ignore dropped columns */
3991  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
3992  {
3993  ReleaseSysCache(attTuple);
3994  continue;
3995  }
3996 
3997  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3998  &isNull);
3999 
4000  /*
4001  * Here we hard-wire knowledge that the default ACL for a column
4002  * grants no privileges, so that we can fall out quickly in the very
4003  * common case where attacl is null.
4004  */
4005  if (isNull)
4006  attmask = 0;
4007  else
4008  {
4009  /* detoast column's ACL if necessary */
4010  acl = DatumGetAclP(aclDatum);
4011 
4012  attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4013 
4014  /* if we have a detoasted copy, free it */
4015  if ((Pointer) acl != DatumGetPointer(aclDatum))
4016  pfree(acl);
4017  }
4018 
4019  ReleaseSysCache(attTuple);
4020 
4021  if (attmask != 0)
4022  {
4023  result = ACLCHECK_OK;
4024  if (how == ACLMASK_ANY)
4025  break; /* succeed on any success */
4026  }
4027  else
4028  {
4029  result = ACLCHECK_NO_PRIV;
4030  if (how == ACLMASK_ALL)
4031  break; /* fail on any failure */
4032  }
4033  }
4034 
4035  return result;
4036 }
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1356
#define DatumGetAclP(X)
Definition: acl.h:120
int16 AttrNumber
Definition: attnum.h:21
char * Pointer
Definition: c.h:472
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:1081
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:831
@ ATTNUM
Definition: syscache.h:41
@ RELOID
Definition: syscache.h:89

References ACLCHECK_NO_PRIV, ACLCHECK_OK, aclmask(), ACLMASK_ALL, ACLMASK_ANY, ATTNUM, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), RELOID, 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 3887 of file aclchk.c.

3889 {
3890  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3891  ACLMASK_ANY, is_missing) != 0)
3892  return ACLCHECK_OK;
3893  else
3894  return ACLCHECK_NO_PRIV;
3895 }
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3205

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

4058 {
4059  if (pg_class_aclmask_ext(table_oid, roleid, mode,
4060  ACLMASK_ANY, is_missing) != 0)
4061  return ACLCHECK_OK;
4062  else
4063  return ACLCHECK_NO_PRIV;
4064 }
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3329

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

3321 {
3322  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3323 }

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

4085 {
4086  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4087  ACLMASK_ANY, snapshot) != 0)
4088  return ACLCHECK_OK;
4089  else
4090  return ACLCHECK_NO_PRIV;
4091 }
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3571

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

Referenced by be_lo_put(), and inv_open().

◆ pg_parameter_aclcheck()

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

Definition at line 4071 of file aclchk.c.

4072 {
4073  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4074  return ACLCHECK_OK;
4075  else
4076  return ACLCHECK_NO_PRIV;
4077 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3448
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_option_ext(), and validate_option_array_item().

◆ recordDependencyOnNewAcl()

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

Definition at line 4328 of file aclchk.c.

4330 {
4331  int nmembers;
4332  Oid *members;
4333 
4334  /* Nothing to do if ACL is defaulted */
4335  if (acl == NULL)
4336  return;
4337 
4338  /* Extract roles mentioned in ACL */
4339  nmembers = aclmembers(acl, &members);
4340 
4341  /* Update the shared dependency ACL info */
4342  updateAclDependencies(classId, objectId, objsubId,
4343  ownerId,
4344  0, NULL,
4345  nmembers, members);
4346 }
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1508
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:482

References aclmembers(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4355 of file aclchk.c.

4356 {
4357  /*
4358  * pg_class / pg_attribute
4359  *
4360  * If this is a relation then we need to see if there are any sub-objects
4361  * (eg: columns) for it and, if so, be sure to call
4362  * recordExtensionInitPrivWorker() for each one.
4363  */
4364  if (classoid == RelationRelationId)
4365  {
4366  Form_pg_class pg_class_tuple;
4367  Datum aclDatum;
4368  bool isNull;
4369  HeapTuple tuple;
4370 
4371  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4372  if (!HeapTupleIsValid(tuple))
4373  elog(ERROR, "cache lookup failed for relation %u", objoid);
4374  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4375 
4376  /*
4377  * Indexes don't have permissions, neither do the pg_class rows for
4378  * composite types. (These cases are unreachable given the
4379  * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4380  */
4381  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4382  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4383  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4384  {
4385  ReleaseSysCache(tuple);
4386  return;
4387  }
4388 
4389  /*
4390  * If this isn't a sequence then it's possibly going to have
4391  * column-level ACLs associated with it.
4392  */
4393  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4394  {
4395  AttrNumber curr_att;
4396  AttrNumber nattrs = pg_class_tuple->relnatts;
4397 
4398  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4399  {
4400  HeapTuple attTuple;
4401  Datum attaclDatum;
4402 
4403  attTuple = SearchSysCache2(ATTNUM,
4404  ObjectIdGetDatum(objoid),
4405  Int16GetDatum(curr_att));
4406 
4407  if (!HeapTupleIsValid(attTuple))
4408  continue;
4409 
4410  /* ignore dropped columns */
4411  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4412  {
4413  ReleaseSysCache(attTuple);
4414  continue;
4415  }
4416 
4417  attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
4418  Anum_pg_attribute_attacl,
4419  &isNull);
4420 
4421  /* no need to do anything for a NULL ACL */
4422  if (isNull)
4423  {
4424  ReleaseSysCache(attTuple);
4425  continue;
4426  }
4427 
4428  recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4429  DatumGetAclP(attaclDatum));
4430 
4431  ReleaseSysCache(attTuple);
4432  }
4433  }
4434 
4435  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
4436  &isNull);
4437 
4438  /* Add the record, if any, for the top-level object */
4439  if (!isNull)
4440  recordExtensionInitPrivWorker(objoid, classoid, 0,
4441  DatumGetAclP(aclDatum));
4442 
4443  ReleaseSysCache(tuple);
4444  }
4445  /* pg_largeobject_metadata */
4446  else if (classoid == LargeObjectMetadataRelationId)
4447  {
4448  Datum aclDatum;
4449  bool isNull;
4450  HeapTuple tuple;
4451  ScanKeyData entry[1];
4452  SysScanDesc scan;
4453  Relation relation;
4454 
4455  /*
4456  * Note: this is dead code, given that we don't allow large objects to
4457  * be made extension members. But it seems worth carrying in case
4458  * some future caller of this function has need for it.
4459  */
4460  relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock);
4461 
4462  /* There's no syscache for pg_largeobject_metadata */
4463  ScanKeyInit(&entry[0],
4464  Anum_pg_largeobject_metadata_oid,
4465  BTEqualStrategyNumber, F_OIDEQ,
4466  ObjectIdGetDatum(objoid));
4467 
4468  scan = systable_beginscan(relation,
4469  LargeObjectMetadataOidIndexId, true,
4470  NULL, 1, entry);
4471 
4472  tuple = systable_getnext(scan);
4473  if (!HeapTupleIsValid(tuple))
4474  elog(ERROR, "could not find tuple for large object %u", objoid);
4475 
4476  aclDatum = heap_getattr(tuple,
4477  Anum_pg_largeobject_metadata_lomacl,
4478  RelationGetDescr(relation), &isNull);
4479 
4480  /* Add the record, if any, for the top-level object */
4481  if (!isNull)
4482  recordExtensionInitPrivWorker(objoid, classoid, 0,
4483  DatumGetAclP(aclDatum));
4484 
4485  systable_endscan(scan);
4486  }
4487  /* This will error on unsupported classoid. */
4488  else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4489  {
4490  Datum aclDatum;
4491  bool isNull;
4492  HeapTuple tuple;
4493 
4494  tuple = SearchSysCache1(get_object_catcache_oid(classoid),
4495  ObjectIdGetDatum(objoid));
4496  if (!HeapTupleIsValid(tuple))
4497  elog(ERROR, "cache lookup failed for %s %u",
4498  get_object_class_descr(classoid), objoid);
4499 
4500  aclDatum = SysCacheGetAttr(get_object_catcache_oid(classoid), tuple,
4501  get_object_attnum_acl(classoid),
4502  &isNull);
4503 
4504  /* Add the record, if any, for the top-level object */
4505  if (!isNull)
4506  recordExtensionInitPrivWorker(objoid, classoid, 0,
4507  DatumGetAclP(aclDatum));
4508 
4509  ReleaseSysCache(tuple);
4510  }
4511 }
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition: aclchk.c:4630
#define InvalidAttrNumber
Definition: attnum.h:23
#define RowExclusiveLock
Definition: lockdefs.h:38
AttrNumber get_object_attnum_acl(Oid class_id)

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

Referenced by ExecAlterExtensionContentsStmt().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4518 of file aclchk.c.

4519 {
4520  /*
4521  * If this is a relation then we need to see if there are any sub-objects
4522  * (eg: columns) for it and, if so, be sure to call
4523  * recordExtensionInitPrivWorker() for each one.
4524  */
4525  if (classoid == RelationRelationId)
4526  {
4527  Form_pg_class pg_class_tuple;
4528  HeapTuple tuple;
4529 
4530  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4531  if (!HeapTupleIsValid(tuple))
4532  elog(ERROR, "cache lookup failed for relation %u", objoid);
4533  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4534 
4535  /*
4536  * Indexes don't have permissions, neither do the pg_class rows for
4537  * composite types. (These cases are unreachable given the
4538  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4539  */
4540  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4541  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4542  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4543  {
4544  ReleaseSysCache(tuple);
4545  return;
4546  }
4547 
4548  /*
4549  * If this isn't a sequence then it's possibly going to have
4550  * column-level ACLs associated with it.
4551  */
4552  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4553  {
4554  AttrNumber curr_att;
4555  AttrNumber nattrs = pg_class_tuple->relnatts;
4556 
4557  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4558  {
4559  HeapTuple attTuple;
4560 
4561  attTuple = SearchSysCache2(ATTNUM,
4562  ObjectIdGetDatum(objoid),
4563  Int16GetDatum(curr_att));
4564 
4565  if (!HeapTupleIsValid(attTuple))
4566  continue;
4567 
4568  /* when removing, remove all entries, even dropped columns */
4569 
4570  recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4571 
4572  ReleaseSysCache(attTuple);
4573  }
4574  }
4575 
4576  ReleaseSysCache(tuple);
4577  }
4578 
4579  /* Remove the record, if any, for the top-level object */
4580  recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4581 }

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

Referenced by ExecAlterExtensionContentsStmt().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1470 of file aclchk.c.

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

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

Referenced by shdepDropOwned().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5215 of file acl.c.

5216 {
5217  Oid admin_role;
5218 
5219  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5220  if (member == role)
5221  return InvalidOid;
5222 
5223  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5224  return admin_role;
5225 }

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

5273 {
5274  AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5275  List *roles_list;
5276  int nrights;
5277  ListCell *l;
5278 
5279  /*
5280  * The object owner is always treated as having all grant options, so if
5281  * roleId is the owner it's easy. Also, if roleId is a superuser it's
5282  * easy: superusers are implicitly members of every role, so they act as
5283  * the object owner.
5284  */
5285  if (roleId == ownerId || superuser_arg(roleId))
5286  {
5287  *grantorId = ownerId;
5288  *grantOptions = needed_goptions;
5289  return;
5290  }
5291 
5292  /*
5293  * Otherwise we have to do a careful search to see if roleId has the
5294  * privileges of any suitable role. Note: we can hang onto the result of
5295  * roles_is_member_of() throughout this loop, because aclmask_direct()
5296  * doesn't query any role memberships.
5297  */
5298  roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5299  InvalidOid, NULL);
5300 
5301  /* initialize candidate result as default */
5302  *grantorId = roleId;
5303  *grantOptions = ACL_NO_RIGHTS;
5304  nrights = 0;
5305 
5306  foreach(l, roles_list)
5307  {
5308  Oid otherrole = lfirst_oid(l);
5309  AclMode otherprivs;
5310 
5311  otherprivs = aclmask_direct(acl, otherrole, ownerId,
5312  needed_goptions, ACLMASK_ALL);
5313  if (otherprivs == needed_goptions)
5314  {
5315  /* Found a suitable grantor */
5316  *grantorId = otherrole;
5317  *grantOptions = otherprivs;
5318  return;
5319  }
5320 
5321  /*
5322  * If it has just some of the needed privileges, remember best
5323  * candidate.
5324  */
5325  if (otherprivs != ACL_NO_RIGHTS)
5326  {
5327  int nnewrights = count_one_bits(otherprivs);
5328 
5329  if (nnewrights > nrights)
5330  {
5331  *grantorId = otherrole;
5332  *grantOptions = otherprivs;
5333  nrights = nnewrights;
5334  }
5335  }
5336  }
5337 }
static int count_one_bits(AclMode mask)
Definition: acl.c:5230
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1445
#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().