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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

#define ACL_ID_PUBLIC   0 /* placeholder for id in a PUBLIC acl item */
 
#define ACLITEM_GET_PRIVS(item)   ((item).ai_privs & 0xFFFF)
 
#define ACLITEM_GET_GOPTIONS(item)   (((item).ai_privs >> 16) & 0xFFFF)
 
#define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
 
#define ACL_GRANT_OPTION_FOR(privs)   (((AclMode) (privs) & 0xFFFF) << 16)
 
#define ACL_OPTION_TO_PRIVS(privs)   (((AclMode) (privs) >> 16) & 0xFFFF)
 
#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) 0xFFFF)
 
#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFF << 16)
 
#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_ALL_RIGHTS_STR   "arwdDxtXUCTc"
 
#define ACL_ALL_RIGHTS_COLUMN   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
 
#define ACL_ALL_RIGHTS_RELATION   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER)
 
#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
 
#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)
 
#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_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 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)
 
void check_is_member_of_role (Oid member, Oid role)
 
Oid get_role_oid (const char *rolename, bool missing_ok)
 
Oid get_role_oid_or_public (const char *rolename)
 
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_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_attribute_aclmask_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_class_aclmask_ext (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
AclMode pg_database_aclmask (Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_proc_aclmask (Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_language_aclmask (Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_largeobject_aclmask_snapshot (Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
 
AclMode pg_namespace_aclmask (Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_tablespace_aclmask (Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_data_wrapper_aclmask (Oid fdw_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_server_aclmask (Oid srv_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_type_aclmask (Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_database_aclcheck (Oid db_oid, Oid roleid, AclMode mode)
 
AclResult pg_proc_aclcheck (Oid proc_oid, Oid roleid, AclMode mode)
 
AclResult pg_language_aclcheck (Oid lang_oid, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lang_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
AclResult pg_namespace_aclcheck (Oid nsp_oid, Oid roleid, AclMode mode)
 
AclResult pg_tablespace_aclcheck (Oid spc_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_data_wrapper_aclcheck (Oid fdw_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_server_aclcheck (Oid srv_oid, Oid roleid, AclMode mode)
 
AclResult pg_type_aclcheck (Oid type_oid, Oid roleid, AclMode mode)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
bool pg_class_ownercheck (Oid class_oid, Oid roleid)
 
bool pg_type_ownercheck (Oid type_oid, Oid roleid)
 
bool pg_oper_ownercheck (Oid oper_oid, Oid roleid)
 
bool pg_proc_ownercheck (Oid proc_oid, Oid roleid)
 
bool pg_language_ownercheck (Oid lan_oid, Oid roleid)
 
bool pg_largeobject_ownercheck (Oid lobj_oid, Oid roleid)
 
bool pg_namespace_ownercheck (Oid nsp_oid, Oid roleid)
 
bool pg_tablespace_ownercheck (Oid spc_oid, Oid roleid)
 
bool pg_opclass_ownercheck (Oid opc_oid, Oid roleid)
 
bool pg_opfamily_ownercheck (Oid opf_oid, Oid roleid)
 
bool pg_database_ownercheck (Oid db_oid, Oid roleid)
 
bool pg_collation_ownercheck (Oid coll_oid, Oid roleid)
 
bool pg_conversion_ownercheck (Oid conv_oid, Oid roleid)
 
bool pg_ts_dict_ownercheck (Oid dict_oid, Oid roleid)
 
bool pg_ts_config_ownercheck (Oid cfg_oid, Oid roleid)
 
bool pg_foreign_data_wrapper_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_foreign_server_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_event_trigger_ownercheck (Oid et_oid, Oid roleid)
 
bool pg_extension_ownercheck (Oid ext_oid, Oid roleid)
 
bool pg_publication_ownercheck (Oid pub_oid, Oid roleid)
 
bool pg_subscription_ownercheck (Oid sub_oid, Oid roleid)
 
bool pg_statistics_object_ownercheck (Oid stat_oid, 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 156 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 157 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 158 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTc"

Definition at line 151 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 167 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) & 0xFFFF) << 16)

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

#define ACL_OPTION_TO_PRIVS (   privs)    (((AclMode) (privs) >> 16) & 0xFFFF)

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_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) 0xFFFF << 16)

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

#define ACLITEM_GET_GOPTIONS (   item)    (((item).ai_privs >> 16) & 0xFFFF)

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

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) 0xFFFF) << 16)) | \
(((AclMode) (goptions) & 0xFFFF) << 16))
uint32 AclMode
Definition: parsenodes.h:80

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) 0xFFFF)) | \
((AclMode) (privs) & 0xFFFF))

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) & 0xFFFF) | \
(((AclMode) (goptions) & 0xFFFF) << 16))

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 170 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 177 of file acl.h.

178 {
179  ACLCHECK_OK = 0,
182 } AclResult;
AclResult
Definition: acl.h:178
@ ACLCHECK_NO_PRIV
Definition: acl.h:180
@ ACLCHECK_OK
Definition: acl.h:179
@ ACLCHECK_NOT_OWNER
Definition: acl.h:181

Function Documentation

◆ aclcheck_error()

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

Definition at line 3308 of file aclchk.c.

3310 {
3311  switch (aclerr)
3312  {
3313  case ACLCHECK_OK:
3314  /* no error, so return to caller */
3315  break;
3316  case ACLCHECK_NO_PRIV:
3317  {
3318  const char *msg = "???";
3319 
3320  switch (objtype)
3321  {
3322  case OBJECT_AGGREGATE:
3323  msg = gettext_noop("permission denied for aggregate %s");
3324  break;
3325  case OBJECT_COLLATION:
3326  msg = gettext_noop("permission denied for collation %s");
3327  break;
3328  case OBJECT_COLUMN:
3329  msg = gettext_noop("permission denied for column %s");
3330  break;
3331  case OBJECT_CONVERSION:
3332  msg = gettext_noop("permission denied for conversion %s");
3333  break;
3334  case OBJECT_DATABASE:
3335  msg = gettext_noop("permission denied for database %s");
3336  break;
3337  case OBJECT_DOMAIN:
3338  msg = gettext_noop("permission denied for domain %s");
3339  break;
3340  case OBJECT_EVENT_TRIGGER:
3341  msg = gettext_noop("permission denied for event trigger %s");
3342  break;
3343  case OBJECT_EXTENSION:
3344  msg = gettext_noop("permission denied for extension %s");
3345  break;
3346  case OBJECT_FDW:
3347  msg = gettext_noop("permission denied for foreign-data wrapper %s");
3348  break;
3349  case OBJECT_FOREIGN_SERVER:
3350  msg = gettext_noop("permission denied for foreign server %s");
3351  break;
3352  case OBJECT_FOREIGN_TABLE:
3353  msg = gettext_noop("permission denied for foreign table %s");
3354  break;
3355  case OBJECT_FUNCTION:
3356  msg = gettext_noop("permission denied for function %s");
3357  break;
3358  case OBJECT_INDEX:
3359  msg = gettext_noop("permission denied for index %s");
3360  break;
3361  case OBJECT_LANGUAGE:
3362  msg = gettext_noop("permission denied for language %s");
3363  break;
3364  case OBJECT_LARGEOBJECT:
3365  msg = gettext_noop("permission denied for large object %s");
3366  break;
3367  case OBJECT_MATVIEW:
3368  msg = gettext_noop("permission denied for materialized view %s");
3369  break;
3370  case OBJECT_OPCLASS:
3371  msg = gettext_noop("permission denied for operator class %s");
3372  break;
3373  case OBJECT_OPERATOR:
3374  msg = gettext_noop("permission denied for operator %s");
3375  break;
3376  case OBJECT_OPFAMILY:
3377  msg = gettext_noop("permission denied for operator family %s");
3378  break;
3379  case OBJECT_POLICY:
3380  msg = gettext_noop("permission denied for policy %s");
3381  break;
3382  case OBJECT_PROCEDURE:
3383  msg = gettext_noop("permission denied for procedure %s");
3384  break;
3385  case OBJECT_PUBLICATION:
3386  msg = gettext_noop("permission denied for publication %s");
3387  break;
3388  case OBJECT_ROUTINE:
3389  msg = gettext_noop("permission denied for routine %s");
3390  break;
3391  case OBJECT_SCHEMA:
3392  msg = gettext_noop("permission denied for schema %s");
3393  break;
3394  case OBJECT_SEQUENCE:
3395  msg = gettext_noop("permission denied for sequence %s");
3396  break;
3397  case OBJECT_STATISTIC_EXT:
3398  msg = gettext_noop("permission denied for statistics object %s");
3399  break;
3400  case OBJECT_SUBSCRIPTION:
3401  msg = gettext_noop("permission denied for subscription %s");
3402  break;
3403  case OBJECT_TABLE:
3404  msg = gettext_noop("permission denied for table %s");
3405  break;
3406  case OBJECT_TABLESPACE:
3407  msg = gettext_noop("permission denied for tablespace %s");
3408  break;
3410  msg = gettext_noop("permission denied for text search configuration %s");
3411  break;
3412  case OBJECT_TSDICTIONARY:
3413  msg = gettext_noop("permission denied for text search dictionary %s");
3414  break;
3415  case OBJECT_TYPE:
3416  msg = gettext_noop("permission denied for type %s");
3417  break;
3418  case OBJECT_VIEW:
3419  msg = gettext_noop("permission denied for view %s");
3420  break;
3421  /* these currently aren't used */
3422  case OBJECT_ACCESS_METHOD:
3423  case OBJECT_AMOP:
3424  case OBJECT_AMPROC:
3425  case OBJECT_ATTRIBUTE:
3426  case OBJECT_CAST:
3427  case OBJECT_DEFAULT:
3428  case OBJECT_DEFACL:
3429  case OBJECT_DOMCONSTRAINT:
3432  case OBJECT_ROLE:
3433  case OBJECT_RULE:
3434  case OBJECT_TABCONSTRAINT:
3435  case OBJECT_TRANSFORM:
3436  case OBJECT_TRIGGER:
3437  case OBJECT_TSPARSER:
3438  case OBJECT_TSTEMPLATE:
3439  case OBJECT_USER_MAPPING:
3440  elog(ERROR, "unsupported object type %d", objtype);
3441  }
3442 
3443  ereport(ERROR,
3444  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3445  errmsg(msg, objectname)));
3446  break;
3447  }
3448  case ACLCHECK_NOT_OWNER:
3449  {
3450  const char *msg = "???";
3451 
3452  switch (objtype)
3453  {
3454  case OBJECT_AGGREGATE:
3455  msg = gettext_noop("must be owner of aggregate %s");
3456  break;
3457  case OBJECT_COLLATION:
3458  msg = gettext_noop("must be owner of collation %s");
3459  break;
3460  case OBJECT_CONVERSION:
3461  msg = gettext_noop("must be owner of conversion %s");
3462  break;
3463  case OBJECT_DATABASE:
3464  msg = gettext_noop("must be owner of database %s");
3465  break;
3466  case OBJECT_DOMAIN:
3467  msg = gettext_noop("must be owner of domain %s");
3468  break;
3469  case OBJECT_EVENT_TRIGGER:
3470  msg = gettext_noop("must be owner of event trigger %s");
3471  break;
3472  case OBJECT_EXTENSION:
3473  msg = gettext_noop("must be owner of extension %s");
3474  break;
3475  case OBJECT_FDW:
3476  msg = gettext_noop("must be owner of foreign-data wrapper %s");
3477  break;
3478  case OBJECT_FOREIGN_SERVER:
3479  msg = gettext_noop("must be owner of foreign server %s");
3480  break;
3481  case OBJECT_FOREIGN_TABLE:
3482  msg = gettext_noop("must be owner of foreign table %s");
3483  break;
3484  case OBJECT_FUNCTION:
3485  msg = gettext_noop("must be owner of function %s");
3486  break;
3487  case OBJECT_INDEX:
3488  msg = gettext_noop("must be owner of index %s");
3489  break;
3490  case OBJECT_LANGUAGE:
3491  msg = gettext_noop("must be owner of language %s");
3492  break;
3493  case OBJECT_LARGEOBJECT:
3494  msg = gettext_noop("must be owner of large object %s");
3495  break;
3496  case OBJECT_MATVIEW:
3497  msg = gettext_noop("must be owner of materialized view %s");
3498  break;
3499  case OBJECT_OPCLASS:
3500  msg = gettext_noop("must be owner of operator class %s");
3501  break;
3502  case OBJECT_OPERATOR:
3503  msg = gettext_noop("must be owner of operator %s");
3504  break;
3505  case OBJECT_OPFAMILY:
3506  msg = gettext_noop("must be owner of operator family %s");
3507  break;
3508  case OBJECT_PROCEDURE:
3509  msg = gettext_noop("must be owner of procedure %s");
3510  break;
3511  case OBJECT_PUBLICATION:
3512  msg = gettext_noop("must be owner of publication %s");
3513  break;
3514  case OBJECT_ROUTINE:
3515  msg = gettext_noop("must be owner of routine %s");
3516  break;
3517  case OBJECT_SEQUENCE:
3518  msg = gettext_noop("must be owner of sequence %s");
3519  break;
3520  case OBJECT_SUBSCRIPTION:
3521  msg = gettext_noop("must be owner of subscription %s");
3522  break;
3523  case OBJECT_TABLE:
3524  msg = gettext_noop("must be owner of table %s");
3525  break;
3526  case OBJECT_TYPE:
3527  msg = gettext_noop("must be owner of type %s");
3528  break;
3529  case OBJECT_VIEW:
3530  msg = gettext_noop("must be owner of view %s");
3531  break;
3532  case OBJECT_SCHEMA:
3533  msg = gettext_noop("must be owner of schema %s");
3534  break;
3535  case OBJECT_STATISTIC_EXT:
3536  msg = gettext_noop("must be owner of statistics object %s");
3537  break;
3538  case OBJECT_TABLESPACE:
3539  msg = gettext_noop("must be owner of tablespace %s");
3540  break;
3542  msg = gettext_noop("must be owner of text search configuration %s");
3543  break;
3544  case OBJECT_TSDICTIONARY:
3545  msg = gettext_noop("must be owner of text search dictionary %s");
3546  break;
3547 
3548  /*
3549  * Special cases: For these, the error message talks
3550  * about "relation", because that's where the
3551  * ownership is attached. See also
3552  * check_object_ownership().
3553  */
3554  case OBJECT_COLUMN:
3555  case OBJECT_POLICY:
3556  case OBJECT_RULE:
3557  case OBJECT_TABCONSTRAINT:
3558  case OBJECT_TRIGGER:
3559  msg = gettext_noop("must be owner of relation %s");
3560  break;
3561  /* these currently aren't used */
3562  case OBJECT_ACCESS_METHOD:
3563  case OBJECT_AMOP:
3564  case OBJECT_AMPROC:
3565  case OBJECT_ATTRIBUTE:
3566  case OBJECT_CAST:
3567  case OBJECT_DEFAULT:
3568  case OBJECT_DEFACL:
3569  case OBJECT_DOMCONSTRAINT:
3572  case OBJECT_ROLE:
3573  case OBJECT_TRANSFORM:
3574  case OBJECT_TSPARSER:
3575  case OBJECT_TSTEMPLATE:
3576  case OBJECT_USER_MAPPING:
3577  elog(ERROR, "unsupported object type %d", objtype);
3578  }
3579 
3580  ereport(ERROR,
3581  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3582  errmsg(msg, objectname)));
3583  break;
3584  }
3585  default:
3586  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3587  break;
3588  }
3589 }
#define gettext_noop(x)
Definition: c.h:1194
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
#define ereport(elevel,...)
Definition: elog.h:143
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:1803
@ OBJECT_FDW
Definition: parsenodes.h:1805
@ OBJECT_TSPARSER
Definition: parsenodes.h:1835
@ OBJECT_COLLATION
Definition: parsenodes.h:1796
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:1838
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:1789
@ OBJECT_OPCLASS
Definition: parsenodes.h:1813
@ OBJECT_DEFACL
Definition: parsenodes.h:1800
@ OBJECT_AGGREGATE
Definition: parsenodes.h:1790
@ OBJECT_MATVIEW
Definition: parsenodes.h:1812
@ OBJECT_SCHEMA
Definition: parsenodes.h:1824
@ OBJECT_POLICY
Definition: parsenodes.h:1816
@ OBJECT_OPERATOR
Definition: parsenodes.h:1814
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:1807
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:1833
@ OBJECT_OPFAMILY
Definition: parsenodes.h:1815
@ OBJECT_DOMAIN
Definition: parsenodes.h:1801
@ OBJECT_COLUMN
Definition: parsenodes.h:1795
@ OBJECT_TABLESPACE
Definition: parsenodes.h:1830
@ OBJECT_ROLE
Definition: parsenodes.h:1821
@ OBJECT_ROUTINE
Definition: parsenodes.h:1822
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:1811
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:1819
@ OBJECT_PROCEDURE
Definition: parsenodes.h:1817
@ OBJECT_EXTENSION
Definition: parsenodes.h:1804
@ OBJECT_INDEX
Definition: parsenodes.h:1809
@ OBJECT_DEFAULT
Definition: parsenodes.h:1799
@ OBJECT_DATABASE
Definition: parsenodes.h:1798
@ OBJECT_SEQUENCE
Definition: parsenodes.h:1825
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:1836
@ OBJECT_LANGUAGE
Definition: parsenodes.h:1810
@ OBJECT_AMOP
Definition: parsenodes.h:1791
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:1820
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:1806
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:1834
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:1793
@ OBJECT_PUBLICATION
Definition: parsenodes.h:1818
@ OBJECT_RULE
Definition: parsenodes.h:1823
@ OBJECT_CONVERSION
Definition: parsenodes.h:1797
@ OBJECT_AMPROC
Definition: parsenodes.h:1792
@ OBJECT_TABLE
Definition: parsenodes.h:1829
@ OBJECT_VIEW
Definition: parsenodes.h:1839
@ OBJECT_TYPE
Definition: parsenodes.h:1837
@ OBJECT_FUNCTION
Definition: parsenodes.h:1808
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:1828
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:1802
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:1826
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:1827
@ OBJECT_CAST
Definition: parsenodes.h:1794
@ OBJECT_TRIGGER
Definition: parsenodes.h:1832
@ OBJECT_TRANSFORM
Definition: parsenodes.h:1831

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_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(), 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(), 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(), ExecCheckRTPerms(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), get_rel_from_relname(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_prewarm(), pgrowlocks(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

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

Definition at line 3593 of file aclchk.c.

3595 {
3596  switch (aclerr)
3597  {
3598  case ACLCHECK_OK:
3599  /* no error, so return to caller */
3600  break;
3601  case ACLCHECK_NO_PRIV:
3602  ereport(ERROR,
3603  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3604  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3605  colname, objectname)));
3606  break;
3607  case ACLCHECK_NOT_OWNER:
3608  /* relation msg is OK since columns don't have separate owners */
3609  aclcheck_error(aclerr, objtype, objectname);
3610  break;
3611  default:
3612  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3613  break;
3614  }
3615 }
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3308

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

414 {
415  Acl *result_acl;
416 
417  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
418 
419  memcpy(ACL_DAT(result_acl),
420  ACL_DAT(left_acl),
421  ACL_NUM(left_acl) * sizeof(AclItem));
422 
423  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
424  ACL_DAT(right_acl),
425  ACL_NUM(right_acl) * sizeof(AclItem));
426 
427  return result_acl;
428 }
static Acl * allocacl(int n)
Definition: acl.c:362
#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 393 of file acl.c.

394 {
395  Acl *result_acl;
396 
397  result_acl = allocacl(ACL_NUM(orig_acl));
398 
399  memcpy(ACL_DAT(result_acl),
400  ACL_DAT(orig_acl),
401  ACL_NUM(orig_acl) * sizeof(AclItem));
402 
403  return result_acl;
404 }

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 734 of file acl.c.

735 {
736  AclMode world_default;
737  AclMode owner_default;
738  int nacl;
739  Acl *acl;
740  AclItem *aip;
741 
742  switch (objtype)
743  {
744  case OBJECT_COLUMN:
745  /* by default, columns have no extra privileges */
746  world_default = ACL_NO_RIGHTS;
747  owner_default = ACL_NO_RIGHTS;
748  break;
749  case OBJECT_TABLE:
750  world_default = ACL_NO_RIGHTS;
751  owner_default = ACL_ALL_RIGHTS_RELATION;
752  break;
753  case OBJECT_SEQUENCE:
754  world_default = ACL_NO_RIGHTS;
755  owner_default = ACL_ALL_RIGHTS_SEQUENCE;
756  break;
757  case OBJECT_DATABASE:
758  /* for backwards compatibility, grant some rights by default */
759  world_default = ACL_CREATE_TEMP | ACL_CONNECT;
760  owner_default = ACL_ALL_RIGHTS_DATABASE;
761  break;
762  case OBJECT_FUNCTION:
763  /* Grant EXECUTE by default, for now */
764  world_default = ACL_EXECUTE;
765  owner_default = ACL_ALL_RIGHTS_FUNCTION;
766  break;
767  case OBJECT_LANGUAGE:
768  /* Grant USAGE by default, for now */
769  world_default = ACL_USAGE;
770  owner_default = ACL_ALL_RIGHTS_LANGUAGE;
771  break;
772  case OBJECT_LARGEOBJECT:
773  world_default = ACL_NO_RIGHTS;
774  owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
775  break;
776  case OBJECT_SCHEMA:
777  world_default = ACL_NO_RIGHTS;
778  owner_default = ACL_ALL_RIGHTS_SCHEMA;
779  break;
780  case OBJECT_TABLESPACE:
781  world_default = ACL_NO_RIGHTS;
782  owner_default = ACL_ALL_RIGHTS_TABLESPACE;
783  break;
784  case OBJECT_FDW:
785  world_default = ACL_NO_RIGHTS;
786  owner_default = ACL_ALL_RIGHTS_FDW;
787  break;
789  world_default = ACL_NO_RIGHTS;
790  owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
791  break;
792  case OBJECT_DOMAIN:
793  case OBJECT_TYPE:
794  world_default = ACL_USAGE;
795  owner_default = ACL_ALL_RIGHTS_TYPE;
796  break;
797  default:
798  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
799  world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
800  owner_default = ACL_NO_RIGHTS;
801  break;
802  }
803 
804  nacl = 0;
805  if (world_default != ACL_NO_RIGHTS)
806  nacl++;
807  if (owner_default != ACL_NO_RIGHTS)
808  nacl++;
809 
810  acl = allocacl(nacl);
811  aip = ACL_DAT(acl);
812 
813  if (world_default != ACL_NO_RIGHTS)
814  {
815  aip->ai_grantee = ACL_ID_PUBLIC;
816  aip->ai_grantor = ownerId;
817  ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
818  aip++;
819  }
820 
821  /*
822  * Note that the owner's entry shows all ordinary privileges but no grant
823  * options. This is because his grant options come "from the system" and
824  * not from his own efforts. (The SQL spec says that the owner's rights
825  * come from a "_SYSTEM" authid.) However, we do consider that the
826  * owner's ordinary privileges are self-granted; this lets him revoke
827  * them. We implement the owner's grant options without any explicit
828  * "_SYSTEM"-like ACL entry, by internally special-casing the owner
829  * wherever we are testing grant options.
830  */
831  if (owner_default != ACL_NO_RIGHTS)
832  {
833  aip->ai_grantee = ownerId;
834  aip->ai_grantor = ownerId;
835  ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
836  }
837 
838  return acl;
839 }
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:161
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:166
#define ACL_ALL_RIGHTS_SCHEMA
Definition: acl.h:165
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:158
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:159
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:162
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:163
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:167
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:160
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:157
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:164
#define ACL_CREATE_TEMP
Definition: parsenodes.h:92
#define ACL_USAGE
Definition: parsenodes.h:90
#define ACL_NO_RIGHTS
Definition: parsenodes.h:95
#define ACL_CONNECT
Definition: parsenodes.h:93
#define ACL_EXECUTE
Definition: parsenodes.h:89
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_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_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

Referenced by acldefault_sql(), buildDefaultACLCommands(), dumpACL(), dumpTable(), dumpTablespaces(), ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), get_user_default_acl(), pg_class_aclmask_ext(), pg_database_aclmask(), pg_foreign_data_wrapper_aclmask(), pg_foreign_server_aclmask(), pg_language_aclmask(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_proc_aclmask(), pg_tablespace_aclmask(), pg_type_aclmask(), and SetDefaultACL().

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 495 of file acl.c.

496 {
497  /* Check for cases where one or both are empty/null */
498  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
499  {
500  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
501  return true;
502  else
503  return false;
504  }
505  else
506  {
507  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
508  return false;
509  }
510 
511  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
512  return false;
513 
514  if (memcmp(ACL_DAT(left_acl),
515  ACL_DAT(right_acl),
516  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
517  return true;
518 
519  return false;
520 }

References ACL_DAT, and ACL_NUM.

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 481 of file acl.c.

482 {
483  if (acl != NULL && ACL_NUM(acl) > 1)
484  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
485 }
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:655
#define qsort(a, b, c, d)
Definition: port.h:495

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

1308 {
1309  AclMode result;
1311  AclItem *aidat;
1312  int i,
1313  num;
1314 
1315  /*
1316  * Null ACL should not happen, since caller should have inserted
1317  * appropriate default
1318  */
1319  if (acl == NULL)
1320  elog(ERROR, "null ACL");
1321 
1322  check_acl(acl);
1323 
1324  /* Quick exit for mask == 0 */
1325  if (mask == 0)
1326  return 0;
1327 
1328  result = 0;
1329 
1330  /* Owner always implicitly has all grant options */
1331  if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1332  has_privs_of_role(roleid, ownerId))
1333  {
1334  result = mask & ACLITEM_ALL_GOPTION_BITS;
1335  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1336  return result;
1337  }
1338 
1339  num = ACL_NUM(acl);
1340  aidat = ACL_DAT(acl);
1341 
1342  /*
1343  * Check privileges granted directly to roleid or to public
1344  */
1345  for (i = 0; i < num; i++)
1346  {
1347  AclItem *aidata = &aidat[i];
1348 
1349  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1350  aidata->ai_grantee == roleid)
1351  {
1352  result |= aidata->ai_privs & mask;
1353  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1354  return result;
1355  }
1356  }
1357 
1358  /*
1359  * Check privileges granted indirectly via role memberships. We do this in
1360  * a separate pass to minimize expensive indirect membership tests. In
1361  * particular, it's worth testing whether a given ACL entry grants any
1362  * privileges still of interest before we perform the has_privs_of_role
1363  * test.
1364  */
1365  remaining = mask & ~result;
1366  for (i = 0; i < num; i++)
1367  {
1368  AclItem *aidata = &aidat[i];
1369 
1370  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1371  aidata->ai_grantee == roleid)
1372  continue; /* already checked it */
1373 
1374  if ((aidata->ai_privs & remaining) &&
1375  has_privs_of_role(roleid, aidata->ai_grantee))
1376  {
1377  result |= aidata->ai_privs & mask;
1378  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1379  return result;
1380  remaining = mask & ~result;
1381  }
1382  }
1383 
1384  return result;
1385 }
static void check_acl(const Acl *acl)
Definition: acl.c:526
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4843
#define ACLITEM_ALL_GOPTION_BITS
Definition: acl.h:88
int remaining
Definition: informix.c:667
int i
Definition: isn.c:73
AclMode ai_privs
Definition: acl.h:58

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

Referenced by check_circularity(), LockTableAclCheck(), pg_attribute_aclmask_ext(), pg_class_aclmask_ext(), pg_database_aclmask(), pg_foreign_data_wrapper_aclmask(), pg_foreign_server_aclmask(), pg_language_aclmask(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_proc_aclmask(), pg_tablespace_aclmask(), pg_type_aclmask(), and recursive_revoke().

◆ aclmembers()

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

Definition at line 1458 of file acl.c.

1459 {
1460  Oid *list;
1461  const AclItem *acldat;
1462  int i,
1463  j;
1464 
1465  if (acl == NULL || ACL_NUM(acl) == 0)
1466  {
1467  *roleids = NULL;
1468  return 0;
1469  }
1470 
1471  check_acl(acl);
1472 
1473  /* Allocate the worst-case space requirement */
1474  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1475  acldat = ACL_DAT(acl);
1476 
1477  /*
1478  * Walk the ACL collecting mentioned RoleIds.
1479  */
1480  j = 0;
1481  for (i = 0; i < ACL_NUM(acl); i++)
1482  {
1483  const AclItem *ai = &acldat[i];
1484 
1485  if (ai->ai_grantee != ACL_ID_PUBLIC)
1486  list[j++] = ai->ai_grantee;
1487  /* grantor is currently never PUBLIC, but let's check anyway */
1488  if (ai->ai_grantor != ACL_ID_PUBLIC)
1489  list[j++] = ai->ai_grantor;
1490  }
1491 
1492  /* Sort the array */
1493  qsort(list, j, sizeof(Oid), oid_cmp);
1494 
1495  /*
1496  * We could repalloc the array down to minimum size, but it's hardly worth
1497  * it since it's only transient memory.
1498  */
1499  *roleids = list;
1500 
1501  /* Remove duplicates from the array */
1502  return qunique(list, j, sizeof(Oid), oid_cmp);
1503 }
int j
Definition: isn.c:74
void * palloc(Size size)
Definition: mcxt.c:1062
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:336
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_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), recordDependencyOnNewAcl(), and SetDefaultACL().

◆ aclmerge()

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

Definition at line 437 of file acl.c.

438 {
439  Acl *result_acl;
440  AclItem *aip;
441  int i,
442  num;
443 
444  /* Check for cases where one or both are empty/null */
445  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
446  {
447  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
448  return NULL;
449  else
450  return aclcopy(right_acl);
451  }
452  else
453  {
454  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
455  return aclcopy(left_acl);
456  }
457 
458  /* Merge them the hard way, one item at a time */
459  result_acl = aclcopy(left_acl);
460 
461  aip = ACL_DAT(right_acl);
462  num = ACL_NUM(right_acl);
463 
464  for (i = 0; i < num; i++, aip++)
465  {
466  Acl *tmp_acl;
467 
468  tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
469  ownerId, DROP_RESTRICT);
470  pfree(result_acl);
471  result_acl = tmp_acl;
472  }
473 
474  return result_acl;
475 }
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:916
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:393
#define ACL_MODECHG_ADD
Definition: acl.h:129
void pfree(void *pointer)
Definition: mcxt.c:1169
@ DROP_RESTRICT
Definition: parsenodes.h:1861

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

1038 {
1039  Acl *new_acl;
1040  AclItem *new_aip;
1041  AclItem *old_aip;
1042  AclItem *dst_aip;
1043  AclItem *src_aip;
1044  AclItem *targ_aip;
1045  bool newpresent = false;
1046  int dst,
1047  src,
1048  targ,
1049  num;
1050 
1051  check_acl(old_acl);
1052 
1053  /*
1054  * Make a copy of the given ACL, substituting new owner ID for old
1055  * wherever it appears as either grantor or grantee. Also note if the new
1056  * owner ID is already present.
1057  */
1058  num = ACL_NUM(old_acl);
1059  old_aip = ACL_DAT(old_acl);
1060  new_acl = allocacl(num);
1061  new_aip = ACL_DAT(new_acl);
1062  memcpy(new_aip, old_aip, num * sizeof(AclItem));
1063  for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1064  {
1065  if (dst_aip->ai_grantor == oldOwnerId)
1066  dst_aip->ai_grantor = newOwnerId;
1067  else if (dst_aip->ai_grantor == newOwnerId)
1068  newpresent = true;
1069  if (dst_aip->ai_grantee == oldOwnerId)
1070  dst_aip->ai_grantee = newOwnerId;
1071  else if (dst_aip->ai_grantee == newOwnerId)
1072  newpresent = true;
1073  }
1074 
1075  /*
1076  * If the old ACL contained any references to the new owner, then we may
1077  * now have generated an ACL containing duplicate entries. Find them and
1078  * merge them so that there are not duplicates. (This is relatively
1079  * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1080  * be the normal case.)
1081  *
1082  * To simplify deletion of duplicate entries, we temporarily leave them in
1083  * the array but set their privilege masks to zero; when we reach such an
1084  * entry it's just skipped. (Thus, a side effect of this code will be to
1085  * remove privilege-free entries, should there be any in the input.) dst
1086  * is the next output slot, targ is the currently considered input slot
1087  * (always >= dst), and src scans entries to the right of targ looking for
1088  * duplicates. Once an entry has been emitted to dst it is known
1089  * duplicate-free and need not be considered anymore.
1090  */
1091  if (newpresent)
1092  {
1093  dst = 0;
1094  for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1095  {
1096  /* ignore if deleted in an earlier pass */
1097  if (ACLITEM_GET_RIGHTS(*targ_aip) == ACL_NO_RIGHTS)
1098  continue;
1099  /* find and merge any duplicates */
1100  for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1101  src++, src_aip++)
1102  {
1103  if (ACLITEM_GET_RIGHTS(*src_aip) == ACL_NO_RIGHTS)
1104  continue;
1105  if (aclitem_match(targ_aip, src_aip))
1106  {
1107  ACLITEM_SET_RIGHTS(*targ_aip,
1108  ACLITEM_GET_RIGHTS(*targ_aip) |
1109  ACLITEM_GET_RIGHTS(*src_aip));
1110  /* mark the duplicate deleted */
1111  ACLITEM_SET_RIGHTS(*src_aip, ACL_NO_RIGHTS);
1112  }
1113  }
1114  /* and emit to output */
1115  new_aip[dst] = *targ_aip;
1116  dst++;
1117  }
1118  /* Adjust array size to be 'dst' items */
1119  ARR_DIMS(new_acl)[0] = dst;
1120  SET_VARSIZE(new_acl, ACL_N_SIZE(dst));
1121  }
1122 
1123  return new_acl;
1124 }
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition: acl.c:644
#define ACL_N_SIZE(N)
Definition: acl.h:110
#define ACLITEM_GET_RIGHTS(item)
Definition: acl.h:68
#define ACLITEM_SET_RIGHTS(item, rights)
Definition: acl.h:79
#define ARR_DIMS(a)
Definition: array.h:287
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

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

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

◆ aclupdate()

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

Definition at line 916 of file acl.c.

918 {
919  Acl *new_acl = NULL;
920  AclItem *old_aip,
921  *new_aip = NULL;
922  AclMode old_rights,
923  old_goptions,
924  new_rights,
925  new_goptions;
926  int dst,
927  num;
928 
929  /* Caller probably already checked old_acl, but be safe */
930  check_acl(old_acl);
931 
932  /* If granting grant options, check for circularity */
933  if (modechg != ACL_MODECHG_DEL &&
934  ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS)
935  check_circularity(old_acl, mod_aip, ownerId);
936 
937  num = ACL_NUM(old_acl);
938  old_aip = ACL_DAT(old_acl);
939 
940  /*
941  * Search the ACL for an existing entry for this grantee and grantor. If
942  * one exists, just modify the entry in-place (well, in the same position,
943  * since we actually return a copy); otherwise, insert the new entry at
944  * the end.
945  */
946 
947  for (dst = 0; dst < num; ++dst)
948  {
949  if (aclitem_match(mod_aip, old_aip + dst))
950  {
951  /* found a match, so modify existing item */
952  new_acl = allocacl(num);
953  new_aip = ACL_DAT(new_acl);
954  memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
955  break;
956  }
957  }
958 
959  if (dst == num)
960  {
961  /* need to append a new item */
962  new_acl = allocacl(num + 1);
963  new_aip = ACL_DAT(new_acl);
964  memcpy(new_aip, old_aip, num * sizeof(AclItem));
965 
966  /* initialize the new entry with no permissions */
967  new_aip[dst].ai_grantee = mod_aip->ai_grantee;
968  new_aip[dst].ai_grantor = mod_aip->ai_grantor;
969  ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
971  num++; /* set num to the size of new_acl */
972  }
973 
974  old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
975  old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
976 
977  /* apply the specified permissions change */
978  switch (modechg)
979  {
980  case ACL_MODECHG_ADD:
981  ACLITEM_SET_RIGHTS(new_aip[dst],
982  old_rights | ACLITEM_GET_RIGHTS(*mod_aip));
983  break;
984  case ACL_MODECHG_DEL:
985  ACLITEM_SET_RIGHTS(new_aip[dst],
986  old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
987  break;
988  case ACL_MODECHG_EQL:
989  ACLITEM_SET_RIGHTS(new_aip[dst],
990  ACLITEM_GET_RIGHTS(*mod_aip));
991  break;
992  }
993 
994  new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
995  new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
996 
997  /*
998  * If the adjusted entry has no permissions, delete it from the list.
999  */
1000  if (new_rights == ACL_NO_RIGHTS)
1001  {
1002  memmove(new_aip + dst,
1003  new_aip + dst + 1,
1004  (num - dst - 1) * sizeof(AclItem));
1005  /* Adjust array size to be 'num - 1' items */
1006  ARR_DIMS(new_acl)[0] = num - 1;
1007  SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1008  }
1009 
1010  /*
1011  * Remove abandoned privileges (cascading revoke). Currently we can only
1012  * handle this when the grantee is not PUBLIC.
1013  */
1014  if ((old_goptions & ~new_goptions) != 0)
1015  {
1016  Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1017  new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1018  (old_goptions & ~new_goptions),
1019  ownerId, behavior);
1020  }
1021 
1022  return new_acl;
1023 }
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition: acl.c:1220
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1140
#define ACL_SIZE(ACL)
Definition: acl.h:111
#define ACL_MODECHG_DEL
Definition: acl.h:130
#define ACLITEM_GET_GOPTIONS(item)
Definition: acl.h:67
#define ACL_MODECHG_EQL
Definition: acl.h:131
Assert(fmt[strlen(fmt) - 1] !='\n')

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

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

◆ check_is_member_of_role()

void check_is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4893 of file acl.c.

4894 {
4895  if (!is_member_of_role(member, role))
4896  ereport(ERROR,
4897  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4898  errmsg("must be member of role \"%s\"",
4899  GetUserNameFromId(role, false))));
4900 }
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4869
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:910

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

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

◆ check_rolespec_name()

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

Definition at line 5235 of file acl.c.

5236 {
5237  if (!role)
5238  return;
5239 
5240  if (role->roletype != ROLESPEC_CSTRING)
5241  return;
5242 
5243  if (IsReservedName(role->rolename))
5244  {
5245  if (detail_msg)
5246  ereport(ERROR,
5247  (errcode(ERRCODE_RESERVED_NAME),
5248  errmsg("role name \"%s\" is reserved",
5249  role->rolename),
5250  errdetail("%s", detail_msg)));
5251  else
5252  ereport(ERROR,
5253  (errcode(ERRCODE_RESERVED_NAME),
5254  errmsg("role name \"%s\" is reserved",
5255  role->rolename)));
5256  }
5257 }
bool IsReservedName(const char *name)
Definition: catalog.c:218
int errdetail(const char *fmt,...)
Definition: elog.c:1037
@ ROLESPEC_CSTRING
Definition: parsenodes.h:341
RoleSpecType roletype
Definition: parsenodes.h:351
char * rolename
Definition: parsenodes.h:352

References ereport, errcode(), errdetail(), 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 905 of file aclchk.c.

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

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, AlterDefaultPrivilegesStmt::action, InternalDefaultACL::all_privs, DefElem::arg, InternalDefaultACL::behavior, check_is_member_of_role(), AccessPriv::cols, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, errorConflictingDefElem(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalDefaultACL::grant_option, InternalDefaultACL::grantees, if(), InternalDefaultACL::is_grant, lappend_oid(), lfirst, NIL, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, InternalDefaultACL::objtype, AlterDefaultPrivilegesStmt::options, AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, InternalDefaultACL::roleid, ROLESPEC_PUBLIC, RoleSpec::roletype, SetDefaultACLsInSchemas(), and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 360 of file aclchk.c.

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

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char *  rolename,
bool  missing_ok 
)

Definition at line 5094 of file acl.c.

5095 {
5096  Oid oid;
5097 
5098  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5100  if (!OidIsValid(oid) && !missing_ok)
5101  ereport(ERROR,
5102  (errcode(ERRCODE_UNDEFINED_OBJECT),
5103  errmsg("role \"%s\" does not exist", rolname)));
5104  return oid;
5105 }
#define OidIsValid(objectId)
Definition: c.h:710
NameData rolname
Definition: pg_authid.h:34
#define CStringGetDatum(X)
Definition: postgres.h:622
@ AUTHNAME
Definition: syscache.h:44
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:195

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

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

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5213 of file acl.c.

5214 {
5215  HeapTuple tp;
5216  Form_pg_authid authForm;
5217  char *rolename;
5218 
5219  tp = get_rolespec_tuple(role);
5220  authForm = (Form_pg_authid) GETSTRUCT(tp);
5221  rolename = pstrdup(NameStr(authForm->rolname));
5222  ReleaseSysCache(tp);
5223 
5224  return rolename;
5225 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5167
#define NameStr(name)
Definition: c.h:681
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
char * pstrdup(const char *in)
Definition: mcxt.c:1299
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1198

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

5129 {
5130  Oid oid;
5131 
5132  switch (role->roletype)
5133  {
5134  case ROLESPEC_CSTRING:
5135  Assert(role->rolename);
5136  oid = get_role_oid(role->rolename, missing_ok);
5137  break;
5138 
5139  case ROLESPEC_CURRENT_ROLE:
5140  case ROLESPEC_CURRENT_USER:
5141  oid = GetUserId();
5142  break;
5143 
5144  case ROLESPEC_SESSION_USER:
5145  oid = GetSessionUserId();
5146  break;
5147 
5148  case ROLESPEC_PUBLIC:
5149  ereport(ERROR,
5150  (errcode(ERRCODE_UNDEFINED_OBJECT),
5151  errmsg("role \"%s\" does not exist", "public")));
5152  oid = InvalidOid; /* make compiler happy */
5153  break;
5154 
5155  default:
5156  elog(ERROR, "unexpected role type %d", role->roletype);
5157  }
5158 
5159  return oid;
5160 }
Oid GetSessionUserId(void)
Definition: miscinit.c:529
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:343
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:344
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:342
#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 5167 of file acl.c.

5168 {
5169  HeapTuple tuple;
5170 
5171  switch (role->roletype)
5172  {
5173  case ROLESPEC_CSTRING:
5174  Assert(role->rolename);
5176  if (!HeapTupleIsValid(tuple))
5177  ereport(ERROR,
5178  (errcode(ERRCODE_UNDEFINED_OBJECT),
5179  errmsg("role \"%s\" does not exist", role->rolename)));
5180  break;
5181 
5182  case ROLESPEC_CURRENT_ROLE:
5183  case ROLESPEC_CURRENT_USER:
5184  tuple = SearchSysCache1(AUTHOID, GetUserId());
5185  if (!HeapTupleIsValid(tuple))
5186  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5187  break;
5188 
5189  case ROLESPEC_SESSION_USER:
5191  if (!HeapTupleIsValid(tuple))
5192  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5193  break;
5194 
5195  case ROLESPEC_PUBLIC:
5196  ereport(ERROR,
5197  (errcode(ERRCODE_UNDEFINED_OBJECT),
5198  errmsg("role \"%s\" does not exist", "public")));
5199  tuple = NULL; /* make compiler happy */
5200  break;
5201 
5202  default:
5203  elog(ERROR, "unexpected role type %d", role->roletype);
5204  }
5205 
5206  return tuple;
5207 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1150
@ AUTHOID
Definition: syscache.h:45

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

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

◆ get_user_default_acl()

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

Definition at line 5523 of file aclchk.c.

5524 {
5525  Acl *result;
5526  Acl *glob_acl;
5527  Acl *schema_acl;
5528  Acl *def_acl;
5529  char defaclobjtype;
5530 
5531  /*
5532  * Use NULL during bootstrap, since pg_default_acl probably isn't there
5533  * yet.
5534  */
5536  return NULL;
5537 
5538  /* Check if object type is supported in pg_default_acl */
5539  switch (objtype)
5540  {
5541  case OBJECT_TABLE:
5542  defaclobjtype = DEFACLOBJ_RELATION;
5543  break;
5544 
5545  case OBJECT_SEQUENCE:
5546  defaclobjtype = DEFACLOBJ_SEQUENCE;
5547  break;
5548 
5549  case OBJECT_FUNCTION:
5550  defaclobjtype = DEFACLOBJ_FUNCTION;
5551  break;
5552 
5553  case OBJECT_TYPE:
5554  defaclobjtype = DEFACLOBJ_TYPE;
5555  break;
5556 
5557  case OBJECT_SCHEMA:
5558  defaclobjtype = DEFACLOBJ_NAMESPACE;
5559  break;
5560 
5561  default:
5562  return NULL;
5563  }
5564 
5565  /* Look up the relevant pg_default_acl entries */
5566  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5567  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5568 
5569  /* Quick out if neither entry exists */
5570  if (glob_acl == NULL && schema_acl == NULL)
5571  return NULL;
5572 
5573  /* We need to know the hard-wired default value, too */
5574  def_acl = acldefault(objtype, ownerId);
5575 
5576  /* If there's no global entry, substitute the hard-wired default */
5577  if (glob_acl == NULL)
5578  glob_acl = def_acl;
5579 
5580  /* Merge in any per-schema privileges */
5581  result = aclmerge(glob_acl, schema_acl, ownerId);
5582 
5583  /*
5584  * For efficiency, we want to return NULL if the result equals default.
5585  * This requires sorting both arrays to get an accurate comparison.
5586  */
5587  aclitemsort(result);
5588  aclitemsort(def_acl);
5589  if (aclequal(result, def_acl))
5590  result = NULL;
5591 
5592  return result;
5593 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:495
void aclitemsort(Acl *acl)
Definition: acl.c:481
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:734
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:437
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:5488
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406

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

5465 {
5466  bool result = false;
5467  HeapTuple utup;
5468 
5469  /* Superusers bypass all permission checking. */
5470  if (superuser_arg(roleid))
5471  return true;
5472 
5473  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5474  if (HeapTupleIsValid(utup))
5475  {
5476  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
5477  ReleaseSysCache(utup);
5478  }
5479  return result;
5480 }
bool rolbypassrls
Definition: pg_authid.h:41
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

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

Referenced by check_enable_rls(), and RI_Initial_Check().

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 5445 of file aclchk.c.

5446 {
5447  bool result = false;
5448  HeapTuple utup;
5449 
5450  /* Superusers bypass all permission checking. */
5451  if (superuser_arg(roleid))
5452  return true;
5453 
5454  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5455  if (HeapTupleIsValid(utup))
5456  {
5457  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
5458  ReleaseSysCache(utup);
5459  }
5460  return result;
5461 }
bool rolcreaterole
Definition: pg_authid.h:37

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

Referenced by check_object_ownership(), and have_createrole_privilege().

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4843 of file acl.c.

4844 {
4845  /* Fast path for simple case */
4846  if (member == role)
4847  return true;
4848 
4849  /* Superusers have every privilege, so are part of every role */
4850  if (superuser_arg(member))
4851  return true;
4852 
4853  /*
4854  * Find all the roles that member has the privileges of, including
4855  * multi-level recursion, then see if target role is any one of them.
4856  */
4858  InvalidOid, NULL),
4859  role);
4860 }
@ ROLERECURSE_PRIVS
Definition: acl.c:67
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, bool *is_admin)
Definition: acl.c:4726
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:701

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

Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), check_role_for_policy(), DropOwnedObjects(), pg_class_aclmask_ext(), pg_class_ownercheck(), pg_collation_ownercheck(), pg_conversion_ownercheck(), pg_database_ownercheck(), pg_event_trigger_ownercheck(), pg_extension_ownercheck(), pg_foreign_data_wrapper_ownercheck(), pg_foreign_server_ownercheck(), pg_language_ownercheck(), pg_largeobject_ownercheck(), pg_namespace_aclmask(), pg_namespace_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_publication_ownercheck(), pg_role_aclcheck(), pg_signal_backend(), pg_statistics_object_ownercheck(), pg_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), ReassignOwnedObjects(), standard_ProcessUtility(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4648 of file acl.c.

4649 {
4651  {
4652  cached_db_hash =
4655 
4656  /*
4657  * In normal mode, set a callback on any syscache invalidation of rows
4658  * of pg_auth_members (for roles_is_member_of()), pg_authid (for
4659  * has_rolinherit()), or pg_database (for roles_is_member_of())
4660  */
4663  (Datum) 0);
4666  (Datum) 0);
4669  (Datum) 0);
4670  }
4671 }
static uint32 cached_db_hash
Definition: acl.c:72
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4678
Oid MyDatabaseId
Definition: globals.c:88
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1518
uintptr_t Datum
Definition: postgres.h:411
@ AUTHMEMROLEMEM
Definition: syscache.h:43
@ DATABASEOID
Definition: syscache.h:55
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:204

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 4931 of file acl.c.

4932 {
4933  bool result = false;
4934 
4935  if (superuser_arg(member))
4936  return true;
4937 
4938  if (member == role)
4939 
4940  /*
4941  * A role can admin itself when it matches the session user and we're
4942  * outside any security-restricted operation, SECURITY DEFINER or
4943  * similar context. SQL-standard roles cannot self-admin. However,
4944  * SQL-standard users are distinct from roles, and they are not
4945  * grantable like roles: PostgreSQL's role-user duality extends the
4946  * standard. Checking for a session user match has the effect of
4947  * letting a role self-admin only when it's conspicuously behaving
4948  * like a user. Note that allowing self-admin under a mere SET ROLE
4949  * would make WITH ADMIN OPTION largely irrelevant; any member could
4950  * SET ROLE to issue the otherwise-forbidden command.
4951  *
4952  * Withholding self-admin in a security-restricted operation prevents
4953  * object owners from harnessing the session user identity during
4954  * administrative maintenance. Suppose Alice owns a database, has
4955  * issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
4956  * an alice-owned SECURITY DEFINER function that issues "REVOKE alice
4957  * FROM carol". If he creates an expression index calling that
4958  * function, Alice will attempt the REVOKE during each ANALYZE.
4959  * Checking InSecurityRestrictedOperation() thwarts that attack.
4960  *
4961  * Withholding self-admin in SECURITY DEFINER functions makes their
4962  * behavior independent of the calling user. There's no security or
4963  * SQL-standard-conformance need for that restriction, though.
4964  *
4965  * A role cannot have actual WITH ADMIN OPTION on itself, because that
4966  * would imply a membership loop. Therefore, we're done either way.
4967  */
4968  return member == GetSessionUserId() &&
4970 
4971  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &result);
4972  return result;
4973 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:68
bool InSecurityRestrictedOperation(void)
Definition: miscinit.c:627
bool InLocalUserIdChange(void)
Definition: miscinit.c:618

References GetSessionUserId(), InLocalUserIdChange(), InSecurityRestrictedOperation(), ROLERECURSE_MEMBERS, roles_is_member_of(), and superuser_arg().

Referenced by AddRoleMems(), DelRoleMems(), and pg_role_aclcheck().

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4869 of file acl.c.

4870 {
4871  /* Fast path for simple case */
4872  if (member == role)
4873  return true;
4874 
4875  /* Superusers have every privilege, so are part of every role */
4876  if (superuser_arg(member))
4877  return true;
4878 
4879  /*
4880  * Find all the roles that member is a member of, including multi-level
4881  * recursion, then see if target role is any one of them.
4882  */
4884  InvalidOid, NULL),
4885  role);
4886 }

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

Referenced by calculate_database_size(), calculate_tablespace_size(), check_is_member_of_role(), check_role(), convert_and_check_filename(), DoCopy(), file_fdw_validator(), get_explain_guc_options(), GetConfigOption(), GetConfigOptionByName(), GetConfigOptionByNum(), GetConfigOptionResetString(), pg_role_aclcheck(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), and ShowAllGUCConfig().

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)

Definition at line 4909 of file acl.c.

4910 {
4911  /* Fast path for simple case */
4912  if (member == role)
4913  return true;
4914 
4915  /*
4916  * Find all the roles that member is a member of, including multi-level
4917  * recursion, then see if target role is any one of them.
4918  */
4920  InvalidOid, NULL),
4921  role);
4922 }

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

385 {
386  return allocacl(0);
387 }

References allocacl().

Referenced by SetDefaultACL().

◆ pg_attribute_aclcheck()

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

Definition at line 4553 of file aclchk.c.

4555 {
4556  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
4557 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:4567
int16 attnum
Definition: pg_attribute.h:83
static PgChecksumMode mode
Definition: pg_checksums.c:65

References attnum, mode, and pg_attribute_aclcheck_ext().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), examine_simple_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckRTEPerms(), ExecCheckRTEPermsModified(), 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 4597 of file aclchk.c.

4599 {
4600  AclResult result;
4601  HeapTuple classTuple;
4602  Form_pg_class classForm;
4603  AttrNumber nattrs;
4604  AttrNumber curr_att;
4605 
4606  /*
4607  * Must fetch pg_class row to check number of attributes. As in
4608  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4609  * throwing an error if we get any unexpected lookup errors.
4610  */
4611  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4612  if (!HeapTupleIsValid(classTuple))
4613  return ACLCHECK_NO_PRIV;
4614  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4615 
4616  nattrs = classForm->relnatts;
4617 
4618  ReleaseSysCache(classTuple);
4619 
4620  /*
4621  * Initialize result in case there are no non-dropped columns. We want to
4622  * report failure in such cases for either value of 'how'.
4623  */
4624  result = ACLCHECK_NO_PRIV;
4625 
4626  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4627  {
4628  HeapTuple attTuple;
4629  AclMode attmask;
4630 
4631  attTuple = SearchSysCache2(ATTNUM,
4632  ObjectIdGetDatum(table_oid),
4633  Int16GetDatum(curr_att));
4634  if (!HeapTupleIsValid(attTuple))
4635  continue;
4636 
4637  /* ignore dropped columns */
4638  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4639  {
4640  ReleaseSysCache(attTuple);
4641  continue;
4642  }
4643 
4644  /*
4645  * Here we hard-wire knowledge that the default ACL for a column
4646  * grants no privileges, so that we can fall out quickly in the very
4647  * common case where attacl is null.
4648  */
4649  if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
4650  attmask = 0;
4651  else
4652  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4653  mode, ACLMASK_ANY);
4654 
4655  ReleaseSysCache(attTuple);
4656 
4657  if (attmask != 0)
4658  {
4659  result = ACLCHECK_OK;
4660  if (how == ACLMASK_ANY)
4661  break; /* succeed on any success */
4662  }
4663  else
4664  {
4665  result = ACLCHECK_NO_PRIV;
4666  if (how == ACLMASK_ALL)
4667  break; /* fail on any failure */
4668  }
4669  }
4670 
4671  return result;
4672 }
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3703
int16 AttrNumber
Definition: attnum.h:21
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define Int16GetDatum(X)
Definition: postgres.h:495
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1161
@ ATTNUM
Definition: syscache.h:41
@ RELOID
Definition: syscache.h:87

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

Referenced by ExecCheckRTEPerms(), ExecCheckRTEPermsModified(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), and statext_is_compatible_clause().

◆ pg_attribute_aclcheck_ext()

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

Definition at line 4567 of file aclchk.c.

4569 {
4570  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
4571  ACLMASK_ANY, is_missing) != 0)
4572  return ACLCHECK_OK;
4573  else
4574  return ACLCHECK_NO_PRIV;
4575 }
AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3717

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

AclMode pg_attribute_aclmask ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3703 of file aclchk.c.

3705 {
3706  return pg_attribute_aclmask_ext(table_oid, attnum, roleid,
3707  mask, how, NULL);
3708 }

References attnum, and pg_attribute_aclmask_ext().

Referenced by pg_aclmask(), and pg_attribute_aclcheck_all().

◆ pg_attribute_aclmask_ext()

AclMode pg_attribute_aclmask_ext ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)

Definition at line 3717 of file aclchk.c.

3719 {
3720  AclMode result;
3721  HeapTuple classTuple;
3722  HeapTuple attTuple;
3723  Form_pg_class classForm;
3724  Form_pg_attribute attributeForm;
3725  Datum aclDatum;
3726  bool isNull;
3727  Acl *acl;
3728  Oid ownerId;
3729 
3730  /*
3731  * First, get the column's ACL from its pg_attribute entry
3732  */
3733  attTuple = SearchSysCache2(ATTNUM,
3734  ObjectIdGetDatum(table_oid),
3736  if (!HeapTupleIsValid(attTuple))
3737  {
3738  if (is_missing != NULL)
3739  {
3740  /* return "no privileges" instead of throwing an error */
3741  *is_missing = true;
3742  return 0;
3743  }
3744  else
3745  ereport(ERROR,
3746  (errcode(ERRCODE_UNDEFINED_COLUMN),
3747  errmsg("attribute %d of relation with OID %u does not exist",
3748  attnum, table_oid)));
3749  }
3750 
3751  attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
3752 
3753  /* Check dropped columns, too */
3754  if (attributeForm->attisdropped)
3755  {
3756  if (is_missing != NULL)
3757  {
3758  /* return "no privileges" instead of throwing an error */
3759  *is_missing = true;
3760  ReleaseSysCache(attTuple);
3761  return 0;
3762  }
3763  else
3764  ereport(ERROR,
3765  (errcode(ERRCODE_UNDEFINED_COLUMN),
3766  errmsg("attribute %d of relation with OID %u does not exist",
3767  attnum, table_oid)));
3768  }
3769 
3770  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3771  &isNull);
3772 
3773  /*
3774  * Here we hard-wire knowledge that the default ACL for a column grants no
3775  * privileges, so that we can fall out quickly in the very common case
3776  * where attacl is null.
3777  */
3778  if (isNull)
3779  {
3780  ReleaseSysCache(attTuple);
3781  return 0;
3782  }
3783 
3784  /*
3785  * Must get the relation's ownerId from pg_class. Since we already found
3786  * a pg_attribute entry, the only likely reason for this to fail is that a
3787  * concurrent DROP of the relation committed since then (which could only
3788  * happen if we don't have lock on the relation). We prefer to report "no
3789  * privileges" rather than failing in such a case, so as to avoid unwanted
3790  * failures in has_column_privilege() tests.
3791  */
3792  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3793  if (!HeapTupleIsValid(classTuple))
3794  {
3795  ReleaseSysCache(attTuple);
3796  return 0;
3797  }
3798  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3799 
3800  ownerId = classForm->relowner;
3801 
3802  ReleaseSysCache(classTuple);
3803 
3804  /* detoast column's ACL if necessary */
3805  acl = DatumGetAclP(aclDatum);
3806 
3807  result = aclmask(acl, roleid, ownerId, mask, how);
3808 
3809  /* if we have a detoasted copy, free it */
3810  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3811  pfree(acl);
3812 
3813  ReleaseSysCache(attTuple);
3814 
3815  return result;
3816 }
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1306
#define DatumGetAclP(X)
Definition: acl.h:120
char * Pointer
Definition: c.h:418
#define DatumGetPointer(X)
Definition: postgres.h:593
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1411

References aclmask(), attnum, ATTNUM, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, Int16GetDatum, ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELOID, SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttr().

Referenced by pg_attribute_aclcheck_ext(), and pg_attribute_aclmask().

◆ pg_class_aclcheck()

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

◆ pg_class_aclcheck_ext()

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

Definition at line 4694 of file aclchk.c.

4696 {
4697  if (pg_class_aclmask_ext(table_oid, roleid, mode,
4698  ACLMASK_ANY, is_missing) != 0)
4699  return ACLCHECK_OK;
4700  else
4701  return ACLCHECK_NO_PRIV;
4702 }
AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3835

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

Referenced by column_privilege_check(), and pg_class_aclcheck().

◆ pg_class_aclmask()

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

Definition at line 3822 of file aclchk.c.

3824 {
3825  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3826 }

References pg_class_aclmask_ext().

Referenced by ExecCheckRTEPerms(), and pg_aclmask().

◆ pg_class_aclmask_ext()

AclMode pg_class_aclmask_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)

Definition at line 3835 of file aclchk.c.

3837 {
3838  AclMode result;
3839  HeapTuple tuple;
3840  Form_pg_class classForm;
3841  Datum aclDatum;
3842  bool isNull;
3843  Acl *acl;
3844  Oid ownerId;
3845 
3846  /*
3847  * Must get the relation's tuple from pg_class
3848  */
3849  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3850  if (!HeapTupleIsValid(tuple))
3851  {
3852  if (is_missing != NULL)
3853  {
3854  /* return "no privileges" instead of throwing an error */
3855  *is_missing = true;
3856  return 0;
3857  }
3858  else
3859  ereport(ERROR,
3861  errmsg("relation with OID %u does not exist",
3862  table_oid)));
3863  }
3864 
3865  classForm = (Form_pg_class) GETSTRUCT(tuple);
3866 
3867  /*
3868  * Deny anyone permission to update a system catalog unless
3869  * pg_authid.rolsuper is set.
3870  *
3871  * As of 7.4 we have some updatable system views; those shouldn't be
3872  * protected in this way. Assume the view rules can take care of
3873  * themselves. ACL_USAGE is if we ever have system sequences.
3874  */
3875  if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3876  IsSystemClass(table_oid, classForm) &&
3877  classForm->relkind != RELKIND_VIEW &&
3878  !superuser_arg(roleid))
3880 
3881  /*
3882  * Otherwise, superusers bypass all permission-checking.
3883  */
3884  if (superuser_arg(roleid))
3885  {
3886  ReleaseSysCache(tuple);
3887  return mask;
3888  }
3889 
3890  /*
3891  * Normal case: get the relation's ACL from pg_class
3892  */
3893  ownerId = classForm->relowner;
3894 
3895  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
3896  &isNull);
3897  if (isNull)
3898  {
3899  /* No ACL, so build default ACL */
3900  switch (classForm->relkind)
3901  {
3902  case RELKIND_SEQUENCE:
3903  acl = acldefault(OBJECT_SEQUENCE, ownerId);
3904  break;
3905  default:
3906  acl = acldefault(OBJECT_TABLE, ownerId);
3907  break;
3908  }
3909  aclDatum = (Datum) 0;
3910  }
3911  else
3912  {
3913  /* detoast rel's ACL if necessary */
3914  acl = DatumGetAclP(aclDatum);
3915  }
3916 
3917  result = aclmask(acl, roleid, ownerId, mask, how);
3918 
3919  /* if we have a detoasted copy, free it */
3920  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3921  pfree(acl);
3922 
3923  ReleaseSysCache(tuple);
3924 
3925  /*
3926  * Check if ACL_SELECT is being checked and, if so, and not set already as
3927  * part of the result, then check if the user is a member of the
3928  * pg_read_all_data role, which allows read access to all relations.
3929  */
3930  if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3931  has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA))
3932  result |= ACL_SELECT;
3933 
3934  /*
3935  * Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if
3936  * so, and not set already as part of the result, then check if the user
3937  * is a member of the pg_write_all_data role, which allows
3938  * INSERT/UPDATE/DELETE access to all relations (except system catalogs,
3939  * which requires superuser, see above).
3940  */
3941  if (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE) &&
3942  !(result & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
3943  has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA))
3944  result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
3945 
3946  return result;
3947 }
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition: catalog.c:86
#define ACL_DELETE
Definition: parsenodes.h:85
#define ACL_INSERT
Definition: parsenodes.h:82
#define ACL_UPDATE
Definition: parsenodes.h:84
#define ACL_SELECT
Definition: parsenodes.h:83
#define ACL_TRUNCATE
Definition: parsenodes.h:86
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:79

References ACL_DELETE, ACL_INSERT, ACL_SELECT, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, IsSystemClass(), OBJECT_SEQUENCE, OBJECT_TABLE, ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELOID, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_class_aclcheck_ext(), and pg_class_aclmask().

◆ pg_class_ownercheck()

bool pg_class_ownercheck ( Oid  class_oid,
Oid  roleid 
)

Definition at line 4820 of file aclchk.c.

4821 {
4822  HeapTuple tuple;
4823  Oid ownerId;
4824 
4825  /* Superusers bypass all permission checking. */
4826  if (superuser_arg(roleid))
4827  return true;
4828 
4829  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
4830  if (!HeapTupleIsValid(tuple))
4831  ereport(ERROR,
4833  errmsg("relation with OID %u does not exist", class_oid)));
4834 
4835  ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
4836 
4837  ReleaseSysCache(tuple);
4838 
4839  return has_privs_of_role(roleid, ownerId);
4840 }

References ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RELOID, SearchSysCache1(), and superuser_arg().

Referenced by AlterTableMoveAll(), ATExecChangeOwner(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), cluster_rel(), CreateStatistics(), DefineQueryRewrite(), EnableDisableRule(), ExecuteTruncateGuts(), get_tables_to_cluster(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), renameatt_check(), RI_Initial_Check(), and vacuum_is_relation_owner().

◆ pg_collation_ownercheck()

bool pg_collation_ownercheck ( Oid  coll_oid,
Oid  roleid 
)

Definition at line 5264 of file aclchk.c.

5265 {
5266  HeapTuple tuple;
5267  Oid ownerId;
5268 
5269  /* Superusers bypass all permission checking. */
5270  if (superuser_arg(roleid))
5271  return true;
5272 
5273  tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid));
5274  if (!HeapTupleIsValid(tuple))
5275  ereport(ERROR,
5276  (errcode(ERRCODE_UNDEFINED_OBJECT),
5277  errmsg("collation with OID %u does not exist", coll_oid)));
5278 
5279  ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner;
5280 
5281  ReleaseSysCache(tuple);
5282 
5283  return has_privs_of_role(roleid, ownerId);
5284 }
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:56
@ COLLOID
Definition: syscache.h:50

References COLLOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterCollation(), and check_object_ownership().

◆ pg_conversion_ownercheck()

bool pg_conversion_ownercheck ( Oid  conv_oid,
Oid  roleid 
)

Definition at line 5290 of file aclchk.c.

5291 {
5292  HeapTuple tuple;
5293  Oid ownerId;
5294 
5295  /* Superusers bypass all permission checking. */
5296  if (superuser_arg(roleid))
5297  return true;
5298 
5299  tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid));
5300  if (!HeapTupleIsValid(tuple))
5301  ereport(ERROR,
5302  (errcode(ERRCODE_UNDEFINED_OBJECT),
5303  errmsg("conversion with OID %u does not exist", conv_oid)));
5304 
5305  ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
5306 
5307  ReleaseSysCache(tuple);
5308 
5309  return has_privs_of_role(roleid, ownerId);
5310 }
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
@ CONVOID
Definition: syscache.h:54

References CONVOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership().

◆ pg_database_aclcheck()

◆ pg_database_aclmask()

AclMode pg_database_aclmask ( Oid  db_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3953 of file aclchk.c.

3955 {
3956  AclMode result;
3957  HeapTuple tuple;
3958  Datum aclDatum;
3959  bool isNull;
3960  Acl *acl;
3961  Oid ownerId;
3962 
3963  /* Superusers bypass all permission checking. */
3964  if (superuser_arg(roleid))
3965  return mask;
3966 
3967  /*
3968  * Get the database's ACL from pg_database
3969  */
3970  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
3971  if (!HeapTupleIsValid(tuple))
3972  ereport(ERROR,
3973  (errcode(ERRCODE_UNDEFINED_DATABASE),
3974  errmsg("database with OID %u does not exist", db_oid)));
3975 
3976  ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
3977 
3978  aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
3979  &isNull);
3980  if (isNull)
3981  {
3982  /* No ACL, so build default ACL */
3983  acl = acldefault(OBJECT_DATABASE, ownerId);
3984  aclDatum = (Datum) 0;
3985  }
3986  else
3987  {
3988  /* detoast ACL if necessary */
3989  acl = DatumGetAclP(aclDatum);
3990  }
3991 
3992  result = aclmask(acl, roleid, ownerId, mask, how);
3993 
3994  /* if we have a detoasted copy, free it */
3995  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3996  pfree(acl);
3997 
3998  ReleaseSysCache(tuple);
3999 
4000  return result;
4001 }
FormData_pg_database * Form_pg_database
Definition: pg_database.h:81

References acldefault(), aclmask(), DATABASEOID, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, OBJECT_DATABASE, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_database_aclcheck().

◆ pg_database_ownercheck()

bool pg_database_ownercheck ( Oid  db_oid,
Oid  roleid 
)

Definition at line 5238 of file aclchk.c.

5239 {
5240  HeapTuple tuple;
5241  Oid dba;
5242 
5243  /* Superusers bypass all permission checking. */
5244  if (superuser_arg(roleid))
5245  return true;
5246 
5247  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
5248  if (!HeapTupleIsValid(tuple))
5249  ereport(ERROR,
5250  (errcode(ERRCODE_UNDEFINED_DATABASE),
5251  errmsg("database with OID %u does not exist", db_oid)));
5252 
5253  dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
5254 
5255  ReleaseSysCache(tuple);
5256 
5257  return has_privs_of_role(roleid, dba);
5258 }

References DATABASEOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseSet(), AlterRoleSet(), check_object_ownership(), createdb(), dropdb(), movedb(), ReindexMultipleTables(), RenameDatabase(), and vacuum_is_relation_owner().

◆ pg_event_trigger_ownercheck()

bool pg_event_trigger_ownercheck ( Oid  et_oid,
Oid  roleid 
)

Definition at line 5211 of file aclchk.c.

5212 {
5213  HeapTuple tuple;
5214  Oid ownerId;
5215 
5216  /* Superusers bypass all permission checking. */
5217  if (superuser_arg(roleid))
5218  return true;
5219 
5221  if (!HeapTupleIsValid(tuple))
5222  ereport(ERROR,
5223  (errcode(ERRCODE_UNDEFINED_OBJECT),
5224  errmsg("event trigger with OID %u does not exist",
5225  et_oid)));
5226 
5227  ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner;
5228 
5229  ReleaseSysCache(tuple);
5230 
5231  return has_privs_of_role(roleid, ownerId);
5232 }
FormData_pg_event_trigger * Form_pg_event_trigger
@ EVENTTRIGGEROID
Definition: syscache.h:60

References ereport, errcode(), errmsg(), ERROR, EVENTTRIGGEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterEventTrigger(), AlterEventTriggerOwner_internal(), and check_object_ownership().

◆ pg_extension_ownercheck()

bool pg_extension_ownercheck ( Oid  ext_oid,
Oid  roleid 
)

Definition at line 5316 of file aclchk.c.

5317 {
5318  Relation pg_extension;
5319  ScanKeyData entry[1];
5320  SysScanDesc scan;
5321  HeapTuple tuple;
5322  Oid ownerId;
5323 
5324  /* Superusers bypass all permission checking. */
5325  if (superuser_arg(roleid))
5326  return true;
5327 
5328  /* There's no syscache for pg_extension, so do it the hard way */
5329  pg_extension = table_open(ExtensionRelationId, AccessShareLock);
5330 
5331  ScanKeyInit(&entry[0],
5332  Anum_pg_extension_oid,
5333  BTEqualStrategyNumber, F_OIDEQ,
5334  ObjectIdGetDatum(ext_oid));
5335 
5336  scan = systable_beginscan(pg_extension,
5337  ExtensionOidIndexId, true,
5338  NULL, 1, entry);
5339 
5340  tuple = systable_getnext(scan);
5341  if (!HeapTupleIsValid(tuple))
5342  ereport(ERROR,
5343  (errcode(ERRCODE_UNDEFINED_OBJECT),
5344  errmsg("extension with OID %u does not exist", ext_oid)));
5345 
5346  ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner;
5347 
5348  systable_endscan(scan);
5349  table_close(pg_extension, AccessShareLock);
5350 
5351  return has_privs_of_role(roleid, ownerId);
5352 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:598
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:505
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:386
#define AccessShareLock
Definition: lockdefs.h:36
FormData_pg_extension * Form_pg_extension
Definition: pg_extension.h:52
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterExtensionNamespace(), check_object_ownership(), ExecAlterExtensionContentsStmt(), and ExecAlterExtensionStmt().

◆ pg_foreign_data_wrapper_aclcheck()

AclResult pg_foreign_data_wrapper_aclcheck ( Oid  fdw_oid,
Oid  roleid,
AclMode  mode 
)

◆ pg_foreign_data_wrapper_aclmask()

AclMode pg_foreign_data_wrapper_aclmask ( Oid  fdw_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4346 of file aclchk.c.

4348 {
4349  AclMode result;
4350  HeapTuple tuple;
4351  Datum aclDatum;
4352  bool isNull;
4353  Acl *acl;
4354  Oid ownerId;
4355 
4357 
4358  /* Bypass permission checks for superusers */
4359  if (superuser_arg(roleid))
4360  return mask;
4361 
4362  /*
4363  * Must get the FDW's tuple from pg_foreign_data_wrapper
4364  */
4366  if (!HeapTupleIsValid(tuple))
4367  ereport(ERROR,
4368  (errcode(ERRCODE_UNDEFINED_OBJECT),
4369  errmsg("foreign-data wrapper with OID %u does not exist",
4370  fdw_oid)));
4371  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
4372 
4373  /*
4374  * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
4375  */
4376  ownerId = fdwForm->fdwowner;
4377 
4378  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
4379  Anum_pg_foreign_data_wrapper_fdwacl, &isNull);
4380  if (isNull)
4381  {
4382  /* No ACL, so build default ACL */
4383  acl = acldefault(OBJECT_FDW, ownerId);
4384  aclDatum = (Datum) 0;
4385  }
4386  else
4387  {
4388  /* detoast rel's ACL if necessary */
4389  acl = DatumGetAclP(aclDatum);
4390  }
4391 
4392  result = aclmask(acl, roleid, ownerId, mask, how);
4393 
4394  /* if we have a detoasted copy, free it */
4395  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4396  pfree(acl);
4397 
4398  ReleaseSysCache(tuple);
4399 
4400  return result;
4401 }
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
@ FOREIGNDATAWRAPPEROID
Definition: syscache.h:62

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, GETSTRUCT, HeapTupleIsValid, OBJECT_FDW, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_foreign_data_wrapper_aclcheck().

◆ pg_foreign_data_wrapper_ownercheck()

bool pg_foreign_data_wrapper_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 5157 of file aclchk.c.

5158 {
5159  HeapTuple tuple;
5160  Oid ownerId;
5161 
5162  /* Superusers bypass all permission checking. */
5163  if (superuser_arg(roleid))
5164  return true;
5165 
5167  if (!HeapTupleIsValid(tuple))
5168  ereport(ERROR,
5169  (errcode(ERRCODE_UNDEFINED_OBJECT),
5170  errmsg("foreign-data wrapper with OID %u does not exist",
5171  srv_oid)));
5172 
5173  ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner;
5174 
5175  ReleaseSysCache(tuple);
5176 
5177  return has_privs_of_role(roleid, ownerId);
5178 }

References ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership().

◆ pg_foreign_server_aclcheck()

AclResult pg_foreign_server_aclcheck ( Oid  srv_oid,
Oid  roleid,
AclMode  mode 
)

◆ pg_foreign_server_aclmask()

AclMode pg_foreign_server_aclmask ( Oid  srv_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4408 of file aclchk.c.

4410 {
4411  AclMode result;
4412  HeapTuple tuple;
4413  Datum aclDatum;
4414  bool isNull;
4415  Acl *acl;
4416  Oid ownerId;
4417 
4418  Form_pg_foreign_server srvForm;
4419 
4420  /* Bypass permission checks for superusers */
4421  if (superuser_arg(roleid))
4422  return mask;
4423 
4424  /*
4425  * Must get the FDW's tuple from pg_foreign_data_wrapper
4426  */
4428  if (!HeapTupleIsValid(tuple))
4429  ereport(ERROR,
4430  (errcode(ERRCODE_UNDEFINED_OBJECT),
4431  errmsg("foreign server with OID %u does not exist",
4432  srv_oid)));
4433  srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
4434 
4435  /*
4436  * Normal case: get the foreign server's ACL from pg_foreign_server
4437  */
4438  ownerId = srvForm->srvowner;
4439 
4440  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
4441  Anum_pg_foreign_server_srvacl, &isNull);
4442  if (isNull)
4443  {
4444  /* No ACL, so build default ACL */
4445  acl = acldefault(OBJECT_FOREIGN_SERVER, ownerId);
4446  aclDatum = (Datum) 0;
4447  }
4448  else
4449  {
4450  /* detoast rel's ACL if necessary */
4451  acl = DatumGetAclP(aclDatum);
4452  }
4453 
4454  result = aclmask(acl, roleid, ownerId, mask, how);
4455 
4456  /* if we have a detoasted copy, free it */
4457  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4458  pfree(acl);
4459 
4460  ReleaseSysCache(tuple);
4461 
4462  return result;
4463 }
FormData_pg_foreign_server * Form_pg_foreign_server
@ FOREIGNSERVEROID
Definition: syscache.h:64

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, FOREIGNSERVEROID, GETSTRUCT, HeapTupleIsValid, OBJECT_FOREIGN_SERVER, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_foreign_server_aclcheck().

◆ pg_foreign_server_ownercheck()

bool pg_foreign_server_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 5184 of file aclchk.c.

5185 {
5186  HeapTuple tuple;
5187  Oid ownerId;
5188 
5189  /* Superusers bypass all permission checking. */
5190  if (superuser_arg(roleid))
5191  return true;
5192 
5194  if (!HeapTupleIsValid(tuple))
5195  ereport(ERROR,
5196  (errcode(ERRCODE_UNDEFINED_OBJECT),
5197  errmsg("foreign server with OID %u does not exist",
5198  srv_oid)));
5199 
5200  ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner;
5201 
5202  ReleaseSysCache(tuple);
5203 
5204  return has_privs_of_role(roleid, ownerId);
5205 }

References ereport, errcode(), errmsg(), ERROR, FOREIGNSERVEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterForeignServer(), AlterForeignServerOwner_internal(), check_object_ownership(), and user_mapping_ddl_aclcheck().

◆ pg_language_aclcheck()

AclResult pg_language_aclcheck ( Oid  lang_oid,
Oid  roleid,
AclMode  mode 
)

Definition at line 4732 of file aclchk.c.

4733 {
4734  if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
4735  return ACLCHECK_OK;
4736  else
4737  return ACLCHECK_NO_PRIV;
4738 }
AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:4061

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

Referenced by CheckFunctionValidatorAccess(), CreateFunction(), CreateTransform(), ExecuteDoStmt(), has_language_privilege_id(), has_language_privilege_id_id(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_id(), and has_language_privilege_name_name().

◆ pg_language_aclmask()

AclMode pg_language_aclmask ( Oid  lang_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4061 of file aclchk.c.

4063 {
4064  AclMode result;
4065  HeapTuple tuple;
4066  Datum aclDatum;
4067  bool isNull;
4068  Acl *acl;
4069  Oid ownerId;
4070 
4071  /* Superusers bypass all permission checking. */
4072  if (superuser_arg(roleid))
4073  return mask;
4074 
4075  /*
4076  * Get the language's ACL from pg_language
4077  */
4078  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
4079  if (!HeapTupleIsValid(tuple))
4080  ereport(ERROR,
4081  (errcode(ERRCODE_UNDEFINED_OBJECT),
4082  errmsg("language with OID %u does not exist", lang_oid)));
4083 
4084  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
4085 
4086  aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
4087  &isNull);
4088  if (isNull)
4089  {
4090  /* No ACL, so build default ACL */
4091  acl = acldefault(OBJECT_LANGUAGE, ownerId);
4092  aclDatum = (Datum) 0;
4093  }
4094  else
4095  {
4096  /* detoast ACL if necessary */
4097  acl = DatumGetAclP(aclDatum);
4098  }
4099 
4100  result = aclmask(acl, roleid, ownerId, mask, how);
4101 
4102  /* if we have a detoasted copy, free it */
4103  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4104  pfree(acl);
4105 
4106  ReleaseSysCache(tuple);
4107 
4108  return result;
4109 }
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
@ LANGOID
Definition: syscache.h:68

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, LANGOID, OBJECT_LANGUAGE, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_language_aclcheck().

◆ pg_language_ownercheck()

bool pg_language_ownercheck ( Oid  lan_oid,
Oid  roleid 
)

Definition at line 4924 of file aclchk.c.

4925 {
4926  HeapTuple tuple;
4927  Oid ownerId;
4928 
4929  /* Superusers bypass all permission checking. */
4930  if (superuser_arg(roleid))
4931  return true;
4932 
4933  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid));
4934  if (!HeapTupleIsValid(tuple))
4935  ereport(ERROR,
4936  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4937  errmsg("language with OID %u does not exist", lan_oid)));
4938 
4939  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
4940 
4941  ReleaseSysCache(tuple);
4942 
4943  return has_privs_of_role(roleid, ownerId);
4944 }

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, LANGOID, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership(), and CreateProceduralLanguage().

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4744 of file aclchk.c.

4746 {
4747  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4748  ACLMASK_ANY, snapshot) != 0)
4749  return ACLCHECK_OK;
4750  else
4751  return ACLCHECK_NO_PRIV;
4752 }
AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:4124

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

Referenced by be_lo_put(), and inv_open().

◆ pg_largeobject_aclmask_snapshot()

AclMode pg_largeobject_aclmask_snapshot ( Oid  lobj_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
Snapshot  snapshot 
)

Definition at line 4124 of file aclchk.c.

4127 {
4128  AclMode result;
4129  Relation pg_lo_meta;
4130  ScanKeyData entry[1];
4131  SysScanDesc scan;
4132  HeapTuple tuple;
4133  Datum aclDatum;
4134  bool isNull;
4135  Acl *acl;
4136  Oid ownerId;
4137 
4138  /* Superusers bypass all permission checking. */
4139  if (superuser_arg(roleid))
4140  return mask;
4141 
4142  /*
4143  * Get the largeobject's ACL from pg_largeobject_metadata
4144  */
4145  pg_lo_meta = table_open(LargeObjectMetadataRelationId,
4146  AccessShareLock);
4147 
4148  ScanKeyInit(&entry[0],
4149  Anum_pg_largeobject_metadata_oid,
4150  BTEqualStrategyNumber, F_OIDEQ,
4151  ObjectIdGetDatum(lobj_oid));
4152 
4153  scan = systable_beginscan(pg_lo_meta,
4154  LargeObjectMetadataOidIndexId, true,
4155  snapshot, 1, entry);
4156 
4157  tuple = systable_getnext(scan);
4158  if (!HeapTupleIsValid(tuple))
4159  ereport(ERROR,
4160  (errcode(ERRCODE_UNDEFINED_OBJECT),
4161  errmsg("large object %u does not exist", lobj_oid)));
4162 
4163  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
4164 
4165  aclDatum = heap_getattr(tuple, Anum_pg_largeobject_metadata_lomacl,
4166  RelationGetDescr(pg_lo_meta), &isNull);
4167 
4168  if (isNull)
4169  {
4170  /* No ACL, so build default ACL */
4171  acl = acldefault(OBJECT_LARGEOBJECT, ownerId);
4172  aclDatum = (Datum) 0;
4173  }
4174  else
4175  {
4176  /* detoast ACL if necessary */
4177  acl = DatumGetAclP(aclDatum);
4178  }
4179 
4180  result = aclmask(acl, roleid, ownerId, mask, how);
4181 
4182  /* if we have a detoasted copy, free it */
4183  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4184  pfree(acl);
4185 
4186  systable_endscan(scan);
4187 
4188  table_close(pg_lo_meta, AccessShareLock);
4189 
4190  return result;
4191 }
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:756
FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
#define RelationGetDescr(relation)
Definition: rel.h:504

References AccessShareLock, acldefault(), aclmask(), BTEqualStrategyNumber, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, heap_getattr, HeapTupleIsValid, OBJECT_LARGEOBJECT, ObjectIdGetDatum, pfree(), RelationGetDescr, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().

◆ pg_largeobject_ownercheck()

bool pg_largeobject_ownercheck ( Oid  lobj_oid,
Oid  roleid 
)

Definition at line 4953 of file aclchk.c.

4954 {
4955  Relation pg_lo_meta;
4956  ScanKeyData entry[1];
4957  SysScanDesc scan;
4958  HeapTuple tuple;
4959  Oid ownerId;
4960 
4961  /* Superusers bypass all permission checking. */
4962  if (superuser_arg(roleid))
4963  return true;
4964 
4965  /* There's no syscache for pg_largeobject_metadata */
4966  pg_lo_meta = table_open(LargeObjectMetadataRelationId,
4967  AccessShareLock);
4968 
4969  ScanKeyInit(&entry[0],
4970  Anum_pg_largeobject_metadata_oid,
4971  BTEqualStrategyNumber, F_OIDEQ,
4972  ObjectIdGetDatum(lobj_oid));
4973 
4974  scan = systable_beginscan(pg_lo_meta,
4975  LargeObjectMetadataOidIndexId, true,
4976  NULL, 1, entry);
4977 
4978  tuple = systable_getnext(scan);
4979  if (!HeapTupleIsValid(tuple))
4980  ereport(ERROR,
4981  (errcode(ERRCODE_UNDEFINED_OBJECT),
4982  errmsg("large object %u does not exist", lobj_oid)));
4983 
4984  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
4985 
4986  systable_endscan(scan);
4987  table_close(pg_lo_meta, AccessShareLock);
4988 
4989  return has_privs_of_role(roleid, ownerId);
4990 }

References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by be_lo_unlink(), and check_object_ownership().

◆ pg_namespace_aclcheck()

◆ pg_namespace_aclmask()

AclMode pg_namespace_aclmask ( Oid  nsp_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4197 of file aclchk.c.

4199 {
4200  AclMode result;
4201  HeapTuple tuple;
4202  Datum aclDatum;
4203  bool isNull;
4204  Acl *acl;
4205  Oid ownerId;
4206 
4207  /* Superusers bypass all permission checking. */
4208  if (superuser_arg(roleid))
4209  return mask;
4210 
4211  /*
4212  * If we have been assigned this namespace as a temp namespace, check to
4213  * make sure we have CREATE TEMP permission on the database, and if so act
4214  * as though we have all standard (but not GRANT OPTION) permissions on
4215  * the namespace. If we don't have CREATE TEMP, act as though we have
4216  * only USAGE (and not CREATE) rights.
4217  *
4218  * This may seem redundant given the check in InitTempTableNamespace, but
4219  * it really isn't since current user ID may have changed since then. The
4220  * upshot of this behavior is that a SECURITY DEFINER function can create
4221  * temp tables that can then be accessed (if permission is granted) by
4222  * code in the same session that doesn't have permissions to create temp
4223  * tables.
4224  *
4225  * XXX Would it be safe to ereport a special error message as
4226  * InitTempTableNamespace does? Returning zero here means we'll get a
4227  * generic "permission denied for schema pg_temp_N" message, which is not
4228  * remarkably user-friendly.
4229  */
4230  if (isTempNamespace(nsp_oid))
4231  {
4232  if (pg_database_aclcheck(MyDatabaseId, roleid,
4234  return mask & ACL_ALL_RIGHTS_SCHEMA;
4235  else
4236  return mask & ACL_USAGE;
4237  }
4238 
4239  /*
4240  * Get the schema's ACL from pg_namespace
4241  */
4242  tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
4243  if (!HeapTupleIsValid(tuple))
4244  ereport(ERROR,
4245  (errcode(ERRCODE_UNDEFINED_SCHEMA),
4246  errmsg("schema with OID %u does not exist", nsp_oid)));
4247 
4248  ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
4249 
4250  aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl,
4251  &isNull);
4252  if (isNull)
4253  {
4254  /* No ACL, so build default ACL */
4255  acl = acldefault(OBJECT_SCHEMA, ownerId);
4256  aclDatum = (Datum) 0;
4257  }
4258  else
4259  {
4260  /* detoast ACL if necessary */
4261  acl = DatumGetAclP(aclDatum);
4262  }
4263 
4264  result = aclmask(acl, roleid, ownerId, mask, how);
4265 
4266  /* if we have a detoasted copy, free it */
4267  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4268  pfree(acl);
4269 
4270  ReleaseSysCache(tuple);
4271 
4272  /*
4273  * Check if ACL_USAGE is being checked and, if so, and not set already as
4274  * part of the result, then check if the user is a member of the
4275  * pg_read_all_data or pg_write_all_data roles, which allow usage access
4276  * to all schemas.
4277  */
4278  if (mask & ACL_USAGE && !(result & ACL_USAGE) &&
4279  (has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA) ||
4280  has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA)))
4281  result |= ACL_USAGE;
4282  return result;
4283 }
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4708
bool isTempNamespace(Oid namespaceId)
Definition: namespace.c:3202
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:52
@ NAMESPACEOID
Definition: syscache.h:70

References ACL_ALL_RIGHTS_SCHEMA, ACL_CREATE_TEMP, ACL_USAGE, ACLCHECK_OK, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, isTempNamespace(), MyDatabaseId, NAMESPACEOID, OBJECT_SCHEMA, ObjectIdGetDatum, pfree(), pg_database_aclcheck(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_namespace_aclcheck().

◆ pg_namespace_ownercheck()

bool pg_namespace_ownercheck ( Oid  nsp_oid,
Oid  roleid 
)

Definition at line 4996 of file aclchk.c.

4997 {
4998  HeapTuple tuple;
4999  Oid ownerId;
5000 
5001  /* Superusers bypass all permission checking. */
5002  if (superuser_arg(roleid))
5003  return true;
5004 
5005  tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
5006  if (!HeapTupleIsValid(tuple))
5007  ereport(ERROR,
5008  (errcode(ERRCODE_UNDEFINED_SCHEMA),
5009  errmsg("schema with OID %u does not exist", nsp_oid)));
5010 
5011  ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
5012 
5013  ReleaseSysCache(tuple);
5014 
5015  return has_privs_of_role(roleid, ownerId);
5016 }

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, NAMESPACEOID, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterSchemaOwner_internal(), check_object_ownership(), RangeVarCallbackForDropRelation(), ReindexMultipleTables(), RemoveObjects(), and RenameSchema().

◆ pg_opclass_ownercheck()

bool pg_opclass_ownercheck ( Oid  opc_oid,
Oid  roleid 
)

Definition at line 5049 of file aclchk.c.

5050 {
5051  HeapTuple tuple;
5052  Oid ownerId;
5053 
5054  /* Superusers bypass all permission checking. */
5055  if (superuser_arg(roleid))
5056  return true;
5057 
5058  tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opc_oid));
5059  if (!HeapTupleIsValid(tuple))
5060  ereport(ERROR,
5061  (errcode(ERRCODE_UNDEFINED_OBJECT),
5062  errmsg("operator class with OID %u does not exist",
5063  opc_oid)));
5064 
5065  ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
5066 
5067  ReleaseSysCache(tuple);
5068 
5069  return has_privs_of_role(roleid, ownerId);
5070 }
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
@ CLAOID
Definition: syscache.h:48

References CLAOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership().

◆ pg_oper_ownercheck()

bool pg_oper_ownercheck ( Oid  oper_oid,
Oid  roleid 
)

Definition at line 4872 of file aclchk.c.

4873 {
4874  HeapTuple tuple;
4875  Oid ownerId;
4876 
4877  /* Superusers bypass all permission checking. */
4878  if (superuser_arg(roleid))
4879  return true;
4880 
4881  tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(oper_oid));
4882  if (!HeapTupleIsValid(tuple))
4883  ereport(ERROR,
4884  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4885  errmsg("operator with OID %u does not exist", oper_oid)));
4886 
4887  ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
4888 
4889  ReleaseSysCache(tuple);
4890 
4891  return has_privs_of_role(roleid, ownerId);
4892 }
FormData_pg_operator * Form_pg_operator
Definition: pg_operator.h:83
@ OPEROID
Definition: syscache.h:72

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, OPEROID, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterOperator(), AlterOpFamilyAdd(), check_object_ownership(), DefineOpClass(), and OperatorCreate().

◆ pg_opfamily_ownercheck()

bool pg_opfamily_ownercheck ( Oid  opf_oid,
Oid  roleid 
)

Definition at line 5076 of file aclchk.c.

5077 {
5078  HeapTuple tuple;
5079  Oid ownerId;
5080 
5081  /* Superusers bypass all permission checking. */
5082  if (superuser_arg(roleid))
5083  return true;
5084 
5085  tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opf_oid));
5086  if (!HeapTupleIsValid(tuple))
5087  ereport(ERROR,
5088  (errcode(ERRCODE_UNDEFINED_OBJECT),
5089  errmsg("operator family with OID %u does not exist",
5090  opf_oid)));
5091 
5092  ownerId = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfowner;
5093 
5094  ReleaseSysCache(tuple);
5095 
5096  return has_privs_of_role(roleid, ownerId);
5097 }
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:51
@ OPFAMILYOID
Definition: syscache.h:74

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, OPFAMILYOID, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership().

◆ pg_proc_aclcheck()

◆ pg_proc_aclmask()

AclMode pg_proc_aclmask ( Oid  proc_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4007 of file aclchk.c.

4009 {
4010  AclMode result;
4011  HeapTuple tuple;
4012  Datum aclDatum;
4013  bool isNull;
4014  Acl *acl;
4015  Oid ownerId;
4016 
4017  /* Superusers bypass all permission checking. */
4018  if (superuser_arg(roleid))
4019  return mask;
4020 
4021  /*
4022  * Get the function's ACL from pg_proc
4023  */
4024  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc_oid));
4025  if (!HeapTupleIsValid(tuple))
4026  ereport(ERROR,
4027  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4028  errmsg("function with OID %u does not exist", proc_oid)));
4029 
4030  ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
4031 
4032  aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
4033  &isNull);
4034  if (isNull)
4035  {
4036  /* No ACL, so build default ACL */
4037  acl = acldefault(OBJECT_FUNCTION, ownerId);
4038  aclDatum = (Datum) 0;
4039  }
4040  else
4041  {
4042  /* detoast ACL if necessary */
4043  acl = DatumGetAclP(aclDatum);
4044  }
4045 
4046  result = aclmask(acl, roleid, ownerId, mask, how);
4047 
4048  /* if we have a detoasted copy, free it */
4049  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4050  pfree(acl);
4051 
4052  ReleaseSysCache(tuple);
4053 
4054  return result;
4055 }
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
@ PROCOID
Definition: syscache.h:77

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, OBJECT_FUNCTION, ObjectIdGetDatum, pfree(), PROCOID, ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask(), and pg_proc_aclcheck().

◆ pg_proc_ownercheck()

bool pg_proc_ownercheck ( Oid  proc_oid,
Oid  roleid 
)

Definition at line 4898 of file aclchk.c.

4899 {
4900  HeapTuple tuple;
4901  Oid ownerId;
4902 
4903  /* Superusers bypass all permission checking. */
4904  if (superuser_arg(roleid))
4905  return true;
4906 
4907  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc_oid));
4908  if (!HeapTupleIsValid(tuple))
4909  ereport(ERROR,
4910  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4911  errmsg("function with OID %u does not exist", proc_oid)));
4912 
4913  ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
4914 
4915  ReleaseSysCache(tuple);
4916 
4917  return has_privs_of_role(roleid, ownerId);
4918 }

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, PROCOID, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterFunction(), AlterOpFamilyAdd(), check_object_ownership(), CreateTransform(), DefineOpClass(), DefineType(), and ProcedureCreate().

◆ pg_publication_ownercheck()

bool pg_publication_ownercheck ( Oid  pub_oid,
Oid  roleid 
)

Definition at line 5358 of file aclchk.c.

5359 {
5360  HeapTuple tuple;
5361  Oid ownerId;
5362 
5363  /* Superusers bypass all permission checking. */
5364  if (superuser_arg(roleid))
5365  return true;
5366 
5367  tuple = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pub_oid));
5368  if (!HeapTupleIsValid(tuple))
5369  ereport(ERROR,
5370  (errcode(ERRCODE_UNDEFINED_OBJECT),
5371  errmsg("publication with OID %u does not exist", pub_oid)));
5372 
5373  ownerId = ((Form_pg_publication) GETSTRUCT(tuple))->pubowner;
5374 
5375  ReleaseSysCache(tuple);
5376 
5377  return has_privs_of_role(roleid, ownerId);
5378 }
FormData_pg_publication * Form_pg_publication
@ PUBLICATIONOID
Definition: syscache.h:81

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, PUBLICATIONOID, ReleaseSysCache(), SearchSysCache1(), and superuser_arg().

Referenced by AlterPublication(), AlterPublicationOwner_internal(), and check_object_ownership().

◆ pg_statistics_object_ownercheck()

bool pg_statistics_object_ownercheck ( Oid  stat_oid,
Oid  roleid 
)

Definition at line 5410 of file aclchk.c.

5411 {
5412  HeapTuple tuple;
5413  Oid ownerId;
5414 
5415  /* Superusers bypass all permission checking. */
5416  if (superuser_arg(roleid))
5417  return true;
5418 
5419  tuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stat_oid));
5420  if (!HeapTupleIsValid(tuple))
5421  ereport(ERROR,
5422  (errcode(ERRCODE_UNDEFINED_OBJECT),
5423  errmsg("statistics object with OID %u does not exist",
5424  stat_oid)));
5425 
5426  ownerId = ((Form_pg_statistic_ext) GETSTRUCT(tuple))->stxowner;
5427 
5428  ReleaseSysCache(tuple);
5429 
5430  return has_privs_of_role(roleid, ownerId);
5431 }
FormData_pg_statistic_ext * Form_pg_statistic_ext
@ STATEXTOID
Definition: syscache.h:94

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), STATEXTOID, and superuser_arg().

Referenced by AlterStatistics(), and check_object_ownership().

◆ pg_subscription_ownercheck()

bool pg_subscription_ownercheck ( Oid  sub_oid,
Oid  roleid 
)

Definition at line 5384 of file aclchk.c.

5385 {
5386  HeapTuple tuple;
5387  Oid ownerId;
5388 
5389  /* Superusers bypass all permission checking. */
5390  if (superuser_arg(roleid))
5391  return true;
5392 
5394  if (!HeapTupleIsValid(tuple))
5395  ereport(ERROR,
5396  (errcode(ERRCODE_UNDEFINED_OBJECT),
5397  errmsg("subscription with OID %u does not exist", sub_oid)));
5398 
5399  ownerId = ((Form_pg_subscription) GETSTRUCT(tuple))->subowner;
5400 
5401  ReleaseSysCache(tuple);
5402 
5403  return has_privs_of_role(roleid, ownerId);
5404 }
FormData_pg_subscription * Form_pg_subscription
@ SUBSCRIPTIONOID
Definition: syscache.h:97

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), SUBSCRIPTIONOID, and superuser_arg().

Referenced by AlterSubscription(), AlterSubscriptionOwner_internal(), check_object_ownership(), and DropSubscription().

◆ pg_tablespace_aclcheck()

◆ pg_tablespace_aclmask()

AclMode pg_tablespace_aclmask ( Oid  spc_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4289 of file aclchk.c.

4291 {
4292  AclMode result;
4293  HeapTuple tuple;
4294  Datum aclDatum;
4295  bool isNull;
4296  Acl *acl;
4297  Oid ownerId;
4298 
4299  /* Superusers bypass all permission checking. */
4300  if (superuser_arg(roleid))
4301  return mask;
4302 
4303  /*
4304  * Get the tablespace's ACL from pg_tablespace
4305  */
4306  tuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid));
4307  if (!HeapTupleIsValid(tuple))
4308  ereport(ERROR,
4309  (errcode(ERRCODE_UNDEFINED_OBJECT),
4310  errmsg("tablespace with OID %u does not exist", spc_oid)));
4311 
4312  ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner;
4313 
4314  aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple,
4315  Anum_pg_tablespace_spcacl,
4316  &isNull);
4317 
4318  if (isNull)
4319  {
4320  /* No ACL, so build default ACL */
4321  acl = acldefault(OBJECT_TABLESPACE, ownerId);
4322  aclDatum = (Datum) 0;
4323  }
4324  else
4325  {
4326  /* detoast ACL if necessary */
4327  acl = DatumGetAclP(aclDatum);
4328  }
4329 
4330  result = aclmask(acl, roleid, ownerId, mask, how);
4331 
4332  /* if we have a detoasted copy, free it */
4333  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4334  pfree(acl);
4335 
4336  ReleaseSysCache(tuple);
4337 
4338  return result;
4339 }
FormData_pg_tablespace * Form_pg_tablespace
Definition: pg_tablespace.h:48
@ TABLESPACEOID
Definition: syscache.h:99

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, OBJECT_TABLESPACE, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), SysCacheGetAttr(), and TABLESPACEOID.

Referenced by pg_aclmask(), and pg_tablespace_aclcheck().

◆ pg_tablespace_ownercheck()

bool pg_tablespace_ownercheck ( Oid  spc_oid,
Oid  roleid 
)

Definition at line 5022 of file aclchk.c.

5023 {
5024  HeapTuple spctuple;
5025  Oid spcowner;
5026 
5027  /* Superusers bypass all permission checking. */
5028  if (superuser_arg(roleid))
5029  return true;
5030 
5031  /* Search syscache for pg_tablespace */
5032  spctuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid));
5033  if (!HeapTupleIsValid(spctuple))
5034  ereport(ERROR,
5035  (errcode(ERRCODE_UNDEFINED_OBJECT),
5036  errmsg("tablespace with OID %u does not exist", spc_oid)));
5037 
5038  spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner;
5039 
5040  ReleaseSysCache(spctuple);
5041 
5042  return has_privs_of_role(roleid, spcowner);
5043 }

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and TABLESPACEOID.

Referenced by AlterTableSpaceOptions(), check_object_ownership(), DropTableSpace(), and RenameTableSpace().

◆ pg_ts_config_ownercheck()

bool pg_ts_config_ownercheck ( Oid  cfg_oid,
Oid  roleid 
)

Definition at line 5130 of file aclchk.c.

5131 {
5132  HeapTuple tuple;
5133  Oid ownerId;
5134 
5135  /* Superusers bypass all permission checking. */
5136  if (superuser_arg(roleid))
5137  return true;
5138 
5139  tuple = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfg_oid));
5140  if (!HeapTupleIsValid(tuple))
5141  ereport(ERROR,
5142  (errcode(ERRCODE_UNDEFINED_OBJECT),
5143  errmsg("text search configuration with OID %u does not exist",
5144  cfg_oid)));
5145 
5146  ownerId = ((Form_pg_ts_config) GETSTRUCT(tuple))->cfgowner;
5147 
5148  ReleaseSysCache(tuple);
5149 
5150  return has_privs_of_role(roleid, ownerId);
5151 }
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
@ TSCONFIGOID
Definition: syscache.h:104

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and TSCONFIGOID.

Referenced by AlterTSConfiguration(), and check_object_ownership().

◆ pg_ts_dict_ownercheck()

bool pg_ts_dict_ownercheck ( Oid  dict_oid,
Oid  roleid 
)

Definition at line 5103 of file aclchk.c.

5104 {
5105  HeapTuple tuple;
5106  Oid ownerId;
5107 
5108  /* Superusers bypass all permission checking. */
5109  if (superuser_arg(roleid))
5110  return true;
5111 
5112  tuple = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dict_oid));
5113  if (!HeapTupleIsValid(tuple))
5114  ereport(ERROR,
5115  (errcode(ERRCODE_UNDEFINED_OBJECT),
5116  errmsg("text search dictionary with OID %u does not exist",
5117  dict_oid)));
5118 
5119  ownerId = ((Form_pg_ts_dict) GETSTRUCT(tuple))->dictowner;
5120 
5121  ReleaseSysCache(tuple);
5122 
5123  return has_privs_of_role(roleid, ownerId);
5124 }
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
@ TSDICTOID
Definition: syscache.h:106

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and TSDICTOID.

Referenced by AlterTSDictionary(), and check_object_ownership().

◆ pg_type_aclcheck()

◆ pg_type_aclmask()

AclMode pg_type_aclmask ( Oid  type_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4469 of file aclchk.c.

4470 {
4471  AclMode result;
4472  HeapTuple tuple;
4473  Datum aclDatum;
4474  bool isNull;
4475  Acl *acl;
4476  Oid ownerId;
4477 
4478  Form_pg_type typeForm;
4479 
4480  /* Bypass permission checks for superusers */
4481  if (superuser_arg(roleid))
4482  return mask;
4483 
4484  /*
4485  * Must get the type's tuple from pg_type
4486  */
4487  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
4488  if (!HeapTupleIsValid(tuple))
4489  ereport(ERROR,
4490  (errcode(ERRCODE_UNDEFINED_OBJECT),
4491  errmsg("type with OID %u does not exist",
4492  type_oid)));
4493  typeForm = (Form_pg_type) GETSTRUCT(tuple);
4494 
4495  /*
4496  * "True" array types don't manage permissions of their own; consult the
4497  * element type instead.
4498  */
4499  if (IsTrueArrayType(typeForm))
4500  {
4501  Oid elttype_oid = typeForm->typelem;
4502 
4503  ReleaseSysCache(tuple);
4504 
4505  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(elttype_oid));
4506  /* this case is not a user-facing error, so elog not ereport */
4507  if (!HeapTupleIsValid(tuple))
4508  elog(ERROR, "cache lookup failed for type %u", elttype_oid);
4509  typeForm = (Form_pg_type) GETSTRUCT(tuple);
4510  }
4511 
4512  /*
4513  * Now get the type's owner and ACL from the tuple
4514  */
4515  ownerId = typeForm->typowner;
4516 
4517  aclDatum = SysCacheGetAttr(TYPEOID, tuple,
4518  Anum_pg_type_typacl, &isNull);
4519  if (isNull)
4520  {
4521  /* No ACL, so build default ACL */
4522  acl = acldefault(OBJECT_TYPE, ownerId);
4523  aclDatum = (Datum) 0;
4524  }
4525  else
4526  {
4527  /* detoast rel's ACL if necessary */
4528  acl = DatumGetAclP(aclDatum);
4529  }
4530 
4531  result = aclmask(acl, roleid, ownerId, mask, how);
4532 
4533  /* if we have a detoasted copy, free it */
4534  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4535  pfree(acl);
4536 
4537  ReleaseSysCache(tuple);
4538 
4539  return result;
4540 }
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
@ TYPEOID
Definition: syscache.h:112

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, OBJECT_TYPE, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1(), superuser_arg(), SysCacheGetAttr(), and TYPEOID.

Referenced by pg_aclmask(), and pg_type_aclcheck().

◆ pg_type_ownercheck()

bool pg_type_ownercheck ( Oid  type_oid,
Oid  roleid 
)

Definition at line 4846 of file aclchk.c.

4847 {
4848  HeapTuple tuple;
4849  Oid ownerId;
4850 
4851  /* Superusers bypass all permission checking. */
4852  if (superuser_arg(roleid))
4853  return true;
4854 
4855  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
4856  if (!HeapTupleIsValid(tuple))
4857  ereport(ERROR,
4858  (errcode(ERRCODE_UNDEFINED_OBJECT),
4859  errmsg("type with OID %u does not exist", type_oid)));
4860 
4861  ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
4862 
4863  ReleaseSysCache(tuple);
4864 
4865  return has_privs_of_role(roleid, ownerId);
4866 }

References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1(), superuser_arg(), and TYPEOID.

Referenced by AlterType(), AlterTypeNamespace_oid(), AlterTypeOwner(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), CreateCast(), CreateTransform(), DefineOpClass(), and RenameType().

◆ recordDependencyOnNewAcl()

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

Definition at line 5599 of file aclchk.c.

5601 {
5602  int nmembers;
5603  Oid *members;
5604 
5605  /* Nothing to do if ACL is defaulted */
5606  if (acl == NULL)
5607  return;
5608 
5609  /* Extract roles mentioned in ACL */
5610  nmembers = aclmembers(acl, &members);
5611 
5612  /* Update the shared dependency ACL info */
5613  updateAclDependencies(classId, objectId, objsubId,
5614  ownerId,
5615  0, NULL,
5616