PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
acl.h File Reference
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/snapshot.h"
Include dependency graph for acl.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

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

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

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

Functions

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

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 171 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

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

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

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

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

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

Definition at line 76 of file acl.h.

◆ ACLITEM_SET_PRIVS

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

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

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

Definition at line 82 of file acl.h.

◆ ACLITEM_SET_RIGHTS

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

Definition at line 79 of file acl.h.

◆ DatumGetAclItemP

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

Definition at line 116 of file acl.h.

◆ DatumGetAclP

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

Definition at line 120 of file acl.h.

◆ DatumGetAclPCopy

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

Definition at line 121 of file acl.h.

◆ PG_GETARG_ACL_P

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

Definition at line 122 of file acl.h.

◆ PG_GETARG_ACL_P_COPY

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

Definition at line 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 117 of file acl.h.

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 124 of file acl.h.

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 118 of file acl.h.

Typedef Documentation

◆ Acl

typedef struct ArrayType Acl

Definition at line 1 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 174 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 181 of file acl.h.

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

Function Documentation

◆ aclcheck_error()

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

Definition at line 2622 of file aclchk.c.

2624 {
2625  switch (aclerr)
2626  {
2627  case ACLCHECK_OK:
2628  /* no error, so return to caller */
2629  break;
2630  case ACLCHECK_NO_PRIV:
2631  {
2632  const char *msg = "???";
2633 
2634  switch (objtype)
2635  {
2636  case OBJECT_AGGREGATE:
2637  msg = gettext_noop("permission denied for aggregate %s");
2638  break;
2639  case OBJECT_COLLATION:
2640  msg = gettext_noop("permission denied for collation %s");
2641  break;
2642  case OBJECT_COLUMN:
2643  msg = gettext_noop("permission denied for column %s");
2644  break;
2645  case OBJECT_CONVERSION:
2646  msg = gettext_noop("permission denied for conversion %s");
2647  break;
2648  case OBJECT_DATABASE:
2649  msg = gettext_noop("permission denied for database %s");
2650  break;
2651  case OBJECT_DOMAIN:
2652  msg = gettext_noop("permission denied for domain %s");
2653  break;
2654  case OBJECT_EVENT_TRIGGER:
2655  msg = gettext_noop("permission denied for event trigger %s");
2656  break;
2657  case OBJECT_EXTENSION:
2658  msg = gettext_noop("permission denied for extension %s");
2659  break;
2660  case OBJECT_FDW:
2661  msg = gettext_noop("permission denied for foreign-data wrapper %s");
2662  break;
2663  case OBJECT_FOREIGN_SERVER:
2664  msg = gettext_noop("permission denied for foreign server %s");
2665  break;
2666  case OBJECT_FOREIGN_TABLE:
2667  msg = gettext_noop("permission denied for foreign table %s");
2668  break;
2669  case OBJECT_FUNCTION:
2670  msg = gettext_noop("permission denied for function %s");
2671  break;
2672  case OBJECT_INDEX:
2673  msg = gettext_noop("permission denied for index %s");
2674  break;
2675  case OBJECT_LANGUAGE:
2676  msg = gettext_noop("permission denied for language %s");
2677  break;
2678  case OBJECT_LARGEOBJECT:
2679  msg = gettext_noop("permission denied for large object %s");
2680  break;
2681  case OBJECT_MATVIEW:
2682  msg = gettext_noop("permission denied for materialized view %s");
2683  break;
2684  case OBJECT_OPCLASS:
2685  msg = gettext_noop("permission denied for operator class %s");
2686  break;
2687  case OBJECT_OPERATOR:
2688  msg = gettext_noop("permission denied for operator %s");
2689  break;
2690  case OBJECT_OPFAMILY:
2691  msg = gettext_noop("permission denied for operator family %s");
2692  break;
2693  case OBJECT_PARAMETER_ACL:
2694  msg = gettext_noop("permission denied for parameter %s");
2695  break;
2696  case OBJECT_POLICY:
2697  msg = gettext_noop("permission denied for policy %s");
2698  break;
2699  case OBJECT_PROCEDURE:
2700  msg = gettext_noop("permission denied for procedure %s");
2701  break;
2702  case OBJECT_PUBLICATION:
2703  msg = gettext_noop("permission denied for publication %s");
2704  break;
2705  case OBJECT_ROUTINE:
2706  msg = gettext_noop("permission denied for routine %s");
2707  break;
2708  case OBJECT_SCHEMA:
2709  msg = gettext_noop("permission denied for schema %s");
2710  break;
2711  case OBJECT_SEQUENCE:
2712  msg = gettext_noop("permission denied for sequence %s");
2713  break;
2714  case OBJECT_STATISTIC_EXT:
2715  msg = gettext_noop("permission denied for statistics object %s");
2716  break;
2717  case OBJECT_SUBSCRIPTION:
2718  msg = gettext_noop("permission denied for subscription %s");
2719  break;
2720  case OBJECT_TABLE:
2721  msg = gettext_noop("permission denied for table %s");
2722  break;
2723  case OBJECT_TABLESPACE:
2724  msg = gettext_noop("permission denied for tablespace %s");
2725  break;
2727  msg = gettext_noop("permission denied for text search configuration %s");
2728  break;
2729  case OBJECT_TSDICTIONARY:
2730  msg = gettext_noop("permission denied for text search dictionary %s");
2731  break;
2732  case OBJECT_TYPE:
2733  msg = gettext_noop("permission denied for type %s");
2734  break;
2735  case OBJECT_VIEW:
2736  msg = gettext_noop("permission denied for view %s");
2737  break;
2738  /* these currently aren't used */
2739  case OBJECT_ACCESS_METHOD:
2740  case OBJECT_AMOP:
2741  case OBJECT_AMPROC:
2742  case OBJECT_ATTRIBUTE:
2743  case OBJECT_CAST:
2744  case OBJECT_DEFAULT:
2745  case OBJECT_DEFACL:
2746  case OBJECT_DOMCONSTRAINT:
2749  case OBJECT_ROLE:
2750  case OBJECT_RULE:
2751  case OBJECT_TABCONSTRAINT:
2752  case OBJECT_TRANSFORM:
2753  case OBJECT_TRIGGER:
2754  case OBJECT_TSPARSER:
2755  case OBJECT_TSTEMPLATE:
2756  case OBJECT_USER_MAPPING:
2757  elog(ERROR, "unsupported object type: %d", objtype);
2758  }
2759 
2760  ereport(ERROR,
2761  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2762  errmsg(msg, objectname)));
2763  break;
2764  }
2765  case ACLCHECK_NOT_OWNER:
2766  {
2767  const char *msg = "???";
2768 
2769  switch (objtype)
2770  {
2771  case OBJECT_AGGREGATE:
2772  msg = gettext_noop("must be owner of aggregate %s");
2773  break;
2774  case OBJECT_COLLATION:
2775  msg = gettext_noop("must be owner of collation %s");
2776  break;
2777  case OBJECT_CONVERSION:
2778  msg = gettext_noop("must be owner of conversion %s");
2779  break;
2780  case OBJECT_DATABASE:
2781  msg = gettext_noop("must be owner of database %s");
2782  break;
2783  case OBJECT_DOMAIN:
2784  msg = gettext_noop("must be owner of domain %s");
2785  break;
2786  case OBJECT_EVENT_TRIGGER:
2787  msg = gettext_noop("must be owner of event trigger %s");
2788  break;
2789  case OBJECT_EXTENSION:
2790  msg = gettext_noop("must be owner of extension %s");
2791  break;
2792  case OBJECT_FDW:
2793  msg = gettext_noop("must be owner of foreign-data wrapper %s");
2794  break;
2795  case OBJECT_FOREIGN_SERVER:
2796  msg = gettext_noop("must be owner of foreign server %s");
2797  break;
2798  case OBJECT_FOREIGN_TABLE:
2799  msg = gettext_noop("must be owner of foreign table %s");
2800  break;
2801  case OBJECT_FUNCTION:
2802  msg = gettext_noop("must be owner of function %s");
2803  break;
2804  case OBJECT_INDEX:
2805  msg = gettext_noop("must be owner of index %s");
2806  break;
2807  case OBJECT_LANGUAGE:
2808  msg = gettext_noop("must be owner of language %s");
2809  break;
2810  case OBJECT_LARGEOBJECT:
2811  msg = gettext_noop("must be owner of large object %s");
2812  break;
2813  case OBJECT_MATVIEW:
2814  msg = gettext_noop("must be owner of materialized view %s");
2815  break;
2816  case OBJECT_OPCLASS:
2817  msg = gettext_noop("must be owner of operator class %s");
2818  break;
2819  case OBJECT_OPERATOR:
2820  msg = gettext_noop("must be owner of operator %s");
2821  break;
2822  case OBJECT_OPFAMILY:
2823  msg = gettext_noop("must be owner of operator family %s");
2824  break;
2825  case OBJECT_PROCEDURE:
2826  msg = gettext_noop("must be owner of procedure %s");
2827  break;
2828  case OBJECT_PUBLICATION:
2829  msg = gettext_noop("must be owner of publication %s");
2830  break;
2831  case OBJECT_ROUTINE:
2832  msg = gettext_noop("must be owner of routine %s");
2833  break;
2834  case OBJECT_SEQUENCE:
2835  msg = gettext_noop("must be owner of sequence %s");
2836  break;
2837  case OBJECT_SUBSCRIPTION:
2838  msg = gettext_noop("must be owner of subscription %s");
2839  break;
2840  case OBJECT_TABLE:
2841  msg = gettext_noop("must be owner of table %s");
2842  break;
2843  case OBJECT_TYPE:
2844  msg = gettext_noop("must be owner of type %s");
2845  break;
2846  case OBJECT_VIEW:
2847  msg = gettext_noop("must be owner of view %s");
2848  break;
2849  case OBJECT_SCHEMA:
2850  msg = gettext_noop("must be owner of schema %s");
2851  break;
2852  case OBJECT_STATISTIC_EXT:
2853  msg = gettext_noop("must be owner of statistics object %s");
2854  break;
2855  case OBJECT_TABLESPACE:
2856  msg = gettext_noop("must be owner of tablespace %s");
2857  break;
2859  msg = gettext_noop("must be owner of text search configuration %s");
2860  break;
2861  case OBJECT_TSDICTIONARY:
2862  msg = gettext_noop("must be owner of text search dictionary %s");
2863  break;
2864 
2865  /*
2866  * Special cases: For these, the error message talks
2867  * about "relation", because that's where the
2868  * ownership is attached. See also
2869  * check_object_ownership().
2870  */
2871  case OBJECT_COLUMN:
2872  case OBJECT_POLICY:
2873  case OBJECT_RULE:
2874  case OBJECT_TABCONSTRAINT:
2875  case OBJECT_TRIGGER:
2876  msg = gettext_noop("must be owner of relation %s");
2877  break;
2878  /* these currently aren't used */
2879  case OBJECT_ACCESS_METHOD:
2880  case OBJECT_AMOP:
2881  case OBJECT_AMPROC:
2882  case OBJECT_ATTRIBUTE:
2883  case OBJECT_CAST:
2884  case OBJECT_DEFAULT:
2885  case OBJECT_DEFACL:
2886  case OBJECT_DOMCONSTRAINT:
2887  case OBJECT_PARAMETER_ACL:
2890  case OBJECT_ROLE:
2891  case OBJECT_TRANSFORM:
2892  case OBJECT_TSPARSER:
2893  case OBJECT_TSTEMPLATE:
2894  case OBJECT_USER_MAPPING:
2895  elog(ERROR, "unsupported object type: %d", objtype);
2896  }
2897 
2898  ereport(ERROR,
2899  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2900  errmsg(msg, objectname)));
2901  break;
2902  }
2903  default:
2904  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2905  break;
2906  }
2907 }
#define gettext_noop(x)
Definition: c.h:1199
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2282
@ OBJECT_FDW
Definition: parsenodes.h:2284
@ OBJECT_TSPARSER
Definition: parsenodes.h:2315
@ OBJECT_COLLATION
Definition: parsenodes.h:2275
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2318
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2268
@ OBJECT_OPCLASS
Definition: parsenodes.h:2292
@ OBJECT_DEFACL
Definition: parsenodes.h:2279
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2269
@ OBJECT_MATVIEW
Definition: parsenodes.h:2291
@ OBJECT_SCHEMA
Definition: parsenodes.h:2304
@ OBJECT_POLICY
Definition: parsenodes.h:2296
@ OBJECT_OPERATOR
Definition: parsenodes.h:2293
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2286
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2313
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2294
@ OBJECT_DOMAIN
Definition: parsenodes.h:2280
@ OBJECT_COLUMN
Definition: parsenodes.h:2274
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2310
@ OBJECT_ROLE
Definition: parsenodes.h:2301
@ OBJECT_ROUTINE
Definition: parsenodes.h:2302
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2290
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2299
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2297
@ OBJECT_EXTENSION
Definition: parsenodes.h:2283
@ OBJECT_INDEX
Definition: parsenodes.h:2288
@ OBJECT_DEFAULT
Definition: parsenodes.h:2278
@ OBJECT_DATABASE
Definition: parsenodes.h:2277
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2305
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2316
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2289
@ OBJECT_AMOP
Definition: parsenodes.h:2270
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2300
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2285
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2314
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2272
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2298
@ OBJECT_RULE
Definition: parsenodes.h:2303
@ OBJECT_CONVERSION
Definition: parsenodes.h:2276
@ OBJECT_AMPROC
Definition: parsenodes.h:2271
@ OBJECT_TABLE
Definition: parsenodes.h:2309
@ OBJECT_VIEW
Definition: parsenodes.h:2319
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2295
@ OBJECT_TYPE
Definition: parsenodes.h:2317
@ OBJECT_FUNCTION
Definition: parsenodes.h:2287
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2308
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2281
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2306
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2307
@ OBJECT_CAST
Definition: parsenodes.h:2273
@ OBJECT_TRIGGER
Definition: parsenodes.h:2312
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2311

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

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

2913 {
2914  switch (aclerr)
2915  {
2916  case ACLCHECK_OK:
2917  /* no error, so return to caller */
2918  break;
2919  case ACLCHECK_NO_PRIV:
2920  ereport(ERROR,
2921  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2922  errmsg("permission denied for column \"%s\" of relation \"%s\"",
2923  colname, objectname)));
2924  break;
2925  case ACLCHECK_NOT_OWNER:
2926  /* relation msg is OK since columns don't have separate owners */
2927  aclcheck_error(aclerr, objtype, objectname);
2928  break;
2929  default:
2930  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2931  break;
2932  }
2933 }
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2622

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

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

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

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 787 of file acl.c.

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

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

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

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 543 of file acl.c.

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

References ACL_DAT, and ACL_NUM.

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

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 529 of file acl.c.

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

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

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

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

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

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

◆ aclmerge()

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

Definition at line 485 of file acl.c.

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

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

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

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

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

◆ aclupdate()

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

Definition at line 976 of file acl.c.

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

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

5326 {
5327  if (!member_can_set_role(member, role))
5328  ereport(ERROR,
5329  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5330  errmsg("must be able to SET ROLE \"%s\"",
5331  GetUserNameFromId(role, false))));
5332 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5302
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:1041

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

5696 {
5697  if (!role)
5698  return;
5699 
5700  if (role->roletype != ROLESPEC_CSTRING)
5701  return;
5702 
5703  if (IsReservedName(role->rolename))
5704  {
5705  if (detail_msg)
5706  ereport(ERROR,
5707  (errcode(ERRCODE_RESERVED_NAME),
5708  errmsg("role name \"%s\" is reserved",
5709  role->rolename),
5710  errdetail_internal("%s", detail_msg)));
5711  else
5712  ereport(ERROR,
5713  (errcode(ERRCODE_RESERVED_NAME),
5714  errmsg("role name \"%s\" is reserved",
5715  role->rolename)));
5716  }
5717 }
bool IsReservedName(const char *name)
Definition: catalog.c:247
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
@ ROLESPEC_CSTRING
Definition: parsenodes.h:396
RoleSpecType roletype
Definition: parsenodes.h:406
char * rolename
Definition: parsenodes.h:407

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

904 {
905  GrantStmt *action = stmt->action;
906  InternalDefaultACL iacls;
907  ListCell *cell;
908  List *rolespecs = NIL;
909  List *nspnames = NIL;
910  DefElem *drolespecs = NULL;
911  DefElem *dnspnames = NULL;
912  AclMode all_privileges;
913  const char *errormsg;
914 
915  /* Deconstruct the "options" part of the statement */
916  foreach(cell, stmt->options)
917  {
918  DefElem *defel = (DefElem *) lfirst(cell);
919 
920  if (strcmp(defel->defname, "schemas") == 0)
921  {
922  if (dnspnames)
923  errorConflictingDefElem(defel, pstate);
924  dnspnames = defel;
925  }
926  else if (strcmp(defel->defname, "roles") == 0)
927  {
928  if (drolespecs)
929  errorConflictingDefElem(defel, pstate);
930  drolespecs = defel;
931  }
932  else
933  elog(ERROR, "option \"%s\" not recognized", defel->defname);
934  }
935 
936  if (dnspnames)
937  nspnames = (List *) dnspnames->arg;
938  if (drolespecs)
939  rolespecs = (List *) drolespecs->arg;
940 
941  /* Prepare the InternalDefaultACL representation of the statement */
942  /* roleid to be filled below */
943  /* nspid to be filled in SetDefaultACLsInSchemas */
944  iacls.is_grant = action->is_grant;
945  iacls.objtype = action->objtype;
946  /* all_privs to be filled below */
947  /* privileges to be filled below */
948  iacls.grantees = NIL; /* filled below */
949  iacls.grant_option = action->grant_option;
950  iacls.behavior = action->behavior;
951 
952  /*
953  * Convert the RoleSpec list into an Oid list. Note that at this point we
954  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
955  * there shouldn't be any additional work needed to support this case.
956  */
957  foreach(cell, action->grantees)
958  {
959  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
960  Oid grantee_uid;
961 
962  switch (grantee->roletype)
963  {
964  case ROLESPEC_PUBLIC:
965  grantee_uid = ACL_ID_PUBLIC;
966  break;
967  default:
968  grantee_uid = get_rolespec_oid(grantee, false);
969  break;
970  }
971  iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
972  }
973 
974  /*
975  * Convert action->privileges, a list of privilege strings, into an
976  * AclMode bitmask.
977  */
978  switch (action->objtype)
979  {
980  case OBJECT_TABLE:
981  all_privileges = ACL_ALL_RIGHTS_RELATION;
982  errormsg = gettext_noop("invalid privilege type %s for relation");
983  break;
984  case OBJECT_SEQUENCE:
985  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
986  errormsg = gettext_noop("invalid privilege type %s for sequence");
987  break;
988  case OBJECT_FUNCTION:
989  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
990  errormsg = gettext_noop("invalid privilege type %s for function");
991  break;
992  case OBJECT_PROCEDURE:
993  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
994  errormsg = gettext_noop("invalid privilege type %s for procedure");
995  break;
996  case OBJECT_ROUTINE:
997  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
998  errormsg = gettext_noop("invalid privilege type %s for routine");
999  break;
1000  case OBJECT_TYPE:
1001  all_privileges = ACL_ALL_RIGHTS_TYPE;
1002  errormsg = gettext_noop("invalid privilege type %s for type");
1003  break;
1004  case OBJECT_SCHEMA:
1005  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
1006  errormsg = gettext_noop("invalid privilege type %s for schema");
1007  break;
1008  default:
1009  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1010  (int) action->objtype);
1011  /* keep compiler quiet */
1012  all_privileges = ACL_NO_RIGHTS;
1013  errormsg = NULL;
1014  }
1015 
1016  if (action->privileges == NIL)
1017  {
1018  iacls.all_privs = true;
1019 
1020  /*
1021  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1022  * depending on the object type
1023  */
1024  iacls.privileges = ACL_NO_RIGHTS;
1025  }
1026  else
1027  {
1028  iacls.all_privs = false;
1029  iacls.privileges = ACL_NO_RIGHTS;
1030 
1031  foreach(cell, action->privileges)
1032  {
1033  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1034  AclMode priv;
1035 
1036  if (privnode->cols)
1037  ereport(ERROR,
1038  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1039  errmsg("default privileges cannot be set for columns")));
1040 
1041  if (privnode->priv_name == NULL) /* parser mistake? */
1042  elog(ERROR, "AccessPriv node must specify privilege");
1043  priv = string_to_privilege(privnode->priv_name);
1044 
1045  if (priv & ~((AclMode) all_privileges))
1046  ereport(ERROR,
1047  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1048  errmsg(errormsg, privilege_to_string(priv))));
1049 
1050  iacls.privileges |= priv;
1051  }
1052  }
1053 
1054  if (rolespecs == NIL)
1055  {
1056  /* Set permissions for myself */
1057  iacls.roleid = GetUserId();
1058 
1059  SetDefaultACLsInSchemas(&iacls, nspnames);
1060  }
1061  else
1062  {
1063  /* Look up the role OIDs and do permissions checks */
1064  ListCell *rolecell;
1065 
1066  foreach(rolecell, rolespecs)
1067  {
1068  RoleSpec *rolespec = lfirst(rolecell);
1069 
1070  iacls.roleid = get_rolespec_oid(rolespec, false);
1071 
1072  if (!has_privs_of_role(GetUserId(), iacls.roleid))
1073  ereport(ERROR,
1074  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1075  errmsg("permission denied to change default privileges")));
1076 
1077  SetDefaultACLsInSchemas(&iacls, nspnames);
1078  }
1079  }
1080 }
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5588
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:2534
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1088
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2575
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:384
#define stmt
Definition: indent_codes.h:59
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
Oid GetUserId(void)
Definition: miscinit.c:524
@ ROLESPEC_PUBLIC
Definition: parsenodes.h:400
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
char * priv_name
Definition: parsenodes.h:2552
List * cols
Definition: parsenodes.h:2553
char * defname
Definition: parsenodes.h:817
Node * arg
Definition: parsenodes.h:818
AclMode privileges
Definition: aclchk.c:99
List * grantees
Definition: aclchk.c:100
DropBehavior behavior
Definition: aclchk.c:102
ObjectType objtype
Definition: aclchk.c:97
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 392 of file aclchk.c.

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

5555 {
5556  Oid oid;
5557 
5558  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5560  if (!OidIsValid(oid) && !missing_ok)
5561  ereport(ERROR,
5562  (errcode(ERRCODE_UNDEFINED_OBJECT),
5563  errmsg("role \"%s\" does not exist", rolname)));
5564  return oid;
5565 }
#define OidIsValid(objectId)
Definition: c.h:778
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:109

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

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

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5673 of file acl.c.

5674 {
5675  HeapTuple tp;
5676  Form_pg_authid authForm;
5677  char *rolename;
5678 
5679  tp = get_rolespec_tuple(role);
5680  authForm = (Form_pg_authid) GETSTRUCT(tp);
5681  rolename = pstrdup(NameStr(authForm->rolname));
5682  ReleaseSysCache(tp);
5683 
5684  return rolename;
5685 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5627
#define NameStr(name)
Definition: c.h:749
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1696
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269

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

5589 {
5590  Oid oid;
5591 
5592  switch (role->roletype)
5593  {
5594  case ROLESPEC_CSTRING:
5595  Assert(role->rolename);
5596  oid = get_role_oid(role->rolename, missing_ok);
5597  break;
5598 
5599  case ROLESPEC_CURRENT_ROLE:
5600  case ROLESPEC_CURRENT_USER:
5601  oid = GetUserId();
5602  break;
5603 
5604  case ROLESPEC_SESSION_USER:
5605  oid = GetSessionUserId();
5606  break;
5607 
5608  case ROLESPEC_PUBLIC:
5609  ereport(ERROR,
5610  (errcode(ERRCODE_UNDEFINED_OBJECT),
5611  errmsg("role \"%s\" does not exist", "public")));
5612  oid = InvalidOid; /* make compiler happy */
5613  break;
5614 
5615  default:
5616  elog(ERROR, "unexpected role type %d", role->roletype);
5617  }
5618 
5619  return oid;
5620 }
Oid GetSessionUserId(void)
Definition: miscinit.c:563
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:398
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:399
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:397
#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 5627 of file acl.c.

5628 {
5629  HeapTuple tuple;
5630 
5631  switch (role->roletype)
5632  {
5633  case ROLESPEC_CSTRING:
5634  Assert(role->rolename);
5635  tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5636  if (!HeapTupleIsValid(tuple))
5637  ereport(ERROR,
5638  (errcode(ERRCODE_UNDEFINED_OBJECT),
5639  errmsg("role \"%s\" does not exist", role->rolename)));
5640  break;
5641 
5642  case ROLESPEC_CURRENT_ROLE:
5643  case ROLESPEC_CURRENT_USER:
5644  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5645  if (!HeapTupleIsValid(tuple))
5646  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5647  break;
5648 
5649  case ROLESPEC_SESSION_USER:
5650  tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetSessionUserId()));
5651  if (!HeapTupleIsValid(tuple))
5652  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5653  break;
5654 
5655  case ROLESPEC_PUBLIC:
5656  ereport(ERROR,
5657  (errcode(ERRCODE_UNDEFINED_OBJECT),
5658  errmsg("role \"%s\" does not exist", "public")));
5659  tuple = NULL; /* make compiler happy */
5660  break;
5661 
5662  default:
5663  elog(ERROR, "unexpected role type %d", role->roletype);
5664  }
5665 
5666  return tuple;
5667 }
#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:221

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

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

◆ get_user_default_acl()

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

Definition at line 4223 of file aclchk.c.

4224 {
4225  Acl *result;
4226  Acl *glob_acl;
4227  Acl *schema_acl;
4228  Acl *def_acl;
4229  char defaclobjtype;
4230 
4231  /*
4232  * Use NULL during bootstrap, since pg_default_acl probably isn't there
4233  * yet.
4234  */
4236  return NULL;
4237 
4238  /* Check if object type is supported in pg_default_acl */
4239  switch (objtype)
4240  {
4241  case OBJECT_TABLE:
4242  defaclobjtype = DEFACLOBJ_RELATION;
4243  break;
4244 
4245  case OBJECT_SEQUENCE:
4246  defaclobjtype = DEFACLOBJ_SEQUENCE;
4247  break;
4248 
4249  case OBJECT_FUNCTION:
4250  defaclobjtype = DEFACLOBJ_FUNCTION;
4251  break;
4252 
4253  case OBJECT_TYPE:
4254  defaclobjtype = DEFACLOBJ_TYPE;
4255  break;
4256 
4257  case OBJECT_SCHEMA:
4258  defaclobjtype = DEFACLOBJ_NAMESPACE;
4259  break;
4260 
4261  default:
4262  return NULL;
4263  }
4264 
4265  /* Look up the relevant pg_default_acl entries */
4266  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4267  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4268 
4269  /* Quick out if neither entry exists */
4270  if (glob_acl == NULL && schema_acl == NULL)
4271  return NULL;
4272 
4273  /* We need to know the hard-wired default value, too */
4274  def_acl = acldefault(objtype, ownerId);
4275 
4276  /* If there's no global entry, substitute the hard-wired default */
4277  if (glob_acl == NULL)
4278  glob_acl = def_acl;
4279 
4280  /* Merge in any per-schema privileges */
4281  result = aclmerge(glob_acl, schema_acl, ownerId);
4282 
4283  /*
4284  * For efficiency, we want to return NULL if the result equals default.
4285  * This requires sorting both arrays to get an accurate comparison.
4286  */
4287  aclitemsort(result);
4288  aclitemsort(def_acl);
4289  if (aclequal(result, def_acl))
4290  result = NULL;
4291 
4292  return result;
4293 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:543
void aclitemsort(Acl *acl)
Definition: acl.c:529
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:787
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:485
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4188
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:454

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 4164 of file aclchk.c.

4165 {
4166  bool result = false;
4167  HeapTuple utup;
4168 
4169  /* Superusers bypass all permission checking. */
4170  if (superuser_arg(roleid))
4171  return true;
4172 
4173  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4174  if (HeapTupleIsValid(utup))
4175  {
4176  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4177  ReleaseSysCache(utup);
4178  }
4179  return result;
4180 }
bool rolbypassrls
Definition: pg_authid.h:41
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

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

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

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4145 of file aclchk.c.

4146 {
4147  bool result = false;
4148  HeapTuple utup;
4149 
4150  /* Superusers bypass all permission checking. */
4151  if (superuser_arg(roleid))
4152  return true;
4153 
4154  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4155  if (HeapTupleIsValid(utup))
4156  {
4157  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4158  ReleaseSysCache(utup);
4159  }
4160  return result;
4161 }
bool rolcreaterole
Definition: pg_authid.h:37

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 5268 of file acl.c.

5269 {
5270  /* Fast path for simple case */
5271  if (member == role)
5272  return true;
5273 
5274  /* Superusers have every privilege, so are part of every role */
5275  if (superuser_arg(member))
5276  return true;
5277 
5278  /*
5279  * Find all the roles that member has the privileges of, including
5280  * multi-level recursion, then see if target role is any one of them.
5281  */
5283  InvalidOid, NULL),
5284  role);
5285 }
@ ROLERECURSE_PRIVS
Definition: acl.c:78
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:5136
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722

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

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

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 5024 of file acl.c.

5025 {
5027  {
5028  cached_db_hash =
5029  GetSysCacheHashValue1(DATABASEOID,
5031 
5032  /*
5033  * In normal mode, set a callback on any syscache invalidation of rows
5034  * of pg_auth_members (for roles_is_member_of()) pg_database (for
5035  * roles_is_member_of())
5036  */
5037  CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
5039  (Datum) 0);
5042  (Datum) 0);
5043  CacheRegisterSyscacheCallback(DATABASEOID,
5045  (Datum) 0);
5046  }
5047 }
static uint32 cached_db_hash
Definition: acl.c:83
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:5054
Oid MyDatabaseId
Definition: globals.c:93
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1704
uintptr_t Datum
Definition: postgres.h:64
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:118

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 5398 of file acl.c.

5399 {
5400  Oid admin_role;
5401 
5402  if (superuser_arg(member))
5403  return true;
5404 
5405  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5406  if (member == role)
5407  return false;
5408 
5409  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5410  return OidIsValid(admin_role);
5411 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:77

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

5349 {
5350  /* Fast path for simple case */
5351  if (member == role)
5352  return true;
5353 
5354  /* Superusers have every privilege, so are part of every role */
5355  if (superuser_arg(member))
5356  return true;
5357 
5358  /*
5359  * Find all the roles that member is a member of, including multi-level
5360  * recursion, then see if target role is any one of them.
5361  */
5363  InvalidOid, NULL),
5364  role);
5365 }

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

5377 {
5378  /* Fast path for simple case */
5379  if (member == role)
5380  return true;
5381 
5382  /*
5383  * Find all the roles that member is a member of, including multi-level
5384  * recursion, then see if target role is any one of them.
5385  */
5387  InvalidOid, NULL),
5388  role);
5389 }

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

433 {
434  return allocacl(0);
435 }

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5302 of file acl.c.

5303 {
5304  /* Fast path for simple case */
5305  if (member == role)
5306  return true;
5307 
5308  /* Superusers have every privilege, so can always SET ROLE */
5309  if (superuser_arg(member))
5310  return true;
5311 
5312  /*
5313  * Find all the roles that member can access via SET ROLE, including
5314  * multi-level recursion, then see if target role is any one of them.
5315  */
5317  InvalidOid, NULL),
5318  role);
5319 }
@ ROLERECURSE_SETROLE
Definition: acl.c:79

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

3811 {
3812  return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3813 }
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3820
static PgChecksumMode mode
Definition: pg_checksums.c:55

References mode, and object_aclcheck_ext().

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

◆ object_aclcheck_ext()

◆ object_ownercheck()

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

Definition at line 4064 of file aclchk.c.

4065 {
4066  int cacheid;
4067  Oid ownerId;
4068 
4069  /* Superusers bypass all permission checking. */
4070  if (superuser_arg(roleid))
4071  return true;
4072 
4073  /* For large objects, the catalog to consult is pg_largeobject_metadata */
4074  if (classid == LargeObjectRelationId)
4075  classid = LargeObjectMetadataRelationId;
4076 
4077  cacheid = get_object_catcache_oid(classid);
4078  if (cacheid != -1)
4079  {
4080  /* we can get the object's tuple from the syscache */
4081  HeapTuple tuple;
4082 
4083  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4084  if (!HeapTupleIsValid(tuple))
4085  ereport(ERROR,
4086  (errcode(ERRCODE_UNDEFINED_OBJECT),
4087  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4088 
4089  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4090  tuple,
4091  get_object_attnum_owner(classid)));
4092  ReleaseSysCache(tuple);
4093  }
4094  else
4095  {
4096  /* for catalogs without an appropriate syscache */
4097  Relation rel;
4098  ScanKeyData entry[1];
4099  SysScanDesc scan;
4100  HeapTuple tuple;
4101  bool isnull;
4102 
4103  rel = table_open(classid, AccessShareLock);
4104 
4105  ScanKeyInit(&entry[0],
4106  get_object_attnum_oid(classid),
4107  BTEqualStrategyNumber, F_OIDEQ,
4108  ObjectIdGetDatum(objectid));
4109 
4110  scan = systable_beginscan(rel,
4111  get_object_oid_index(classid), true,
4112  NULL, 1, entry);
4113 
4114  tuple = systable_getnext(scan);
4115  if (!HeapTupleIsValid(tuple))
4116  ereport(ERROR,
4117  (errcode(ERRCODE_UNDEFINED_OBJECT),
4118  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4119 
4120  ownerId = DatumGetObjectId(heap_getattr(tuple,
4121  get_object_attnum_owner(classid),
4122  RelationGetDescr(rel),
4123  &isnull));
4124  Assert(!isnull);
4125 
4126  systable_endscan(scan);
4128  }
4129 
4130  return has_privs_of_role(roleid, ownerId);
4131 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:511
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:531
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:626
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

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

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

◆ pg_attribute_aclcheck()

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

Definition at line 3842 of file aclchk.c.

3844 {
3845  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3846 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3854
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 3884 of file aclchk.c.

3886 {
3887  return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3888 }
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3895

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

3898 {
3899  AclResult result;
3900  HeapTuple classTuple;
3901  Form_pg_class classForm;
3902  Oid ownerId;
3903  AttrNumber nattrs;
3904  AttrNumber curr_att;
3905 
3906  /*
3907  * Must fetch pg_class row to get owner ID and number of attributes.
3908  */
3909  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3910  if (!HeapTupleIsValid(classTuple))
3911  {
3912  if (is_missing != NULL)
3913  {
3914  /* return "no privileges" instead of throwing an error */
3915  *is_missing = true;
3916  return ACLCHECK_NO_PRIV;
3917  }
3918  else
3919  ereport(ERROR,
3921  errmsg("relation with OID %u does not exist",
3922  table_oid)));
3923  }
3924  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3925 
3926  ownerId = classForm->relowner;
3927  nattrs = classForm->relnatts;
3928 
3929  ReleaseSysCache(classTuple);
3930 
3931  /*
3932  * Initialize result in case there are no non-dropped columns. We want to
3933  * report failure in such cases for either value of 'how'.
3934  */
3935  result = ACLCHECK_NO_PRIV;
3936 
3937  for (curr_att = 1; curr_att <= nattrs; curr_att++)
3938  {
3939  HeapTuple attTuple;
3940  Datum aclDatum;
3941  bool isNull;
3942  Acl *acl;
3943  AclMode attmask;
3944 
3945  attTuple = SearchSysCache2(ATTNUM,
3946  ObjectIdGetDatum(table_oid),
3947  Int16GetDatum(curr_att));
3948 
3949  /*
3950  * Lookup failure probably indicates that the table was just dropped,
3951  * but we'll treat it the same as a dropped column rather than
3952  * throwing error.
3953  */
3954  if (!HeapTupleIsValid(attTuple))
3955  continue;
3956 
3957  /* ignore dropped columns */
3958  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
3959  {
3960  ReleaseSysCache(attTuple);
3961  continue;
3962  }
3963 
3964  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3965  &isNull);
3966 
3967  /*
3968  * Here we hard-wire knowledge that the default ACL for a column
3969  * grants no privileges, so that we can fall out quickly in the very
3970  * common case where attacl is null.
3971  */
3972  if (isNull)
3973  attmask = 0;
3974  else
3975  {
3976  /* detoast column's ACL if necessary */
3977  acl = DatumGetAclP(aclDatum);
3978 
3979  attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
3980 
3981  /* if we have a detoasted copy, free it */
3982  if ((Pointer) acl != DatumGetPointer(aclDatum))
3983  pfree(acl);
3984  }
3985 
3986  ReleaseSysCache(attTuple);
3987 
3988  if (attmask != 0)
3989  {
3990  result = ACLCHECK_OK;
3991  if (how == ACLMASK_ANY)
3992  break; /* succeed on any success */
3993  }
3994  else
3995  {
3996  result = ACLCHECK_NO_PRIV;
3997  if (how == ACLMASK_ALL)
3998  break; /* fail on any failure */
3999  }
4000  }
4001 
4002  return result;
4003 }
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1372
#define DatumGetAclP(X)
Definition: acl.h:120
int16 AttrNumber
Definition: attnum.h:21
char * Pointer
Definition: c.h:498
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:595
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:232

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

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

◆ pg_attribute_aclcheck_ext()

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

Definition at line 3854 of file aclchk.c.

3856 {
3857  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3858  ACLMASK_ANY, is_missing) != 0)
3859  return ACLCHECK_OK;
3860  else
3861  return ACLCHECK_NO_PRIV;
3862 }
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3132

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

4025 {
4026  if (pg_class_aclmask_ext(table_oid, roleid, mode,
4027  ACLMASK_ANY, is_missing) != 0)
4028  return ACLCHECK_OK;
4029  else
4030  return ACLCHECK_NO_PRIV;
4031 }
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3256

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

3248 {
3249  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3250 }

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

4052 {
4053  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4054  ACLMASK_ANY, snapshot) != 0)
4055  return ACLCHECK_OK;
4056  else
4057  return ACLCHECK_NO_PRIV;
4058 }
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3509

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

Referenced by has_lo_priv_byid(), and inv_open().

◆ pg_parameter_aclcheck()

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

Definition at line 4038 of file aclchk.c.

4039 {
4040  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4041  return ACLCHECK_OK;
4042  else
4043  return ACLCHECK_NO_PRIV;
4044 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3386
const char * name

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

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

◆ recordDependencyOnNewAcl()

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

Definition at line 4299 of file aclchk.c.

4301 {
4302  int nmembers;
4303  Oid *members;
4304 
4305  /* Nothing to do if ACL is defaulted */
4306  if (acl == NULL)
4307  return;
4308 
4309  /* Extract roles mentioned in ACL */
4310  nmembers = aclmembers(acl, &members);
4311 
4312  /* Update the shared dependency ACL info */
4313  updateAclDependencies(classId, objectId, objsubId,
4314  ownerId,
4315  0, NULL,
4316  nmembers, members);
4317 }
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1524
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:491

References aclmembers(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4326 of file aclchk.c.

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

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4490 of file aclchk.c.

4491 {
4492  /*
4493  * If this is a relation then we need to see if there are any sub-objects
4494  * (eg: columns) for it and, if so, be sure to call
4495  * recordExtensionInitPrivWorker() for each one.
4496  */
4497  if (classoid == RelationRelationId)
4498  {
4499  Form_pg_class pg_class_tuple;
4500  HeapTuple tuple;
4501 
4502  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4503  if (!HeapTupleIsValid(tuple))
4504  elog(ERROR, "cache lookup failed for relation %u", objoid);
4505  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4506 
4507  /*
4508  * Indexes don't have permissions, neither do the pg_class rows for
4509  * composite types. (These cases are unreachable given the
4510  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4511  */
4512  if (pg_class_tuple->relkind == RELKIND_INDEX ||
4513  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4514  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4515  {
4516  ReleaseSysCache(tuple);
4517  return;
4518  }
4519 
4520  /*
4521  * If this isn't a sequence then it's possibly going to have
4522  * column-level ACLs associated with it.
4523  */
4524  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4525  {
4526  AttrNumber curr_att;
4527  AttrNumber nattrs = pg_class_tuple->relnatts;
4528 
4529  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4530  {
4531  HeapTuple attTuple;
4532 
4533  attTuple = SearchSysCache2(ATTNUM,
4534  ObjectIdGetDatum(objoid),
4535  Int16GetDatum(curr_att));
4536 
4537  if (!HeapTupleIsValid(attTuple))
4538  continue;
4539 
4540  /* when removing, remove all entries, even dropped columns */
4541 
4542  recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4543 
4544  ReleaseSysCache(attTuple);
4545  }
4546  }
4547 
4548  ReleaseSysCache(tuple);
4549  }
4550 
4551  /* Remove the record, if any, for the top-level object */
4552  recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4553 }

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

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

Definition at line 4839 of file aclchk.c.

4840 {
4841  Relation rel;
4842  ScanKeyData key[3];
4843  SysScanDesc scan;
4844  HeapTuple oldtuple;
4845  int cacheid;
4846  HeapTuple objtuple;
4847  Oid ownerId;
4848  Datum oldAclDatum;
4849  bool isNull;
4850  Acl *old_acl;
4851  Acl *new_acl;
4852  HeapTuple newtuple;
4853  int noldmembers;
4854  int nnewmembers;
4855  Oid *oldmembers;
4856  Oid *newmembers;
4857 
4858  /* Search for existing pg_init_privs entry for the target object. */
4859  rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4860 
4861  ScanKeyInit(&key[0],
4862  Anum_pg_init_privs_objoid,
4863  BTEqualStrategyNumber, F_OIDEQ,
4864  ObjectIdGetDatum(objid));
4865  ScanKeyInit(&key[1],
4866  Anum_pg_init_privs_classoid,
4867  BTEqualStrategyNumber, F_OIDEQ,
4868  ObjectIdGetDatum(classid));
4869  ScanKeyInit(&key[2],
4870  Anum_pg_init_privs_objsubid,
4871  BTEqualStrategyNumber, F_INT4EQ,
4872  Int32GetDatum(objsubid));
4873 
4874  scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4875  NULL, 3, key);
4876 
4877  /* There should exist only one entry or none. */
4878  oldtuple = systable_getnext(scan);
4879 
4880  if (!HeapTupleIsValid(oldtuple))
4881  {
4882  /*
4883  * Hmm, why are we here if there's no entry? But pack up and go away
4884  * quietly.
4885  */
4886  systable_endscan(scan);
4888  return;
4889  }
4890 
4891  /* Get a writable copy of the existing ACL. */
4892  oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4893  RelationGetDescr(rel), &isNull);
4894  Assert(!isNull);
4895  old_acl = DatumGetAclPCopy(oldAclDatum);
4896 
4897  /*
4898  * We need the members of both old and new ACLs so we can correct the
4899  * shared dependency information. Collect data before
4900  * merge_acl_with_grant throws away old_acl.
4901  */
4902  noldmembers = aclmembers(old_acl, &oldmembers);
4903 
4904  /* Must find out the owner's OID the hard way. */
4905  cacheid = get_object_catcache_oid(classid);
4906  objtuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objid));
4907  if (!HeapTupleIsValid(objtuple))
4908  elog(ERROR, "cache lookup failed for %s %u",
4909  get_object_class_descr(classid), objid);
4910 
4911  ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4912  objtuple,
4913  get_object_attnum_owner(classid)));
4914  ReleaseSysCache(objtuple);
4915 
4916  /*
4917  * Generate new ACL. Grantor of rights is always the same as the owner.
4918  */
4919  if (old_acl != NULL)
4920  new_acl = merge_acl_with_grant(old_acl,
4921  false, /* is_grant */
4922  false, /* grant_option */
4923  DROP_RESTRICT,
4924  list_make1_oid(roleid),
4926  ownerId,
4927  ownerId);
4928  else
4929  new_acl = NULL; /* this case shouldn't happen, probably */
4930 
4931  /* If we end with an empty ACL, delete the pg_init_privs entry. */
4932  if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4933  {
4934  CatalogTupleDelete(rel, &oldtuple->t_self);
4935  }
4936  else
4937  {
4938  Datum values[Natts_pg_init_privs] = {0};
4939  bool nulls[Natts_pg_init_privs] = {0};
4940  bool replaces[Natts_pg_init_privs] = {0};
4941 
4942  /* Update existing entry. */
4943  values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4944  replaces[Anum_pg_init_privs_initprivs - 1] = true;
4945 
4946  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4947  values, nulls, replaces);
4948  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4949  }
4950 
4951  /*
4952  * Update the shared dependency ACL info.
4953  */
4954  nnewmembers = aclmembers(new_acl, &newmembers);
4955 
4956  updateInitAclDependencies(classid, objid, objsubid,
4957  noldmembers, oldmembers,
4958  nnewmembers, newmembers);
4959 
4960  systable_endscan(scan);
4961 
4962  /* prevent error when processing objects multiple times */
4964 
4966 }
#define ACLITEM_ALL_PRIV_BITS
Definition: acl.h:87
#define DatumGetAclPCopy(X)
Definition: acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition: aclchk.c:182
static Datum values[MAXATTR]
Definition: bootstrap.c:151
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1209
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
#define list_make1_oid(x1)
Definition: pg_list.h:242
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:512
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
ItemPointerData t_self
Definition: htup.h:65
void CommandCounterIncrement(void)
Definition: xact.c:1099

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

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1393 of file aclchk.c.

1394 {
1395  if (classid == DefaultAclRelationId)
1396  {
1397  InternalDefaultACL iacls;
1398  Form_pg_default_acl pg_default_acl_tuple;
1399  Relation rel;
1400  ScanKeyData skey[1];
1401  SysScanDesc scan;
1402  HeapTuple tuple;
1403 
1404  /* first fetch info needed by SetDefaultACL */
1405  rel = table_open(DefaultAclRelationId, AccessShareLock);
1406 
1407  ScanKeyInit(&skey[0],
1408  Anum_pg_default_acl_oid,
1409  BTEqualStrategyNumber, F_OIDEQ,
1410  ObjectIdGetDatum(objid));
1411 
1412  scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1413  NULL, 1, skey);
1414 
1415  tuple = systable_getnext(scan);
1416 
1417  if (!HeapTupleIsValid(tuple))
1418  elog(ERROR, "could not find tuple for default ACL %u", objid);
1419 
1420  pg_default_acl_tuple = (Form_pg_default_acl) GETSTRUCT(tuple);
1421 
1422  iacls.roleid = pg_default_acl_tuple->defaclrole;
1423  iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1424 
1425  switch (pg_default_acl_tuple->defaclobjtype)
1426  {
1427  case DEFACLOBJ_RELATION:
1428  iacls.objtype = OBJECT_TABLE;
1429  break;
1430  case DEFACLOBJ_SEQUENCE:
1431  iacls.objtype = OBJECT_SEQUENCE;
1432  break;
1433  case DEFACLOBJ_FUNCTION:
1434  iacls.objtype = OBJECT_FUNCTION;
1435  break;
1436  case DEFACLOBJ_TYPE:
1437  iacls.objtype = OBJECT_TYPE;
1438  break;
1439  case DEFACLOBJ_NAMESPACE:
1440  iacls.objtype = OBJECT_SCHEMA;
1441  break;
1442  default:
1443  /* Shouldn't get here */
1444  elog(ERROR, "unexpected default ACL type: %d",
1445  (int) pg_default_acl_tuple->defaclobjtype);
1446  break;
1447  }
1448 
1449  systable_endscan(scan);
1451 
1452  iacls.is_grant = false;
1453  iacls.all_privs = true;
1454  iacls.privileges = ACL_NO_RIGHTS;
1455  iacls.grantees = list_make1_oid(roleid);
1456  iacls.grant_option = false;
1457  iacls.behavior = DROP_CASCADE;
1458 
1459  /* Do it */
1460  SetDefaultACL(&iacls);
1461  }
1462  else
1463  {
1464  InternalGrant istmt;
1465 
1466  switch (classid)
1467  {
1468  case RelationRelationId:
1469  /* it's OK to use TABLE for a sequence */
1470  istmt.objtype = OBJECT_TABLE;
1471  break;
1472  case DatabaseRelationId:
1473  istmt.objtype = OBJECT_DATABASE;
1474  break;
1475  case TypeRelationId:
1476  istmt.objtype = OBJECT_TYPE;
1477  break;
1478  case ProcedureRelationId:
1479  istmt.objtype = OBJECT_ROUTINE;
1480  break;
1481  case LanguageRelationId:
1482  istmt.objtype = OBJECT_LANGUAGE;
1483  break;
1484  case LargeObjectRelationId:
1485  istmt.objtype = OBJECT_LARGEOBJECT;
1486  break;
1487  case NamespaceRelationId:
1488  istmt.objtype = OBJECT_SCHEMA;
1489  break;
1490  case TableSpaceRelationId:
1491  istmt.objtype = OBJECT_TABLESPACE;
1492  break;
1493  case ForeignServerRelationId:
1495  break;
1496  case ForeignDataWrapperRelationId:
1497  istmt.objtype = OBJECT_FDW;
1498  break;
1499  case ParameterAclRelationId:
1500  istmt.objtype = OBJECT_PARAMETER_ACL;
1501  break;
1502  default:
1503  elog(ERROR, "unexpected object class %u", classid);
1504  break;
1505  }
1506  istmt.is_grant = false;
1507  istmt.objects = list_make1_oid(objid);
1508  istmt.all_privs = true;
1509  istmt.privileges = ACL_NO_RIGHTS;
1510  istmt.col_privs = NIL;
1511  istmt.grantees = list_make1_oid(roleid);
1512  istmt.grant_option = false;
1513  istmt.behavior = DROP_CASCADE;
1514 
1515  ExecGrantStmt_oids(&istmt);
1516  }
1517 }
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition: aclchk.c:1130
@ DROP_CASCADE
Definition: parsenodes.h:2342
FormData_pg_default_acl * Form_pg_default_acl

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

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

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

Definition at line 4730 of file aclchk.c.

4732 {
4733  Relation rel;
4734  ScanKeyData key[3];
4735  SysScanDesc scan;
4736  HeapTuple oldtuple;
4737  Datum oldAclDatum;
4738  bool isNull;
4739  Acl *old_acl;
4740  Acl *new_acl;
4741  HeapTuple newtuple;
4742  int noldmembers;
4743  int nnewmembers;
4744  Oid *oldmembers;
4745  Oid *newmembers;
4746 
4747  /* Search for existing pg_init_privs entry for the target object. */
4748  rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4749 
4750  ScanKeyInit(&key[0],
4751  Anum_pg_init_privs_objoid,
4752  BTEqualStrategyNumber, F_OIDEQ,
4753  ObjectIdGetDatum(objid));
4754  ScanKeyInit(&key[1],
4755  Anum_pg_init_privs_classoid,
4756  BTEqualStrategyNumber, F_OIDEQ,
4757  ObjectIdGetDatum(classid));
4758  ScanKeyInit(&key[2],
4759  Anum_pg_init_privs_objsubid,
4760  BTEqualStrategyNumber, F_INT4EQ,
4761  Int32GetDatum(objsubid));
4762 
4763  scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4764  NULL, 3, key);
4765 
4766  /* There should exist only one entry or none. */
4767  oldtuple = systable_getnext(scan);
4768 
4769  if (!HeapTupleIsValid(oldtuple))
4770  {
4771  /*
4772  * Hmm, why are we here if there's no entry? But pack up and go away
4773  * quietly.
4774  */
4775  systable_endscan(scan);
4777  return;
4778  }
4779 
4780  /* Get a writable copy of the existing ACL. */
4781  oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4782  RelationGetDescr(rel), &isNull);
4783  Assert(!isNull);
4784  old_acl = DatumGetAclPCopy(oldAclDatum);
4785 
4786  /*
4787  * Generate new ACL. This usage of aclnewowner is a bit off-label when
4788  * oldroleid isn't the owner; but it does the job fine.
4789  */
4790  new_acl = aclnewowner(old_acl, oldroleid, newroleid);
4791 
4792  /*
4793  * If we end with an empty ACL, delete the pg_init_privs entry. (That
4794  * probably can't happen here, but we may as well cover the case.)
4795  */
4796  if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4797  {
4798  CatalogTupleDelete(rel, &oldtuple->t_self);
4799  }
4800  else
4801  {
4802  Datum values[Natts_pg_init_privs] = {0};
4803  bool nulls[Natts_pg_init_privs] = {0};
4804  bool replaces[Natts_pg_init_privs] = {0};
4805 
4806  /* Update existing entry. */
4807  values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4808  replaces[Anum_pg_init_privs_initprivs - 1] = true;
4809 
4810  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4811  values, nulls, replaces);
4812  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4813  }
4814 
4815  /*
4816  * Update the shared dependency ACL info.
4817  */
4818  noldmembers = aclmembers(old_acl, &oldmembers);
4819  nnewmembers = aclmembers(new_acl, &newmembers);
4820 
4821  updateInitAclDependencies(classid, objid, objsubid,
4822  noldmembers, oldmembers,
4823  nnewmembers, newmembers);
4824 
4825  systable_endscan(scan);
4826 
4827  /* prevent error when processing objects multiple times */
4829 
4831 }
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1103

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

Referenced by shdepReassignOwned_InitAcl().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5423 of file acl.c.

5424 {
5425  Oid admin_role;
5426 
5427  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5428  if (member == role)
5429  return InvalidOid;
5430 
5431  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5432  return admin_role;
5433 }

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

5481 {
5482  AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5483  List *roles_list;
5484  int nrights;
5485  ListCell *l;
5486 
5487  /*
5488  * The object owner is always treated as having all grant options, so if
5489  * roleId is the owner it's easy. Also, if roleId is a superuser it's
5490  * easy: superusers are implicitly members of every role, so they act as
5491  * the object owner.
5492  */
5493  if (roleId == ownerId || superuser_arg(roleId))
5494  {
5495  *grantorId = ownerId;
5496  *grantOptions = needed_goptions;
5497  return;
5498  }
5499 
5500  /*
5501  * Otherwise we have to do a careful search to see if roleId has the
5502  * privileges of any suitable role. Note: we can hang onto the result of
5503  * roles_is_member_of() throughout this loop, because aclmask_direct()
5504  * doesn't query any role memberships.
5505  */
5506  roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5507  InvalidOid, NULL);
5508 
5509  /* initialize candidate result as default */
5510  *grantorId = roleId;
5511  *grantOptions = ACL_NO_RIGHTS;
5512  nrights = 0;
5513 
5514  foreach(l, roles_list)
5515  {
5516  Oid otherrole = lfirst_oid(l);
5517  AclMode otherprivs;
5518 
5519  otherprivs = aclmask_direct(acl, otherrole, ownerId,
5520  needed_goptions, ACLMASK_ALL);
5521  if (otherprivs == needed_goptions)
5522  {
5523  /* Found a suitable grantor */
5524  *grantorId = otherrole;
5525  *grantOptions = otherprivs;
5526  return;
5527  }
5528 
5529  /*
5530  * If it has just some of the needed privileges, remember best
5531  * candidate.
5532  */
5533  if (otherprivs != ACL_NO_RIGHTS)
5534  {
5535  int nnewrights = count_one_bits(otherprivs);
5536 
5537  if (nnewrights > nrights)
5538  {
5539  *grantorId = otherrole;
5540  *grantOptions = otherprivs;
5541  nrights = nnewrights;
5542  }
5543  }
5544  }
5545 }
static int count_one_bits(AclMode mask)
Definition: acl.c:5438
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1461
#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().