PostgreSQL Source Code  git master
acl.h File Reference
#include "access/htup.h"
#include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/array.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_NAMESPACE   (ACL_USAGE|ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)
 

Typedefs

typedef struct AclItem AclItem
 
typedef ArrayType Acl
 
typedef enum AclObjectKind AclObjectKind
 

Enumerations

enum  AclMaskHow { ACLMASK_ALL, ACLMASK_ANY }
 
enum  AclResult { ACLCHECK_OK = 0, ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER }
 
enum  AclObjectKind {
  ACL_KIND_COLUMN, ACL_KIND_CLASS, ACL_KIND_SEQUENCE, ACL_KIND_DATABASE,
  ACL_KIND_PROC, ACL_KIND_OPER, ACL_KIND_TYPE, ACL_KIND_LANGUAGE,
  ACL_KIND_LARGEOBJECT, ACL_KIND_NAMESPACE, ACL_KIND_OPCLASS, ACL_KIND_OPFAMILY,
  ACL_KIND_COLLATION, ACL_KIND_CONVERSION, ACL_KIND_STATISTICS, ACL_KIND_TABLESPACE,
  ACL_KIND_TSDICTIONARY, ACL_KIND_TSCONFIGURATION, ACL_KIND_FDW, ACL_KIND_FOREIGN_SERVER,
  ACL_KIND_EVENT_TRIGGER, ACL_KIND_EXTENSION, ACL_KIND_PUBLICATION, ACL_KIND_SUBSCRIPTION,
  MAX_ACL_KIND
}
 

Functions

Aclacldefault (GrantObjectType objtype, Oid ownerId)
 
Aclget_user_default_acl (GrantObjectType objtype, Oid ownerId, Oid nsp_oid)
 
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)
 
void RemoveDefaultACLById (Oid defaclOid)
 
AclMode pg_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
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_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
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, AclObjectKind objectkind, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, AclObjectKind objectkind, 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 157 of file acl.h.

Referenced by ExecGrant_Attribute(), ExecGrant_Relation(), and restrict_and_check_grant().

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 160 of file acl.h.

Referenced by acldefault(), ExecGrant_Database(), ExecuteGrantStmt(), and restrict_and_check_grant().

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 161 of file acl.h.

Referenced by acldefault(), ExecGrant_Fdw(), ExecuteGrantStmt(), and restrict_and_check_grant().

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 164 of file acl.h.

Referenced by acldefault(), ExecGrant_Language(), ExecuteGrantStmt(), and restrict_and_check_grant().

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

◆ ACL_ALL_RIGHTS_NAMESPACE

◆ ACL_ALL_RIGHTS_RELATION

◆ ACL_ALL_RIGHTS_SEQUENCE

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTc"

Definition at line 152 of file acl.h.

Referenced by aclitemout(), and aclparse().

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 149 of file acl.h.

Referenced by aclparse().

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 147 of file acl.h.

Referenced by aclparse().

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 148 of file acl.h.

Referenced by aclparse().

◆ ACL_DAT

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 145 of file acl.h.

Referenced by aclparse().

◆ ACL_GRANT_OPTION_FOR

◆ ACL_ID_PUBLIC

◆ ACL_INSERT_CHR

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

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 130 of file acl.h.

Referenced by aclmerge(), aclupdate(), and merge_acl_with_grant().

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 131 of file acl.h.

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

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 132 of file acl.h.

Referenced by aclupdate().

◆ ACL_N_SIZE

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

Definition at line 111 of file acl.h.

Referenced by aclnewowner(), aclupdate(), and allocacl().

◆ ACL_NUM

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 72 of file acl.h.

Referenced by check_circularity(), recursive_revoke(), and restrict_and_check_grant().

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 143 of file acl.h.

Referenced by aclparse().

◆ ACL_SELECT_CHR

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

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 112 of file acl.h.

Referenced by aclupdate(), and check_circularity().

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 144 of file acl.h.

Referenced by aclparse().

◆ ACL_TRUNCATE_CHR

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

Definition at line 142 of file acl.h.

Referenced by aclparse().

◆ ACL_UPDATE_CHR

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

Definition at line 140 of file acl.h.

Referenced by aclparse(), get_policies_for_relation(), and parse_policy_command().

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 146 of file acl.h.

Referenced by aclparse().

◆ ACLITEM_ALL_GOPTION_BITS

#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFF << 16)

Definition at line 89 of file acl.h.

Referenced by aclmask(), and aclmask_direct().

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFF)

Definition at line 88 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 68 of file acl.h.

Referenced by aclexplode(), aclitemout(), aclupdate(), and check_circularity().

◆ ACLITEM_GET_PRIVS

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

Definition at line 67 of file acl.h.

Referenced by aclexplode(), aclitemout(), and recursive_revoke().

◆ ACLITEM_GET_RIGHTS

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

Definition at line 69 of file acl.h.

Referenced by aclcontains(), aclnewowner(), and aclupdate().

◆ 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:70

Definition at line 77 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))
uint32 AclMode
Definition: parsenodes.h:70

Definition at line 74 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))
uint32 AclMode
Definition: parsenodes.h:70

Definition at line 83 of file acl.h.

Referenced by acldefault(), aclparse(), aclupdate(), makeaclitem(), merge_acl_with_grant(), and recursive_revoke().

◆ ACLITEM_SET_RIGHTS

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

Definition at line 80 of file acl.h.

Referenced by aclnewowner(), and aclupdate().

◆ DatumGetAclItemP

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

Definition at line 117 of file acl.h.

◆ DatumGetAclP

◆ DatumGetAclPCopy

◆ PG_GETARG_ACL_P

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

Definition at line 123 of file acl.h.

Referenced by aclcontains(), and aclexplode().

◆ PG_GETARG_ACL_P_COPY

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

Definition at line 124 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 118 of file acl.h.

Referenced by aclcontains(), aclitem_eq(), aclitemout(), hash_aclitem(), and hash_aclitem_extended().

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 125 of file acl.h.

Referenced by acldefault_sql().

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 119 of file acl.h.

Referenced by aclitemin(), and makeaclitem().

Typedef Documentation

◆ Acl

Definition at line 107 of file acl.h.

◆ AclItem

◆ AclObjectKind

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 171 of file acl.h.

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

◆ AclObjectKind

Enumerator
ACL_KIND_COLUMN 
ACL_KIND_CLASS 
ACL_KIND_SEQUENCE 
ACL_KIND_DATABASE 
ACL_KIND_PROC 
ACL_KIND_OPER 
ACL_KIND_TYPE 
ACL_KIND_LANGUAGE 
ACL_KIND_LARGEOBJECT 
ACL_KIND_NAMESPACE 
ACL_KIND_OPCLASS 
ACL_KIND_OPFAMILY 
ACL_KIND_COLLATION 
ACL_KIND_CONVERSION 
ACL_KIND_STATISTICS 
ACL_KIND_TABLESPACE 
ACL_KIND_TSDICTIONARY 
ACL_KIND_TSCONFIGURATION 
ACL_KIND_FDW 
ACL_KIND_FOREIGN_SERVER 
ACL_KIND_EVENT_TRIGGER 
ACL_KIND_EXTENSION 
ACL_KIND_PUBLICATION 
ACL_KIND_SUBSCRIPTION 
MAX_ACL_KIND 

Definition at line 187 of file acl.h.

188 {
189  ACL_KIND_COLUMN, /* pg_attribute */
190  ACL_KIND_CLASS, /* pg_class */
191  ACL_KIND_SEQUENCE, /* pg_sequence */
192  ACL_KIND_DATABASE, /* pg_database */
193  ACL_KIND_PROC, /* pg_proc */
194  ACL_KIND_OPER, /* pg_operator */
195  ACL_KIND_TYPE, /* pg_type */
196  ACL_KIND_LANGUAGE, /* pg_language */
197  ACL_KIND_LARGEOBJECT, /* pg_largeobject */
198  ACL_KIND_NAMESPACE, /* pg_namespace */
199  ACL_KIND_OPCLASS, /* pg_opclass */
200  ACL_KIND_OPFAMILY, /* pg_opfamily */
201  ACL_KIND_COLLATION, /* pg_collation */
202  ACL_KIND_CONVERSION, /* pg_conversion */
203  ACL_KIND_STATISTICS, /* pg_statistic_ext */
204  ACL_KIND_TABLESPACE, /* pg_tablespace */
205  ACL_KIND_TSDICTIONARY, /* pg_ts_dict */
206  ACL_KIND_TSCONFIGURATION, /* pg_ts_config */
207  ACL_KIND_FDW, /* pg_foreign_data_wrapper */
208  ACL_KIND_FOREIGN_SERVER, /* pg_foreign_server */
209  ACL_KIND_EVENT_TRIGGER, /* pg_event_trigger */
210  ACL_KIND_EXTENSION, /* pg_extension */
211  ACL_KIND_PUBLICATION, /* pg_publication */
212  ACL_KIND_SUBSCRIPTION, /* pg_subscription */
213  MAX_ACL_KIND /* MUST BE LAST */
214 } AclObjectKind;
AclObjectKind
Definition: acl.h:187

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 178 of file acl.h.

179 {
180  ACLCHECK_OK = 0,
183 } AclResult;
AclResult
Definition: acl.h:178

Function Documentation

◆ aclcheck_error()

void aclcheck_error ( AclResult  aclerr,
AclObjectKind  objectkind,
const char *  objectname 
)

Definition at line 3457 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg(), and ERROR.

Referenced by 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(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetStatistics(), 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(), create_proc_lang(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateTransform(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecCheckRTPerms(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncate(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), get_rel_from_relname(), gin_clean_pending_list(), HandleFunctionRequest(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockTableRecurse(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_prewarm(), pgrowlocks(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), transformTableLikeClause(), truncate_check_rel(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

3459 {
3460  switch (aclerr)
3461  {
3462  case ACLCHECK_OK:
3463  /* no error, so return to caller */
3464  break;
3465  case ACLCHECK_NO_PRIV:
3466  ereport(ERROR,
3467  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3468  errmsg(no_priv_msg[objectkind], objectname)));
3469  break;
3470  case ACLCHECK_NOT_OWNER:
3471  ereport(ERROR,
3472  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3473  errmsg(not_owner_msg[objectkind], objectname)));
3474  break;
3475  default:
3476  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3477  break;
3478  }
3479 }
static const char *const no_priv_msg[MAX_ACL_KIND]
Definition: aclchk.c:3351
static const char *const not_owner_msg[MAX_ACL_KIND]
Definition: aclchk.c:3403
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ aclcheck_error_col()

void aclcheck_error_col ( AclResult  aclerr,
AclObjectKind  objectkind,
const char *  objectname,
const char *  colname 
)

Definition at line 3483 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg(), and ERROR.

Referenced by restrict_and_check_grant().

3485 {
3486  switch (aclerr)
3487  {
3488  case ACLCHECK_OK:
3489  /* no error, so return to caller */
3490  break;
3491  case ACLCHECK_NO_PRIV:
3492  ereport(ERROR,
3493  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3494  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3495  colname, objectname)));
3496  break;
3497  case ACLCHECK_NOT_OWNER:
3498  /* relation msg is OK since columns don't have separate owners */
3499  ereport(ERROR,
3500  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3501  errmsg(not_owner_msg[objectkind], objectname)));
3502  break;
3503  default:
3504  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3505  break;
3506  }
3507 }
static const char *const not_owner_msg[MAX_ACL_KIND]
Definition: aclchk.c:3403
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ aclcheck_error_type()

void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

Definition at line 3515 of file aclchk.c.

References ACL_KIND_TYPE, aclcheck_error(), format_type_be(), and get_element_type().

Referenced by AggregateCreate(), AlterTypeNamespace_oid(), AlterTypeOwner(), ATExecAddColumn(), ATPrepAlterColumnType(), BuildDescForRelation(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), compute_return_type(), CreateCast(), CreateTransform(), DefineDomain(), DefineOpClass(), DefineOperator(), DefineRelation(), interpret_function_parameter_list(), and RenameType().

3516 {
3517  Oid element_type = get_element_type(typeOid);
3518 
3519  aclcheck_error(aclerr, ACL_KIND_TYPE, format_type_be(element_type ? element_type : typeOid));
3520 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2517
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3457

◆ aclconcat()

Acl* aclconcat ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 427 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

428 {
429  Acl *result_acl;
430 
431  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
432 
433  memcpy(ACL_DAT(result_acl),
434  ACL_DAT(left_acl),
435  ACL_NUM(left_acl) * sizeof(AclItem));
436 
437  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
438  ACL_DAT(right_acl),
439  ACL_NUM(right_acl) * sizeof(AclItem));
440 
441  return result_acl;
442 }
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55

◆ aclcopy()

Acl* aclcopy ( const Acl orig_acl)

Definition at line 407 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

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

408 {
409  Acl *result_acl;
410 
411  result_acl = allocacl(ACL_NUM(orig_acl));
412 
413  memcpy(ACL_DAT(result_acl),
414  ACL_DAT(orig_acl),
415  ACL_NUM(orig_acl) * sizeof(AclItem));
416 
417  return result_acl;
418 }
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55

◆ acldefault()

Acl* acldefault ( GrantObjectType  objtype,
Oid  ownerId 
)

Definition at line 748 of file acl.c.

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_NAMESPACE, ACL_ALL_RIGHTS_RELATION, 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_OBJECT_COLUMN, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog, and ERROR.

Referenced by acldefault_sql(), 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(), 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().

749 {
750  AclMode world_default;
751  AclMode owner_default;
752  int nacl;
753  Acl *acl;
754  AclItem *aip;
755 
756  switch (objtype)
757  {
758  case ACL_OBJECT_COLUMN:
759  /* by default, columns have no extra privileges */
760  world_default = ACL_NO_RIGHTS;
761  owner_default = ACL_NO_RIGHTS;
762  break;
763  case ACL_OBJECT_RELATION:
764  world_default = ACL_NO_RIGHTS;
765  owner_default = ACL_ALL_RIGHTS_RELATION;
766  break;
767  case ACL_OBJECT_SEQUENCE:
768  world_default = ACL_NO_RIGHTS;
769  owner_default = ACL_ALL_RIGHTS_SEQUENCE;
770  break;
771  case ACL_OBJECT_DATABASE:
772  /* for backwards compatibility, grant some rights by default */
773  world_default = ACL_CREATE_TEMP | ACL_CONNECT;
774  owner_default = ACL_ALL_RIGHTS_DATABASE;
775  break;
776  case ACL_OBJECT_FUNCTION:
777  /* Grant EXECUTE by default, for now */
778  world_default = ACL_EXECUTE;
779  owner_default = ACL_ALL_RIGHTS_FUNCTION;
780  break;
781  case ACL_OBJECT_LANGUAGE:
782  /* Grant USAGE by default, for now */
783  world_default = ACL_USAGE;
784  owner_default = ACL_ALL_RIGHTS_LANGUAGE;
785  break;
787  world_default = ACL_NO_RIGHTS;
788  owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
789  break;
791  world_default = ACL_NO_RIGHTS;
792  owner_default = ACL_ALL_RIGHTS_NAMESPACE;
793  break;
795  world_default = ACL_NO_RIGHTS;
796  owner_default = ACL_ALL_RIGHTS_TABLESPACE;
797  break;
798  case ACL_OBJECT_FDW:
799  world_default = ACL_NO_RIGHTS;
800  owner_default = ACL_ALL_RIGHTS_FDW;
801  break;
803  world_default = ACL_NO_RIGHTS;
804  owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
805  break;
806  case ACL_OBJECT_DOMAIN:
807  case ACL_OBJECT_TYPE:
808  world_default = ACL_USAGE;
809  owner_default = ACL_ALL_RIGHTS_TYPE;
810  break;
811  default:
812  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
813  world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
814  owner_default = ACL_NO_RIGHTS;
815  break;
816  }
817 
818  nacl = 0;
819  if (world_default != ACL_NO_RIGHTS)
820  nacl++;
821  if (owner_default != ACL_NO_RIGHTS)
822  nacl++;
823 
824  acl = allocacl(nacl);
825  aip = ACL_DAT(acl);
826 
827  if (world_default != ACL_NO_RIGHTS)
828  {
829  aip->ai_grantee = ACL_ID_PUBLIC;
830  aip->ai_grantor = ownerId;
831  ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
832  aip++;
833  }
834 
835  /*
836  * Note that the owner's entry shows all ordinary privileges but no grant
837  * options. This is because his grant options come "from the system" and
838  * not from his own efforts. (The SQL spec says that the owner's rights
839  * come from a "_SYSTEM" authid.) However, we do consider that the
840  * owner's ordinary privileges are self-granted; this lets him revoke
841  * them. We implement the owner's grant options without any explicit
842  * "_SYSTEM"-like ACL entry, by internally special-casing the owner
843  * wherever we are testing grant options.
844  */
845  if (owner_default != ACL_NO_RIGHTS)
846  {
847  aip->ai_grantee = ownerId;
848  aip->ai_grantor = ownerId;
849  ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
850  }
851 
852  return acl;
853 }
Oid ai_grantee
Definition: acl.h:57
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:163
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:167
Oid ai_grantor
Definition: acl.h:58
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:164
uint32 AclMode
Definition: parsenodes.h:70
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:86
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:168
#define ACL_USAGE
Definition: parsenodes.h:80
#define ACL_CONNECT
Definition: parsenodes.h:84
#define ACL_ALL_RIGHTS_NAMESPACE
Definition: acl.h:166
#define ACL_DAT(ACL)
Definition: acl.h:110
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:159
Definition: acl.h:55
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:165
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:160
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:162
#define ACL_EXECUTE
Definition: parsenodes.h:79
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:158
#define ACL_CREATE_TEMP
Definition: parsenodes.h:83
#define ACL_ID_PUBLIC
Definition: acl.h:47
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:161
#define elog
Definition: elog.h:219
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:83

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 509 of file acl.c.

References ACL_DAT, and ACL_NUM.

Referenced by get_user_default_acl(), and SetDefaultACL().

510 {
511  /* Check for cases where one or both are empty/null */
512  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
513  {
514  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
515  return true;
516  else
517  return false;
518  }
519  else
520  {
521  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
522  return false;
523  }
524 
525  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
526  return false;
527 
528  if (memcmp(ACL_DAT(left_acl),
529  ACL_DAT(right_acl),
530  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
531  return true;
532 
533  return false;
534 }
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 495 of file acl.c.

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

Referenced by get_user_default_acl(), and SetDefaultACL().

496 {
497  if (acl != NULL && ACL_NUM(acl) > 1)
498  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
499 }
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55
#define qsort(a, b, c, d)
Definition: port.h:408
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:669

◆ aclmask()

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

Definition at line 1321 of file acl.c.

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

1323 {
1324  AclMode result;
1326  AclItem *aidat;
1327  int i,
1328  num;
1329 
1330  /*
1331  * Null ACL should not happen, since caller should have inserted
1332  * appropriate default
1333  */
1334  if (acl == NULL)
1335  elog(ERROR, "null ACL");
1336 
1337  check_acl(acl);
1338 
1339  /* Quick exit for mask == 0 */
1340  if (mask == 0)
1341  return 0;
1342 
1343  result = 0;
1344 
1345  /* Owner always implicitly has all grant options */
1346  if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1347  has_privs_of_role(roleid, ownerId))
1348  {
1349  result = mask & ACLITEM_ALL_GOPTION_BITS;
1350  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1351  return result;
1352  }
1353 
1354  num = ACL_NUM(acl);
1355  aidat = ACL_DAT(acl);
1356 
1357  /*
1358  * Check privileges granted directly to roleid or to public
1359  */
1360  for (i = 0; i < num; i++)
1361  {
1362  AclItem *aidata = &aidat[i];
1363 
1364  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1365  aidata->ai_grantee == roleid)
1366  {
1367  result |= aidata->ai_privs & mask;
1368  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1369  return result;
1370  }
1371  }
1372 
1373  /*
1374  * Check privileges granted indirectly via role memberships. We do this in
1375  * a separate pass to minimize expensive indirect membership tests. In
1376  * particular, it's worth testing whether a given ACL entry grants any
1377  * privileges still of interest before we perform the has_privs_of_role
1378  * test.
1379  */
1380  remaining = mask & ~result;
1381  for (i = 0; i < num; i++)
1382  {
1383  AclItem *aidata = &aidat[i];
1384 
1385  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1386  aidata->ai_grantee == roleid)
1387  continue; /* already checked it */
1388 
1389  if ((aidata->ai_privs & remaining) &&
1390  has_privs_of_role(roleid, aidata->ai_grantee))
1391  {
1392  result |= aidata->ai_privs & mask;
1393  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1394  return result;
1395  remaining = mask & ~result;
1396  }
1397  }
1398 
1399  return result;
1400 }
int remaining
Definition: informix.c:692
Oid ai_grantee
Definition: acl.h:57
#define ACLITEM_ALL_GOPTION_BITS
Definition: acl.h:89
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
AclMode ai_privs
Definition: acl.h:59
uint32 AclMode
Definition: parsenodes.h:70
#define ERROR
Definition: elog.h:43
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55
int i
#define ACL_ID_PUBLIC
Definition: acl.h:47
#define elog
Definition: elog.h:219
static void check_acl(const Acl *acl)
Definition: acl.c:540

◆ aclmembers()

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

Definition at line 1473 of file acl.c.

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

Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), heap_create_with_catalog(), ProcedureCreate(), and SetDefaultACL().

1474 {
1475  Oid *list;
1476  const AclItem *acldat;
1477  int i,
1478  j,
1479  k;
1480 
1481  if (acl == NULL || ACL_NUM(acl) == 0)
1482  {
1483  *roleids = NULL;
1484  return 0;
1485  }
1486 
1487  check_acl(acl);
1488 
1489  /* Allocate the worst-case space requirement */
1490  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1491  acldat = ACL_DAT(acl);
1492 
1493  /*
1494  * Walk the ACL collecting mentioned RoleIds.
1495  */
1496  j = 0;
1497  for (i = 0; i < ACL_NUM(acl); i++)
1498  {
1499  const AclItem *ai = &acldat[i];
1500 
1501  if (ai->ai_grantee != ACL_ID_PUBLIC)
1502  list[j++] = ai->ai_grantee;
1503  /* grantor is currently never PUBLIC, but let's check anyway */
1504  if (ai->ai_grantor != ACL_ID_PUBLIC)
1505  list[j++] = ai->ai_grantor;
1506  }
1507 
1508  /* Sort the array */
1509  qsort(list, j, sizeof(Oid), oid_cmp);
1510 
1511  /* Remove duplicates from the array */
1512  k = 0;
1513  for (i = 1; i < j; i++)
1514  {
1515  if (list[k] != list[i])
1516  list[++k] = list[i];
1517  }
1518 
1519  /*
1520  * We could repalloc the array down to minimum size, but it's hardly worth
1521  * it since it's only transient memory.
1522  */
1523  *roleids = list;
1524 
1525  return k + 1;
1526 }
Oid ai_grantee
Definition: acl.h:57
unsigned int Oid
Definition: postgres_ext.h:31
Oid ai_grantor
Definition: acl.h:58
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:336
void * palloc(Size size)
Definition: mcxt.c:835
int i
#define ACL_ID_PUBLIC
Definition: acl.h:47
#define qsort(a, b, c, d)
Definition: port.h:408
static void check_acl(const Acl *acl)
Definition: acl.c:540

◆ aclmerge()

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

Definition at line 451 of file acl.c.

References ACL_DAT, ACL_MODECHG_ADD, ACL_NUM, aclcopy(), aclupdate(), DROP_RESTRICT, i, and pfree().

Referenced by get_user_default_acl().

452 {
453  Acl *result_acl;
454  AclItem *aip;
455  int i,
456  num;
457 
458  /* Check for cases where one or both are empty/null */
459  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
460  {
461  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
462  return NULL;
463  else
464  return aclcopy(right_acl);
465  }
466  else
467  {
468  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
469  return aclcopy(left_acl);
470  }
471 
472  /* Merge them the hard way, one item at a time */
473  result_acl = aclcopy(left_acl);
474 
475  aip = ACL_DAT(right_acl);
476  num = ACL_NUM(right_acl);
477 
478  for (i = 0; i < num; i++, aip++)
479  {
480  Acl *tmp_acl;
481 
482  tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
483  ownerId, DROP_RESTRICT);
484  pfree(result_acl);
485  result_acl = tmp_acl;
486  }
487 
488  return result_acl;
489 }
void pfree(void *pointer)
Definition: mcxt.c:936
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_MODECHG_ADD
Definition: acl.h:130
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:407
int i
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:931

◆ aclnewowner()

Acl* aclnewowner ( const Acl old_acl,
Oid  oldOwnerId,
Oid  newOwnerId 
)

Definition at line 1052 of file acl.c.

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

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

◆ aclupdate()

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

Definition at line 931 of file acl.c.

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(), memmove, recursive_revoke(), and SET_VARSIZE.

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

933 {
934  Acl *new_acl = NULL;
935  AclItem *old_aip,
936  *new_aip = NULL;
937  AclMode old_rights,
938  old_goptions,
939  new_rights,
940  new_goptions;
941  int dst,
942  num;
943 
944  /* Caller probably already checked old_acl, but be safe */
945  check_acl(old_acl);
946 
947  /* If granting grant options, check for circularity */
948  if (modechg != ACL_MODECHG_DEL &&
949  ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS)
950  check_circularity(old_acl, mod_aip, ownerId);
951 
952  num = ACL_NUM(old_acl);
953  old_aip = ACL_DAT(old_acl);
954 
955  /*
956  * Search the ACL for an existing entry for this grantee and grantor. If
957  * one exists, just modify the entry in-place (well, in the same position,
958  * since we actually return a copy); otherwise, insert the new entry at
959  * the end.
960  */
961 
962  for (dst = 0; dst < num; ++dst)
963  {
964  if (aclitem_match(mod_aip, old_aip + dst))
965  {
966  /* found a match, so modify existing item */
967  new_acl = allocacl(num);
968  new_aip = ACL_DAT(new_acl);
969  memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
970  break;
971  }
972  }
973 
974  if (dst == num)
975  {
976  /* need to append a new item */
977  new_acl = allocacl(num + 1);
978  new_aip = ACL_DAT(new_acl);
979  memcpy(new_aip, old_aip, num * sizeof(AclItem));
980 
981  /* initialize the new entry with no permissions */
982  new_aip[dst].ai_grantee = mod_aip->ai_grantee;
983  new_aip[dst].ai_grantor = mod_aip->ai_grantor;
984  ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
986  num++; /* set num to the size of new_acl */
987  }
988 
989  old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
990  old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
991 
992  /* apply the specified permissions change */
993  switch (modechg)
994  {
995  case ACL_MODECHG_ADD:
996  ACLITEM_SET_RIGHTS(new_aip[dst],
997  old_rights | ACLITEM_GET_RIGHTS(*mod_aip));
998  break;
999  case ACL_MODECHG_DEL:
1000  ACLITEM_SET_RIGHTS(new_aip[dst],
1001  old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
1002  break;
1003  case ACL_MODECHG_EQL:
1004  ACLITEM_SET_RIGHTS(new_aip[dst],
1005  ACLITEM_GET_RIGHTS(*mod_aip));
1006  break;
1007  }
1008 
1009  new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1010  new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1011 
1012  /*
1013  * If the adjusted entry has no permissions, delete it from the list.
1014  */
1015  if (new_rights == ACL_NO_RIGHTS)
1016  {
1017  memmove(new_aip + dst,
1018  new_aip + dst + 1,
1019  (num - dst - 1) * sizeof(AclItem));
1020  /* Adjust array size to be 'num - 1' items */
1021  ARR_DIMS(new_acl)[0] = num - 1;
1022  SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1023  }
1024 
1025  /*
1026  * Remove abandoned privileges (cascading revoke). Currently we can only
1027  * handle this when the grantee is not PUBLIC.
1028  */
1029  if ((old_goptions & ~new_goptions) != 0)
1030  {
1031  Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1032  new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1033  (old_goptions & ~new_goptions),
1034  ownerId, behavior);
1035  }
1036 
1037  return new_acl;
1038 }
Oid ai_grantee
Definition: acl.h:57
#define ACL_MODECHG_EQL
Definition: acl.h:132
#define ACLITEM_GET_GOPTIONS(item)
Definition: acl.h:68
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_MODECHG_DEL
Definition: acl.h:131
#define ACL_SIZE(ACL)
Definition: acl.h:112
Oid ai_grantor
Definition: acl.h:58
uint32 AclMode
Definition: parsenodes.h:70
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1155
#define ARR_DIMS(a)
Definition: array.h:279
#define ACL_NUM(ACL)
Definition: acl.h:109
#define ACL_NO_RIGHTS
Definition: parsenodes.h:86
#define memmove(d, s, c)
Definition: c.h:1069
#define ACLITEM_GET_RIGHTS(item)
Definition: acl.h:69
#define ACLITEM_SET_RIGHTS(item, rights)
Definition: acl.h:80
#define ACL_MODECHG_ADD
Definition: acl.h:130
#define ACL_DAT(ACL)
Definition: acl.h:110
Definition: acl.h:55
#define Assert(condition)
Definition: c.h:680
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition: acl.c:658
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition: acl.c:1235
#define ACL_ID_PUBLIC
Definition: acl.h:47
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
#define ACL_N_SIZE(N)
Definition: acl.h:111
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:83
static void check_acl(const Acl *acl)
Definition: acl.c:540

◆ check_is_member_of_role()

void check_is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4879 of file acl.c.

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

4880 {
4881  if (!is_member_of_role(member, role))
4882  ereport(ERROR,
4883  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4884  errmsg("must be member of role \"%s\"",
4885  GetUserNameFromId(role, false))));
4886 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4857
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:692
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ check_rolespec_name()

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

Definition at line 5253 of file acl.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, IsReservedName(), RoleSpec::rolename, ROLESPEC_CSTRING, and RoleSpec::roletype.

Referenced by AlterRole(), and AlterRoleSet().

5254 {
5255  if (!role)
5256  return;
5257 
5258  if (role->roletype != ROLESPEC_CSTRING)
5259  return;
5260 
5261  if (IsReservedName(role->rolename))
5262  {
5263  if (detail_msg)
5264  ereport(ERROR,
5265  (errcode(ERRCODE_RESERVED_NAME),
5266  errmsg("role name \"%s\" is reserved",
5267  role->rolename),
5268  errdetail("%s", detail_msg)));
5269  else
5270  ereport(ERROR,
5271  (errcode(ERRCODE_RESERVED_NAME),
5272  errmsg("role name \"%s\" is reserved",
5273  role->rolename)));
5274  }
5275 }
int errcode(int sqlerrcode)
Definition: elog.c:575
bool IsReservedName(const char *name)
Definition: catalog.c:194
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
RoleSpecType roletype
Definition: parsenodes.h:327
char * rolename
Definition: parsenodes.h:328
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

Definition at line 913 of file aclchk.c.

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_NAMESPACE, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_OBJECT_FUNCTION, ACL_OBJECT_NAMESPACE, ACL_OBJECT_PROCEDURE, ACL_OBJECT_RELATION, ACL_OBJECT_ROUTINE, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, generate_unaccent_rules::action, AlterDefaultPrivilegesStmt::action, InternalDefaultACL::all_privs, DefElem::arg, InternalDefaultACL::behavior, GrantStmt::behavior, check_is_member_of_role(), AccessPriv::cols, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, get_rolespec_oid(), gettext_noop, GetUserId(), InternalDefaultACL::grant_option, GrantStmt::grant_option, InternalDefaultACL::grantees, GrantStmt::grantees, InternalDefaultACL::is_grant, GrantStmt::is_grant, lappend_oid(), lfirst, DefElem::location, NIL, InternalDefaultACL::objtype, GrantStmt::objtype, AlterDefaultPrivilegesStmt::options, parser_errposition(), AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, GrantStmt::privileges, InternalDefaultACL::roleid, ROLESPEC_PUBLIC, RoleSpec::roletype, SetDefaultACLsInSchemas(), and string_to_privilege().

Referenced by ProcessUtilitySlow().

914 {
915  GrantStmt *action = stmt->action;
916  InternalDefaultACL iacls;
917  ListCell *cell;
918  List *rolespecs = NIL;
919  List *nspnames = NIL;
920  DefElem *drolespecs = NULL;
921  DefElem *dnspnames = NULL;
922  AclMode all_privileges;
923  const char *errormsg;
924 
925  /* Deconstruct the "options" part of the statement */
926  foreach(cell, stmt->options)
927  {
928  DefElem *defel = (DefElem *) lfirst(cell);
929 
930  if (strcmp(defel->defname, "schemas") == 0)
931  {
932  if (dnspnames)
933  ereport(ERROR,
934  (errcode(ERRCODE_SYNTAX_ERROR),
935  errmsg("conflicting or redundant options"),
936  parser_errposition(pstate, defel->location)));
937  dnspnames = defel;
938  }
939  else if (strcmp(defel->defname, "roles") == 0)
940  {
941  if (drolespecs)
942  ereport(ERROR,
943  (errcode(ERRCODE_SYNTAX_ERROR),
944  errmsg("conflicting or redundant options"),
945  parser_errposition(pstate, defel->location)));
946  drolespecs = defel;
947  }
948  else
949  elog(ERROR, "option \"%s\" not recognized", defel->defname);
950  }
951 
952  if (dnspnames)
953  nspnames = (List *) dnspnames->arg;
954  if (drolespecs)
955  rolespecs = (List *) drolespecs->arg;
956 
957  /* Prepare the InternalDefaultACL representation of the statement */
958  /* roleid to be filled below */
959  /* nspid to be filled in SetDefaultACLsInSchemas */
960  iacls.is_grant = action->is_grant;
961  iacls.objtype = action->objtype;
962  /* all_privs to be filled below */
963  /* privileges to be filled below */
964  iacls.grantees = NIL; /* filled below */
965  iacls.grant_option = action->grant_option;
966  iacls.behavior = action->behavior;
967 
968  /*
969  * Convert the RoleSpec list into an Oid list. Note that at this point we
970  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
971  * there shouldn't be any additional work needed to support this case.
972  */
973  foreach(cell, action->grantees)
974  {
975  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
976  Oid grantee_uid;
977 
978  switch (grantee->roletype)
979  {
980  case ROLESPEC_PUBLIC:
981  grantee_uid = ACL_ID_PUBLIC;
982  break;
983  default:
984  grantee_uid = get_rolespec_oid(grantee, false);
985  break;
986  }
987  iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
988  }
989 
990  /*
991  * Convert action->privileges, a list of privilege strings, into an
992  * AclMode bitmask.
993  */
994  switch (action->objtype)
995  {
996  case ACL_OBJECT_RELATION:
997  all_privileges = ACL_ALL_RIGHTS_RELATION;
998  errormsg = gettext_noop("invalid privilege type %s for relation");
999  break;
1000  case ACL_OBJECT_SEQUENCE:
1001  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
1002  errormsg = gettext_noop("invalid privilege type %s for sequence");
1003  break;
1004  case ACL_OBJECT_FUNCTION:
1005  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1006  errormsg = gettext_noop("invalid privilege type %s for function");
1007  break;
1008  case ACL_OBJECT_PROCEDURE:
1009  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1010  errormsg = gettext_noop("invalid privilege type %s for procedure");
1011  break;
1012  case ACL_OBJECT_ROUTINE:
1013  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1014  errormsg = gettext_noop("invalid privilege type %s for routine");
1015  break;
1016  case ACL_OBJECT_TYPE:
1017  all_privileges = ACL_ALL_RIGHTS_TYPE;
1018  errormsg = gettext_noop("invalid privilege type %s for type");
1019  break;
1020  case ACL_OBJECT_NAMESPACE:
1021  all_privileges = ACL_ALL_RIGHTS_NAMESPACE;
1022  errormsg = gettext_noop("invalid privilege type %s for schema");
1023  break;
1024  default:
1025  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1026  (int) action->objtype);
1027  /* keep compiler quiet */
1028  all_privileges = ACL_NO_RIGHTS;
1029  errormsg = NULL;
1030  }
1031 
1032  if (action->privileges == NIL)
1033  {
1034  iacls.all_privs = true;
1035 
1036  /*
1037  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1038  * depending on the object type
1039  */
1040  iacls.privileges = ACL_NO_RIGHTS;
1041  }
1042  else
1043  {
1044  iacls.all_privs = false;
1045  iacls.privileges = ACL_NO_RIGHTS;
1046 
1047  foreach(cell, action->privileges)
1048  {
1049  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1050  AclMode priv;
1051 
1052  if (privnode->cols)
1053  ereport(ERROR,
1054  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1055  errmsg("default privileges cannot be set for columns")));
1056 
1057  if (privnode->priv_name == NULL) /* parser mistake? */
1058  elog(ERROR, "AccessPriv node must specify privilege");
1059  priv = string_to_privilege(privnode->priv_name);
1060 
1061  if (priv & ~((AclMode) all_privileges))
1062  ereport(ERROR,
1063  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1064  errmsg(errormsg, privilege_to_string(priv))));
1065 
1066  iacls.privileges |= priv;
1067  }
1068  }
1069 
1070  if (rolespecs == NIL)
1071  {
1072  /* Set permissions for myself */
1073  iacls.roleid = GetUserId();
1074 
1075  SetDefaultACLsInSchemas(&iacls, nspnames);
1076  }
1077  else
1078  {
1079  /* Look up the role OIDs and do permissions checks */
1080  ListCell *rolecell;
1081 
1082  foreach(rolecell, rolespecs)
1083  {
1084  RoleSpec *rolespec = lfirst(rolecell);
1085 
1086  iacls.roleid = get_rolespec_oid(rolespec, false);
1087 
1088  /*
1089  * We insist that calling user be a member of each target role. If
1090  * he has that, he could become that role anyway via SET ROLE, so
1091  * FOR ROLE is just a syntactic convenience and doesn't give any
1092  * special privileges.
1093  */
1095 
1096  SetDefaultACLsInSchemas(&iacls, nspnames);
1097  }
1098  }
1099 }
#define NIL
Definition: pg_list.h:69
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:163
bool grant_option
Definition: aclchk.c:93
Oid GetUserId(void)
Definition: miscinit.c:284
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:3273
bool grant_option
Definition: parsenodes.h:1878
#define gettext_noop(x)
Definition: c.h:1005
int errcode(int sqlerrcode)
Definition: elog.c:575
List * cols
Definition: parsenodes.h:1908
unsigned int Oid
Definition: postgres_ext.h:31
GrantObjectType objtype
Definition: aclchk.c:89
List * grantees
Definition: aclchk.c:92
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
uint32 AclMode
Definition: parsenodes.h:70
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:86
int location
Definition: parsenodes.h:722
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:168
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4879
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:720
#define ACL_ALL_RIGHTS_NAMESPACE
Definition: acl.h:166
bool is_grant
Definition: parsenodes.h:1870
RoleSpecType roletype
Definition: parsenodes.h:327
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5149
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:159
DropBehavior behavior
Definition: aclchk.c:94
List * privileges
Definition: parsenodes.h:1875
DropBehavior behavior
Definition: parsenodes.h:1879
#define lfirst(lc)
Definition: pg_list.h:106
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1107
GrantObjectType objtype
Definition: parsenodes.h:1872
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:158
#define ACL_ID_PUBLIC
Definition: acl.h:47
char * defname
Definition: parsenodes.h:719
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:3310
List * grantees
Definition: parsenodes.h:1877
#define elog
Definition: elog.h:219
AclMode privileges
Definition: aclchk.c:91
Definition: pg_list.h:45
char * priv_name
Definition: parsenodes.h:1907

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 385 of file aclchk.c.

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_NAMESPACE, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_PROCEDURE, ACL_OBJECT_RELATION, ACL_OBJECT_ROUTINE, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, GrantStmt::behavior, InternalGrant::col_privs, AccessPriv::cols, elog, ereport, errcode(), errmsg(), ERROR, ExecGrantStmt_oids(), get_rolespec_oid(), gettext_noop, InternalGrant::grant_option, GrantStmt::grant_option, InternalGrant::grantees, GrantStmt::grantees, InternalGrant::is_grant, GrantStmt::is_grant, lappend(), lappend_oid(), lfirst, NIL, objectNamesToOids(), InternalGrant::objects, GrantStmt::objects, objectsInSchemaToOids(), InternalGrant::objtype, GrantStmt::objtype, AccessPriv::priv_name, privilege_to_string(), InternalGrant::privileges, GrantStmt::privileges, ROLESPEC_PUBLIC, RoleSpec::roletype, string_to_privilege(), and GrantStmt::targtype.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

386 {
387  InternalGrant istmt;
388  ListCell *cell;
389  const char *errormsg;
390  AclMode all_privileges;
391 
392  /*
393  * Turn the regular GrantStmt into the InternalGrant form.
394  */
395  istmt.is_grant = stmt->is_grant;
396  istmt.objtype = stmt->objtype;
397 
398  /* Collect the OIDs of the target objects */
399  switch (stmt->targtype)
400  {
401  case ACL_TARGET_OBJECT:
402  istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
403  break;
405  istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
406  break;
407  /* ACL_TARGET_DEFAULTS should not be seen here */
408  default:
409  elog(ERROR, "unrecognized GrantStmt.targtype: %d",
410  (int) stmt->targtype);
411  }
412 
413  /* all_privs to be filled below */
414  /* privileges to be filled below */
415  istmt.col_privs = NIL; /* may get filled below */
416  istmt.grantees = NIL; /* filled below */
417  istmt.grant_option = stmt->grant_option;
418  istmt.behavior = stmt->behavior;
419 
420  /*
421  * Convert the RoleSpec list into an Oid list. Note that at this point we
422  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
423  * there shouldn't be any additional work needed to support this case.
424  */
425  foreach(cell, stmt->grantees)
426  {
427  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
428  Oid grantee_uid;
429 
430  switch (grantee->roletype)
431  {
432  case ROLESPEC_PUBLIC:
433  grantee_uid = ACL_ID_PUBLIC;
434  break;
435  default:
436  grantee_uid = get_rolespec_oid(grantee, false);
437  break;
438  }
439  istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
440  }
441 
442  /*
443  * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
444  * bitmask. Note: objtype can't be ACL_OBJECT_COLUMN.
445  */
446  switch (stmt->objtype)
447  {
448  /*
449  * Because this might be a sequence, we test both relation and
450  * sequence bits, and later do a more limited test when we know
451  * the object type.
452  */
453  case ACL_OBJECT_RELATION:
455  errormsg = gettext_noop("invalid privilege type %s for relation");
456  break;
457  case ACL_OBJECT_SEQUENCE:
458  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
459  errormsg = gettext_noop("invalid privilege type %s for sequence");
460  break;
461  case ACL_OBJECT_DATABASE:
462  all_privileges = ACL_ALL_RIGHTS_DATABASE;
463  errormsg = gettext_noop("invalid privilege type %s for database");
464  break;
465  case ACL_OBJECT_DOMAIN:
466  all_privileges = ACL_ALL_RIGHTS_TYPE;
467  errormsg = gettext_noop("invalid privilege type %s for domain");
468  break;
469  case ACL_OBJECT_FUNCTION:
470  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
471  errormsg = gettext_noop("invalid privilege type %s for function");
472  break;
473  case ACL_OBJECT_LANGUAGE:
474  all_privileges = ACL_ALL_RIGHTS_LANGUAGE;
475  errormsg = gettext_noop("invalid privilege type %s for language");
476  break;
478  all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
479  errormsg = gettext_noop("invalid privilege type %s for large object");
480  break;
482  all_privileges = ACL_ALL_RIGHTS_NAMESPACE;
483  errormsg = gettext_noop("invalid privilege type %s for schema");
484  break;
486  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
487  errormsg = gettext_noop("invalid privilege type %s for procedure");
488  break;
489  case ACL_OBJECT_ROUTINE:
490  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
491  errormsg = gettext_noop("invalid privilege type %s for routine");
492  break;
494  all_privileges = ACL_ALL_RIGHTS_TABLESPACE;
495  errormsg = gettext_noop("invalid privilege type %s for tablespace");
496  break;
497  case ACL_OBJECT_TYPE:
498  all_privileges = ACL_ALL_RIGHTS_TYPE;
499  errormsg = gettext_noop("invalid privilege type %s for type");
500  break;
501  case ACL_OBJECT_FDW:
502  all_privileges = ACL_ALL_RIGHTS_FDW;
503  errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
504  break;
506  all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER;
507  errormsg = gettext_noop("invalid privilege type %s for foreign server");
508  break;
509  default:
510  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
511  (int) stmt->objtype);
512  /* keep compiler quiet */
513  all_privileges = ACL_NO_RIGHTS;
514  errormsg = NULL;
515  }
516 
517  if (stmt->privileges == NIL)
518  {
519  istmt.all_privs = true;
520 
521  /*
522  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
523  * depending on the object type
524  */
525  istmt.privileges = ACL_NO_RIGHTS;
526  }
527  else
528  {
529  istmt.all_privs = false;
530  istmt.privileges = ACL_NO_RIGHTS;
531 
532  foreach(cell, stmt->privileges)
533  {
534  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
535  AclMode priv;
536 
537  /*
538  * If it's a column-level specification, we just set it aside in
539  * col_privs for the moment; but insist it's for a relation.
540  */
541  if (privnode->cols)
542  {
543  if (stmt->objtype != ACL_OBJECT_RELATION)
544  ereport(ERROR,
545  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
546  errmsg("column privileges are only valid for relations")));
547  istmt.col_privs = lappend(istmt.col_privs, privnode);
548  continue;
549  }
550 
551  if (privnode->priv_name == NULL) /* parser mistake? */
552  elog(ERROR, "AccessPriv node must specify privilege or columns");
553  priv = string_to_privilege(privnode->priv_name);
554 
555  if (priv & ~((AclMode) all_privileges))
556  ereport(ERROR,
557  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
558  errmsg(errormsg, privilege_to_string(priv))));
559 
560  istmt.privileges |= priv;
561  }
562  }
563 
564  ExecGrantStmt_oids(&istmt);
565 }
#define NIL
Definition: pg_list.h:69
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:163
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:3273
AclMode privileges
bool grant_option
Definition: parsenodes.h:1878
#define gettext_noop(x)
Definition: c.h:1005
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:167
List * cols
Definition: parsenodes.h:1908
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
static List * objectsInSchemaToOids(GrantObjectType objtype, List *nspnames)
Definition: aclchk.c:786
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:164
GrantObjectType objtype
uint32 AclMode
Definition: parsenodes.h:70
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:86
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:168
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
#define ACL_ALL_RIGHTS_NAMESPACE
Definition: acl.h:166
bool is_grant
Definition: parsenodes.h:1870
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition: aclchk.c:573
RoleSpecType roletype
Definition: parsenodes.h:327
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5149
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:159
List * privileges
Definition: parsenodes.h:1875
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:165
DropBehavior behavior
DropBehavior behavior
Definition: parsenodes.h:1879
#define lfirst(lc)
Definition: pg_list.h:106
List * objects
Definition: parsenodes.h:1873
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:160
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:162
GrantObjectType objtype
Definition: parsenodes.h:1872
static List * objectNamesToOids(GrantObjectType objtype, List *objnames)
Definition: aclchk.c:637
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:158
#define ACL_ID_PUBLIC
Definition: acl.h:47
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:161
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:3310
List * grantees
Definition: parsenodes.h:1877
#define elog
Definition: elog.h:219
GrantTargetType targtype
Definition: parsenodes.h:1871
char * priv_name
Definition: parsenodes.h:1907

◆ get_role_oid()

Oid get_role_oid ( const char *  rolename,
bool  missing_ok 
)

Definition at line 5116 of file acl.c.

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

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

5117 {
5118  Oid oid;
5119 
5120  oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname));
5121  if (!OidIsValid(oid) && !missing_ok)
5122  ereport(ERROR,
5123  (errcode(ERRCODE_UNDEFINED_OBJECT),
5124  errmsg("role \"%s\" does not exist", rolname)));
5125  return oid;
5126 }
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:586
#define GetSysCacheOid1(cacheId, key1)
Definition: syscache.h:191
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5231 of file acl.c.

References get_rolespec_tuple(), GETSTRUCT, NameStr, pstrdup(), and ReleaseSysCache().

Referenced by AddRoleMems(), and DelRoleMems().

5232 {
5233  HeapTuple tp;
5234  Form_pg_authid authForm;
5235  char *rolename;
5236 
5237  tp = get_rolespec_tuple(role);
5238  authForm = (Form_pg_authid) GETSTRUCT(tp);
5239  rolename = pstrdup(NameStr(authForm->rolname));
5240  ReleaseSysCache(tp);
5241 
5242  return rolename;
5243 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
char * pstrdup(const char *in)
Definition: mcxt.c:1063
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5187
#define NameStr(name)
Definition: c.h:557

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

Definition at line 5149 of file acl.c.

References Assert, elog, ereport, errcode(), errmsg(), ERROR, get_role_oid(), GetSessionUserId(), GetUserId(), InvalidOid, RoleSpec::rolename, ROLESPEC_CSTRING, 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().

5150 {
5151  Oid oid;
5152 
5153  switch (role->roletype)
5154  {
5155  case ROLESPEC_CSTRING:
5156  Assert(role->rolename);
5157  oid = get_role_oid(role->rolename, missing_ok);
5158  break;
5159 
5160  case ROLESPEC_CURRENT_USER:
5161  oid = GetUserId();
5162  break;
5163 
5164  case ROLESPEC_SESSION_USER:
5165  oid = GetSessionUserId();
5166  break;
5167 
5168  case ROLESPEC_PUBLIC:
5169  ereport(ERROR,
5170  (errcode(ERRCODE_UNDEFINED_OBJECT),
5171  errmsg("role \"%s\" does not exist", "public")));
5172  oid = InvalidOid; /* make compiler happy */
5173  break;
5174 
5175  default:
5176  elog(ERROR, "unexpected role type %d", role->roletype);
5177  }
5178 
5179  return oid;
5180 }
Oid GetUserId(void)
Definition: miscinit.c:284
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:318
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5116
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
RoleSpecType roletype
Definition: parsenodes.h:327
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:680
char * rolename
Definition: parsenodes.h:328
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

Definition at line 5187 of file acl.c.

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

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

5188 {
5189  HeapTuple tuple;
5190 
5191  switch (role->roletype)
5192  {
5193  case ROLESPEC_CSTRING:
5194  Assert(role->rolename);
5196  if (!HeapTupleIsValid(tuple))
5197  ereport(ERROR,
5198  (errcode(ERRCODE_UNDEFINED_OBJECT),
5199  errmsg("role \"%s\" does not exist", role->rolename)));
5200  break;
5201 
5202  case ROLESPEC_CURRENT_USER:
5203  tuple = SearchSysCache1(AUTHOID, GetUserId());
5204  if (!HeapTupleIsValid(tuple))
5205  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5206  break;
5207 
5208  case ROLESPEC_SESSION_USER:
5210  if (!HeapTupleIsValid(tuple))
5211  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5212  break;
5213 
5214  case ROLESPEC_PUBLIC:
5215  ereport(ERROR,
5216  (errcode(ERRCODE_UNDEFINED_OBJECT),
5217  errmsg("role \"%s\" does not exist", "public")));
5218  tuple = NULL; /* make compiler happy */
5219 
5220  default:
5221  elog(ERROR, "unexpected role type %d", role->roletype);
5222  }
5223 
5224  return tuple;
5225 }
Oid GetUserId(void)
Definition: miscinit.c:284
int errcode(int sqlerrcode)
Definition: elog.c:575
Oid GetSessionUserId(void)
Definition: miscinit.c:318
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:584
#define ereport(elevel, rest)
Definition: elog.h:122
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
RoleSpecType roletype
Definition: parsenodes.h:327
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:680
char * rolename
Definition: parsenodes.h:328
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219

◆ get_user_default_acl()

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

Definition at line 5304 of file aclchk.c.

References ACL_OBJECT_FUNCTION, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, acldefault(), aclequal(), aclitemsort(), aclmerge(), DEFACLOBJ_FUNCTION, DEFACLOBJ_NAMESPACE, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, get_default_acl_internal(), InvalidOid, and IsBootstrapProcessingMode.

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

5305 {
5306  Acl *result;
5307  Acl *glob_acl;
5308  Acl *schema_acl;
5309  Acl *def_acl;
5310  char defaclobjtype;
5311 
5312  /*
5313  * Use NULL during bootstrap, since pg_default_acl probably isn't there
5314  * yet.
5315  */
5317  return NULL;
5318 
5319  /* Check if object type is supported in pg_default_acl */
5320  switch (objtype)
5321  {
5322  case ACL_OBJECT_RELATION:
5323  defaclobjtype = DEFACLOBJ_RELATION;
5324  break;
5325 
5326  case ACL_OBJECT_SEQUENCE:
5327  defaclobjtype = DEFACLOBJ_SEQUENCE;
5328  break;
5329 
5330  case ACL_OBJECT_FUNCTION:
5331  defaclobjtype = DEFACLOBJ_FUNCTION;
5332  break;
5333 
5334  case ACL_OBJECT_TYPE:
5335  defaclobjtype = DEFACLOBJ_TYPE;
5336  break;
5337 
5338  case ACL_OBJECT_NAMESPACE:
5339  defaclobjtype = DEFACLOBJ_NAMESPACE;
5340  break;
5341 
5342  default:
5343  return NULL;
5344  }
5345 
5346  /* Look up the relevant pg_default_acl entries */
5347  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5348  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5349 
5350  /* Quick out if neither entry exists */
5351  if (glob_acl == NULL && schema_acl == NULL)
5352  return NULL;
5353 
5354  /* We need to know the hard-wired default value, too */
5355  def_acl = acldefault(objtype, ownerId);
5356 
5357  /* If there's no global entry, substitute the hard-wired default */
5358  if (glob_acl == NULL)
5359  glob_acl = def_acl;
5360 
5361  /* Merge in any per-schema privileges */
5362  result = aclmerge(glob_acl, schema_acl, ownerId);
5363 
5364  /*
5365  * For efficiency, we want to return NULL if the result equals default.
5366  * This requires sorting both arrays to get an accurate comparison.
5367  */
5368  aclitemsort(result);
5369  aclitemsort(def_acl);
5370  if (aclequal(result, def_acl))
5371  result = NULL;
5372 
5373  return result;
5374 }
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:5272
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:509
#define DEFACLOBJ_SEQUENCE
#define DEFACLOBJ_TYPE
#define InvalidOid
Definition: postgres_ext.h:36
#define DEFACLOBJ_NAMESPACE
#define DEFACLOBJ_RELATION
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:451
#define DEFACLOBJ_FUNCTION
void aclitemsort(Acl *acl)
Definition: acl.c:495
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 5248 of file aclchk.c.

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

Referenced by check_enable_rls(), and RI_Initial_Check().

5249 {
5250  bool result = false;
5251  HeapTuple utup;
5252 
5253  /* Superusers bypass all permission checking. */
5254  if (superuser_arg(roleid))
5255  return true;
5256 
5257  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5258  if (HeapTupleIsValid(utup))
5259  {
5260  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
5261  ReleaseSysCache(utup);
5262  }
5263  return result;
5264 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 5229 of file aclchk.c.

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

Referenced by check_object_ownership(), and have_createrole_privilege().

5230 {
5231  bool result = false;
5232  HeapTuple utup;
5233 
5234  /* Superusers bypass all permission checking. */
5235  if (superuser_arg(roleid))
5236  return true;
5237 
5238  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5239  if (HeapTupleIsValid(utup))
5240  {
5241  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
5242  ReleaseSysCache(utup);
5243  }
5244  return result;
5245 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4833 of file acl.c.

References list_member_oid(), roles_has_privs_of(), and superuser_arg().

Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), check_role_for_policy(), DropOwnedObjects(), 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_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_publication_ownercheck(), pg_role_aclcheck(), pg_signal_backend(), pg_stat_get_activity(), pg_stat_get_backend_activity(), pg_stat_get_backend_activity_start(), pg_stat_get_backend_client_addr(), pg_stat_get_backend_client_port(), pg_stat_get_backend_start(), pg_stat_get_backend_wait_event(), pg_stat_get_backend_wait_event_type(), pg_stat_get_backend_xact_start(), pg_stat_get_progress_info(), pg_statistics_object_ownercheck(), pg_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), and ReassignOwnedObjects().

4834 {
4835  /* Fast path for simple case */
4836  if (member == role)
4837  return true;
4838 
4839  /* Superusers have every privilege, so are part of every role */
4840  if (superuser_arg(member))
4841  return true;
4842 
4843  /*
4844  * Find all the roles that member has the privileges of, including
4845  * multi-level recursion, then see if target role is any one of them.
4846  */
4847  return list_member_oid(roles_has_privs_of(member), role);
4848 }
static List * roles_has_privs_of(Oid roleid)
Definition: acl.c:4673
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4614 of file acl.c.

References AUTHMEMROLEMEM, CacheRegisterSyscacheCallback(), IsBootstrapProcessingMode, and RoleMembershipCacheCallback().

Referenced by InitPostgres().

4615 {
4617  {
4618  /*
4619  * In normal mode, set a callback on any syscache invalidation of
4620  * pg_auth_members rows
4621  */
4624  (Datum) 0);
4625  }
4626 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1389
uintptr_t Datum
Definition: postgres.h:372
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4633
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:367

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 4915 of file acl.c.

References AUTHMEMMEMROLE, GetSessionUserId(), GETSTRUCT, i, InLocalUserIdChange(), InSecurityRestrictedOperation(), lfirst_oid, list_append_unique_oid(), list_free(), list_make1_oid, catclist::members, catclist::n_members, ObjectIdGetDatum, ReleaseSysCacheList, SearchSysCacheList1, superuser_arg(), and catctup::tuple.

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

4916 {
4917  bool result = false;
4918  List *roles_list;
4919  ListCell *l;
4920 
4921  if (superuser_arg(member))
4922  return true;
4923 
4924  if (member == role)
4925 
4926  /*
4927  * A role can admin itself when it matches the session user and we're
4928  * outside any security-restricted operation, SECURITY DEFINER or
4929  * similar context. SQL-standard roles cannot self-admin. However,
4930  * SQL-standard users are distinct from roles, and they are not
4931  * grantable like roles: PostgreSQL's role-user duality extends the
4932  * standard. Checking for a session user match has the effect of
4933  * letting a role self-admin only when it's conspicuously behaving
4934  * like a user. Note that allowing self-admin under a mere SET ROLE
4935  * would make WITH ADMIN OPTION largely irrelevant; any member could
4936  * SET ROLE to issue the otherwise-forbidden command.
4937  *
4938  * Withholding self-admin in a security-restricted operation prevents
4939  * object owners from harnessing the session user identity during
4940  * administrative maintenance. Suppose Alice owns a database, has
4941  * issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
4942  * an alice-owned SECURITY DEFINER function that issues "REVOKE alice
4943  * FROM carol". If he creates an expression index calling that
4944  * function, Alice will attempt the REVOKE during each ANALYZE.
4945  * Checking InSecurityRestrictedOperation() thwarts that attack.
4946  *
4947  * Withholding self-admin in SECURITY DEFINER functions makes their
4948  * behavior independent of the calling user. There's no security or
4949  * SQL-standard-conformance need for that restriction, though.
4950  *
4951  * A role cannot have actual WITH ADMIN OPTION on itself, because that
4952  * would imply a membership loop. Therefore, we're done either way.
4953  */
4954  return member == GetSessionUserId() &&
4956 
4957  /*
4958  * Find all the roles that member is a member of, including multi-level
4959  * recursion. We build a list in the same way that is_member_of_role does
4960  * to track visited and unvisited roles.
4961  */
4962  roles_list = list_make1_oid(member);
4963 
4964  foreach(l, roles_list)
4965  {
4966  Oid memberid = lfirst_oid(l);
4967  CatCList *memlist;
4968  int i;
4969 
4970  /* Find roles that memberid is directly a member of */
4972  ObjectIdGetDatum(memberid));
4973  for (i = 0; i < memlist->n_members; i++)
4974  {
4975  HeapTuple tup = &memlist->members[i]->tuple;
4976  Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid;
4977 
4978  if (otherid == role &&
4979  ((Form_pg_auth_members) GETSTRUCT(tup))->admin_option)
4980  {
4981  /* Found what we came for, so can stop searching */
4982  result = true;
4983  break;
4984  }
4985 
4986  roles_list = list_append_unique_oid(roles_list, otherid);
4987  }
4988  ReleaseSysCacheList(memlist);
4989  if (result)
4990  break;
4991  }
4992 
4993  list_free(roles_list);
4994 
4995  return result;
4996 }
bool InLocalUserIdChange(void)
Definition: miscinit.c:407
int n_members
Definition: catcache.h:176
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:999
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:318
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:209
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define ReleaseSysCacheList(x)
Definition: syscache.h:218
#define list_make1_oid(x1)
Definition: pg_list.h:151
FormData_pg_auth_members * Form_pg_auth_members
bool InSecurityRestrictedOperation(void)
Definition: miscinit.c:416
void list_free(List *list)
Definition: list.c:1133
int i
HeapTupleData tuple
Definition: catcache.h:121
Definition: pg_list.h:45
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4857 of file acl.c.

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

Referenced by calculate_database_size(), calculate_tablespace_size(), check_is_member_of_role(), check_role(), GetConfigOption(), GetConfigOptionByName(), GetConfigOptionByNum(), GetConfigOptionResetString(), pg_role_aclcheck(), pg_stat_get_activity(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), and pgrowlocks().

4858 {
4859  /* Fast path for simple case */
4860  if (member == role)
4861  return true;
4862 
4863  /* Superusers have every privilege, so are part of every role */
4864  if (superuser_arg(member))
4865  return true;
4866 
4867  /*
4868  * Find all the roles that member is a member of, including multi-level
4869  * recursion, then see if target role is any one of them.
4870  */
4871  return list_member_oid(roles_is_member_of(member), role);
4872 }
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4756
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)

Definition at line 4895 of file acl.c.

References list_member_oid(), and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

4896 {
4897  /* Fast path for simple case */
4898  if (member == role)
4899  return true;
4900 
4901  /*
4902  * Find all the roles that member is a member of, including multi-level
4903  * recursion, then see if target role is any one of them.
4904  */
4905  return list_member_oid(roles_is_member_of(member), role);
4906 }
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4756
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:505

◆ make_empty_acl()

Acl* make_empty_acl ( void  )

Definition at line 398 of file acl.c.

References allocacl().

Referenced by SetDefaultACL().

399 {
400  return allocacl(0);
401 }
static Acl * allocacl(int n)
Definition: acl.c:376

◆ pg_attribute_aclcheck()

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

Definition at line 4366 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, and pg_attribute_aclmask().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), column_privilege_check(), examine_simple_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckRTEPerms(), ExecCheckRTEPermsModified(), and ri_ReportViolation().

4368 {
4369  if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0)
4370  return ACLCHECK_OK;
4371  else
4372  return ACLCHECK_NO_PRIV;
4373 }
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3595

◆ pg_attribute_aclcheck_all()

AclResult pg_attribute_aclcheck_all ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how 
)

Definition at line 4395 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ALL, ACLMASK_ANY, Anum_pg_attribute_attacl, ATTNUM, GETSTRUCT, heap_attisnull(), HeapTupleIsValid, Int16GetDatum, 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(), and has_any_column_privilege_name_name().

4397 {
4398  AclResult result;
4399  HeapTuple classTuple;
4400  Form_pg_class classForm;
4401  AttrNumber nattrs;
4402  AttrNumber curr_att;
4403 
4404  /*
4405  * Must fetch pg_class row to check number of attributes. As in
4406  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4407  * throwing an error if we get any unexpected lookup errors.
4408  */
4409  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4410  if (!HeapTupleIsValid(classTuple))
4411  return ACLCHECK_NO_PRIV;
4412  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4413 
4414  nattrs = classForm->relnatts;
4415 
4416  ReleaseSysCache(classTuple);
4417 
4418  /*
4419  * Initialize result in case there are no non-dropped columns. We want to
4420  * report failure in such cases for either value of 'how'.
4421  */
4422  result = ACLCHECK_NO_PRIV;
4423 
4424  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4425  {
4426  HeapTuple attTuple;
4427  AclMode attmask;
4428 
4429  attTuple = SearchSysCache2(ATTNUM,
4430  ObjectIdGetDatum(table_oid),
4431  Int16GetDatum(curr_att));
4432  if (!HeapTupleIsValid(attTuple))
4433  continue;
4434 
4435  /* ignore dropped columns */
4436  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4437  {
4438  ReleaseSysCache(attTuple);
4439  continue;
4440  }
4441 
4442  /*
4443  * Here we hard-wire knowledge that the default ACL for a column
4444  * grants no privileges, so that we can fall out quickly in the very
4445  * common case where attacl is null.
4446  */
4448  attmask = 0;
4449  else
4450  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4451  mode, ACLMASK_ANY);
4452 
4453  ReleaseSysCache(attTuple);
4454 
4455  if (attmask != 0)
4456  {
4457  result = ACLCHECK_OK;
4458  if (how == ACLMASK_ANY)
4459  break; /* succeed on any success */
4460  }
4461  else
4462  {
4463  result = ACLCHECK_NO_PRIV;
4464  if (how == ACLMASK_ALL)
4465  break; /* fail on any failure */
4466  }
4467  }
4468 
4469  return result;
4470 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3595
#define Int16GetDatum(X)
Definition: postgres.h:457
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:214
uint32 AclMode
Definition: parsenodes.h:70
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:296
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
AclResult
Definition: acl.h:178
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int16 AttrNumber
Definition: attnum.h:21

◆ pg_attribute_aclmask()

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

Definition at line 3595 of file aclchk.c.

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

Referenced by pg_aclmask(), pg_attribute_aclcheck(), and pg_attribute_aclcheck_all().

3597 {
3598  AclMode result;
3599  HeapTuple classTuple;
3600  HeapTuple attTuple;
3601  Form_pg_class classForm;
3602  Form_pg_attribute attributeForm;
3603  Datum aclDatum;
3604  bool isNull;
3605  Acl *acl;
3606  Oid ownerId;
3607 
3608  /*
3609  * First, get the column's ACL from its pg_attribute entry
3610  */
3611  attTuple = SearchSysCache2(ATTNUM,
3612  ObjectIdGetDatum(table_oid),
3613  Int16GetDatum(attnum));
3614  if (!HeapTupleIsValid(attTuple))
3615  ereport(ERROR,
3616  (errcode(ERRCODE_UNDEFINED_COLUMN),
3617  errmsg("attribute %d of relation with OID %u does not exist",
3618  attnum, table_oid)));
3619  attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
3620 
3621  /* Throw error on dropped columns, too */
3622  if (attributeForm->attisdropped)
3623  ereport(ERROR,
3624  (errcode(ERRCODE_UNDEFINED_COLUMN),
3625  errmsg("attribute %d of relation with OID %u does not exist",
3626  attnum, table_oid)));
3627 
3628  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3629  &isNull);
3630 
3631  /*
3632  * Here we hard-wire knowledge that the default ACL for a column grants no
3633  * privileges, so that we can fall out quickly in the very common case
3634  * where attacl is null.
3635  */
3636  if (isNull)
3637  {
3638  ReleaseSysCache(attTuple);
3639  return 0;
3640  }
3641 
3642  /*
3643  * Must get the relation's ownerId from pg_class. Since we already found
3644  * a pg_attribute entry, the only likely reason for this to fail is that a
3645  * concurrent DROP of the relation committed since then (which could only
3646  * happen if we don't have lock on the relation). We prefer to report "no
3647  * privileges" rather than failing in such a case, so as to avoid unwanted
3648  * failures in has_column_privilege() tests.
3649  */
3650  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3651  if (!HeapTupleIsValid(classTuple))
3652  {
3653  ReleaseSysCache(attTuple);
3654  return 0;
3655  }
3656  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3657 
3658  ownerId = classForm->relowner;
3659 
3660  ReleaseSysCache(classTuple);
3661 
3662  /* detoast column's ACL if necessary */
3663  acl = DatumGetAclP(aclDatum);
3664 
3665  result = aclmask(acl, roleid, ownerId, mask, how);
3666 
3667  /* if we have a detoasted copy, free it */
3668  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3669  pfree(acl);
3670 
3671  ReleaseSysCache(attTuple);
3672 
3673  return result;
3674 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
#define Int16GetDatum(X)
Definition: postgres.h:457
int errcode(int sqlerrcode)
Definition: elog.c:575
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:214
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define ereport(elevel, rest)
Definition: elog.h:122
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1123
#define DatumGetPointer(X)
Definition: postgres.h:555
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_class_aclcheck()

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

Definition at line 4480 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, and pg_class_aclmask().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), column_privilege_check(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), currval_oid(), do_setval(), examine_simple_variable(), examine_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), get_rel_from_relname(), 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(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), lastval(), LockTableAclCheck(), nextval_internal(), pg_prewarm(), pg_sequence_last_value(), pg_sequence_parameters(), pgrowlocks(), ri_ReportViolation(), transformTableLikeClause(), and truncate_check_rel().

4481 {
4482  if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
4483  return ACLCHECK_OK;
4484  else
4485  return ACLCHECK_NO_PRIV;
4486 }
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3680

◆ pg_class_aclmask()

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

Definition at line 3680 of file aclchk.c.

References ACL_DELETE, ACL_INSERT, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), allowSystemTableMods, Anum_pg_class_relacl, DatumGetAclP, DatumGetPointer, DEBUG2, elog, ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, IsSystemClass(), ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELKIND_SEQUENCE, RELKIND_VIEW, RELOID, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by ExecCheckRTEPerms(), pg_aclmask(), and pg_class_aclcheck().

3682 {
3683  AclMode result;
3684  HeapTuple tuple;
3685  Form_pg_class classForm;
3686  Datum aclDatum;
3687  bool isNull;
3688  Acl *acl;
3689  Oid ownerId;
3690 
3691  /*
3692  * Must get the relation's tuple from pg_class
3693  */
3694  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3695  if (!HeapTupleIsValid(tuple))
3696  ereport(ERROR,
3698  errmsg("relation with OID %u does not exist",
3699  table_oid)));
3700  classForm = (Form_pg_class) GETSTRUCT(tuple);
3701 
3702  /*
3703  * Deny anyone permission to update a system catalog unless
3704  * pg_authid.rolsuper is set. Also allow it if allowSystemTableMods.
3705  *
3706  * As of 7.4 we have some updatable system views; those shouldn't be
3707  * protected in this way. Assume the view rules can take care of
3708  * themselves. ACL_USAGE is if we ever have system sequences.
3709  */
3710  if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3711  IsSystemClass(table_oid, classForm) &&
3712  classForm->relkind != RELKIND_VIEW &&
3713  !superuser_arg(roleid) &&
3715  {
3716 #ifdef ACLDEBUG
3717  elog(DEBUG2, "permission denied for system catalog update");
3718 #endif
3720  }
3721 
3722  /*
3723  * Otherwise, superusers bypass all permission-checking.
3724  */
3725  if (superuser_arg(roleid))
3726  {
3727 #ifdef ACLDEBUG
3728  elog(DEBUG2, "OID %u is superuser, home free", roleid);
3729 #endif
3730  ReleaseSysCache(tuple);
3731  return mask;
3732  }
3733 
3734  /*
3735  * Normal case: get the relation's ACL from pg_class
3736  */
3737  ownerId = classForm->relowner;
3738 
3739  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
3740  &isNull);
3741  if (isNull)
3742  {
3743  /* No ACL, so build default ACL */
3744  switch (classForm->relkind)
3745  {
3746  case RELKIND_SEQUENCE:
3747  acl = acldefault(ACL_OBJECT_SEQUENCE, ownerId);
3748  break;
3749  default:
3750  acl = acldefault(ACL_OBJECT_RELATION, ownerId);
3751  break;
3752  }
3753  aclDatum = (Datum) 0;
3754  }
3755  else
3756  {
3757  /* detoast rel's ACL if necessary */
3758  acl = DatumGetAclP(aclDatum);
3759  }
3760 
3761  result = aclmask(acl, roleid, ownerId, mask, how);
3762 
3763  /* if we have a detoasted copy, free it */
3764  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3765  pfree(acl);
3766 
3767  ReleaseSysCache(tuple);
3768 
3769  return result;
3770 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
#define Anum_pg_class_relacl
Definition: pg_class.h:133
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ACL_DELETE
Definition: parsenodes.h:75
unsigned int Oid
Definition: postgres_ext.h:31
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition: catalog.c:75
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define DEBUG2
Definition: elog.h:24
#define ACL_USAGE
Definition: parsenodes.h:80
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
#define ACL_UPDATE
Definition: parsenodes.h:74
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
bool allowSystemTableMods
Definition: globals.c:112
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define ACL_INSERT
Definition: parsenodes.h:72
#define DatumGetPointer(X)
Definition: postgres.h:555
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
#define elog
Definition: elog.h:219
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define ACL_TRUNCATE
Definition: parsenodes.h:76

◆ pg_class_ownercheck()

bool pg_class_ownercheck ( Oid  class_oid,
Oid  roleid 
)

Definition at line 4604 of file aclchk.c.

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

Referenced by AlterTableMoveAll(), analyze_rel(), ATExecChangeOwner(), ATPrepSetStatistics(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), cluster_rel(), CreateStatistics(), DefineQueryRewrite(), EnableDisableRule(), ExecuteTruncate(), get_tables_to_cluster(), gin_clean_pending_list(), MergeAttributes(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), RemoveRoleFromObjectPolicy(), renameatt_check(), RI_Initial_Check(), and vacuum_rel().

4605 {
4606  HeapTuple tuple;
4607  Oid ownerId;
4608 
4609  /* Superusers bypass all permission checking. */
4610  if (superuser_arg(roleid))
4611  return true;
4612 
4613  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
4614  if (!HeapTupleIsValid(tuple))
4615  ereport(ERROR,
4617  errmsg("relation with OID %u does not exist", class_oid)));
4618 
4619  ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
4620 
4621  ReleaseSysCache(tuple);
4622 
4623  return has_privs_of_role(roleid, ownerId);
4624 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_collation_ownercheck()

bool pg_collation_ownercheck ( Oid  coll_oid,
Oid  roleid 
)

Definition at line 5048 of file aclchk.c.

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

5049 {
5050  HeapTuple tuple;
5051  Oid ownerId;
5052 
5053  /* Superusers bypass all permission checking. */
5054  if (superuser_arg(roleid))
5055  return true;
5056 
5057  tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid));
5058  if (!HeapTupleIsValid(tuple))
5059  ereport(ERROR,
5060  (errcode(ERRCODE_UNDEFINED_OBJECT),
5061  errmsg("collation with OID %u does not exist", coll_oid)));
5062 
5063  ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner;
5064 
5065  ReleaseSysCache(tuple);
5066 
5067  return has_privs_of_role(roleid, ownerId);
5068 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:52
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_conversion_ownercheck()

bool pg_conversion_ownercheck ( Oid  conv_oid,
Oid  roleid 
)

Definition at line 5074 of file aclchk.c.

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

Referenced by check_object_ownership().

5075 {
5076  HeapTuple tuple;
5077  Oid ownerId;
5078 
5079  /* Superusers bypass all permission checking. */
5080  if (superuser_arg(roleid))
5081  return true;
5082 
5083  tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid));
5084  if (!HeapTupleIsValid(tuple))
5085  ereport(ERROR,
5086  (errcode(ERRCODE_UNDEFINED_OBJECT),
5087  errmsg("conversion with OID %u does not exist", conv_oid)));
5088 
5089  ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
5090 
5091  ReleaseSysCache(tuple);
5092 
5093  return has_privs_of_role(roleid, ownerId);
5094 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:56
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_database_aclcheck()

◆ pg_database_aclmask()

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

Definition at line 3776 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_database_aclcheck().

3778 {
3779  AclMode result;
3780  HeapTuple tuple;
3781  Datum aclDatum;
3782  bool isNull;
3783  Acl *acl;
3784  Oid ownerId;
3785 
3786  /* Superusers bypass all permission checking. */
3787  if (superuser_arg(roleid))
3788  return mask;
3789 
3790  /*
3791  * Get the database's ACL from pg_database
3792  */
3793  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
3794  if (!HeapTupleIsValid(tuple))
3795  ereport(ERROR,
3796  (errcode(ERRCODE_UNDEFINED_DATABASE),
3797  errmsg("database with OID %u does not exist", db_oid)));
3798 
3799  ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
3800 
3802  &isNull);
3803  if (isNull)
3804  {
3805  /* No ACL, so build default ACL */
3806  acl = acldefault(ACL_OBJECT_DATABASE, ownerId);
3807  aclDatum = (Datum) 0;
3808  }
3809  else
3810  {
3811  /* detoast ACL if necessary */
3812  acl = DatumGetAclP(aclDatum);
3813  }
3814 
3815  result = aclmask(acl, roleid, ownerId, mask, how);
3816 
3817  /* if we have a detoasted copy, free it */
3818  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3819  pfree(acl);
3820 
3821  ReleaseSysCache(tuple);
3822 
3823  return result;
3824 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define Anum_pg_database_datacl
Definition: pg_database.h:76
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:555
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_database_ownercheck()

bool pg_database_ownercheck ( Oid  db_oid,
Oid  roleid 
)

Definition at line 5022 of file aclchk.c.

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

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

5023 {
5024  HeapTuple tuple;
5025  Oid dba;
5026 
5027  /* Superusers bypass all permission checking. */
5028  if (superuser_arg(roleid))
5029  return true;
5030 
5031  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
5032  if (!HeapTupleIsValid(tuple))
5033  ereport(ERROR,
5034  (errcode(ERRCODE_UNDEFINED_DATABASE),
5035  errmsg("database with OID %u does not exist", db_oid)));
5036 
5037  dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
5038 
5039  ReleaseSysCache(tuple);
5040 
5041  return has_privs_of_role(roleid, dba);
5042 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_event_trigger_ownercheck()

bool pg_event_trigger_ownercheck ( Oid  et_oid,
Oid  roleid 
)

Definition at line 4995 of file aclchk.c.

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

4996 {
4997  HeapTuple tuple;
4998  Oid ownerId;
4999 
5000  /* Superusers bypass all permission checking. */
5001  if (superuser_arg(roleid))
5002  return true;
5003 
5005  if (!HeapTupleIsValid(tuple))
5006  ereport(ERROR,
5007  (errcode(ERRCODE_UNDEFINED_OBJECT),
5008  errmsg("event trigger with OID %u does not exist",
5009  et_oid)));
5010 
5011  ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner;
5012 
5013  ReleaseSysCache(tuple);
5014 
5015  return has_privs_of_role(roleid, ownerId);
5016 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_extension_ownercheck()

bool pg_extension_ownercheck ( Oid  ext_oid,
Oid  roleid 
)

Definition at line 5100 of file aclchk.c.

References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, ExtensionOidIndexId, ExtensionRelationId, GETSTRUCT, has_privs_of_role(), heap_close, heap_open(), HeapTupleIsValid, ObjectIdAttributeNumber, ObjectIdGetDatum, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

5101 {
5102  Relation pg_extension;
5103  ScanKeyData entry[1];
5104  SysScanDesc scan;
5105  HeapTuple tuple;
5106  Oid ownerId;
5107 
5108  /* Superusers bypass all permission checking. */
5109  if (superuser_arg(roleid))
5110  return true;
5111 
5112  /* There's no syscache for pg_extension, so do it the hard way */
5114 
5115  ScanKeyInit(&entry[0],
5117  BTEqualStrategyNumber, F_OIDEQ,
5118  ObjectIdGetDatum(ext_oid));
5119 
5120  scan = systable_beginscan(pg_extension,
5121  ExtensionOidIndexId, true,
5122  NULL, 1, entry);
5123 
5124  tuple = systable_getnext(scan);
5125  if (!HeapTupleIsValid(tuple))
5126  ereport(ERROR,
5127  (errcode(ERRCODE_UNDEFINED_OBJECT),
5128  errmsg("extension with OID %u does not exist", ext_oid)));
5129 
5130  ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner;
5131 
5132  systable_endscan(scan);
5133  heap_close(pg_extension, AccessShareLock);
5134 
5135  return has_privs_of_role(roleid, ownerId);
5136 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define ExtensionOidIndexId
Definition: indexing.h:319
FormData_pg_extension * Form_pg_extension
Definition: pg_extension.h:51
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ExtensionRelationId
Definition: pg_extension.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31

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

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

Referenced by pg_aclmask(), and pg_foreign_data_wrapper_aclcheck().

4161 {
4162  AclMode result;
4163  HeapTuple tuple;
4164  Datum aclDatum;
4165  bool isNull;
4166  Acl *acl;
4167  Oid ownerId;
4168 
4170 
4171  /* Bypass permission checks for superusers */
4172  if (superuser_arg(roleid))
4173  return mask;
4174 
4175  /*
4176  * Must get the FDW's tuple from pg_foreign_data_wrapper
4177  */
4179  if (!HeapTupleIsValid(tuple))
4180  ereport(ERROR,
4181  (errcode(ERRCODE_UNDEFINED_OBJECT),
4182  errmsg("foreign-data wrapper with OID %u does not exist",
4183  fdw_oid)));
4184  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
4185 
4186  /*
4187  * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
4188  */
4189  ownerId = fdwForm->fdwowner;
4190 
4191  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
4193  if (isNull)
4194  {
4195  /* No ACL, so build default ACL */
4196  acl = acldefault(ACL_OBJECT_FDW, ownerId);
4197  aclDatum = (Datum) 0;
4198  }
4199  else
4200  {
4201  /* detoast rel's ACL if necessary */
4202  acl = DatumGetAclP(aclDatum);
4203  }
4204 
4205  result = aclmask(acl, roleid, ownerId, mask, how);
4206 
4207  /* if we have a detoasted copy, free it */
4208  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4209  pfree(acl);
4210 
4211  ReleaseSysCache(tuple);
4212 
4213  return result;
4214 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define Anum_pg_foreign_data_wrapper_fdwacl
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
#define DatumGetPointer(X)
Definition: postgres.h:555
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_foreign_data_wrapper_ownercheck()

bool pg_foreign_data_wrapper_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 4941 of file aclchk.c.

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

Referenced by check_object_ownership().

4942 {
4943  HeapTuple tuple;
4944  Oid ownerId;
4945 
4946  /* Superusers bypass all permission checking. */
4947  if (superuser_arg(roleid))
4948  return true;
4949 
4951  if (!HeapTupleIsValid(tuple))
4952  ereport(ERROR,
4953  (errcode(ERRCODE_UNDEFINED_OBJECT),
4954  errmsg("foreign-data wrapper with OID %u does not exist",
4955  srv_oid)));
4956 
4957  ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner;
4958 
4959  ReleaseSysCache(tuple);
4960 
4961  return has_privs_of_role(roleid, ownerId);
4962 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
int errmsg(const char *fmt,...)
Definition: elog.c:797

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

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

Referenced by pg_aclmask(), and pg_foreign_server_aclcheck().

4223 {
4224  AclMode result;
4225  HeapTuple tuple;
4226  Datum aclDatum;
4227  bool isNull;
4228  Acl *acl;
4229  Oid ownerId;
4230 
4231  Form_pg_foreign_server srvForm;
4232 
4233  /* Bypass permission checks for superusers */
4234  if (superuser_arg(roleid))
4235  return mask;
4236 
4237  /*
4238  * Must get the FDW's tuple from pg_foreign_data_wrapper
4239  */
4241  if (!HeapTupleIsValid(tuple))
4242  ereport(ERROR,
4243  (errcode(ERRCODE_UNDEFINED_OBJECT),
4244  errmsg("foreign server with OID %u does not exist",
4245  srv_oid)));
4246  srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
4247 
4248  /*
4249  * Normal case: get the foreign server's ACL from pg_foreign_server
4250  */
4251  ownerId = srvForm->srvowner;
4252 
4253  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
4255  if (isNull)
4256  {
4257  /* No ACL, so build default ACL */
4258  acl = acldefault(ACL_OBJECT_FOREIGN_SERVER, ownerId);
4259  aclDatum = (Datum) 0;
4260  }
4261  else
4262  {
4263  /* detoast rel's ACL if necessary */
4264  acl = DatumGetAclP(aclDatum);
4265  }
4266 
4267  result = aclmask(acl, roleid, ownerId, mask, how);
4268 
4269  /* if we have a detoasted copy, free it */
4270  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4271  pfree(acl);
4272 
4273  ReleaseSysCache(tuple);
4274 
4275  return result;
4276 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define Anum_pg_foreign_server_srvacl
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:555
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_foreign_server_ownercheck()

bool pg_foreign_server_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 4968 of file aclchk.c.

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

4969 {
4970  HeapTuple tuple;
4971  Oid ownerId;
4972 
4973  /* Superusers bypass all permission checking. */
4974  if (superuser_arg(roleid))
4975  return true;
4976 
4978  if (!HeapTupleIsValid(tuple))
4979  ereport(ERROR,
4980  (errcode(ERRCODE_UNDEFINED_OBJECT),
4981  errmsg("foreign server with OID %u does not exist",
4982  srv_oid)));
4983 
4984  ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner;
4985 
4986  ReleaseSysCache(tuple);
4987 
4988  return has_privs_of_role(roleid, ownerId);
4989 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_language_aclcheck()

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

Definition at line 4516 of file aclchk.c.

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, 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().

4517 {
4518  if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
4519  return ACLCHECK_OK;
4520  else
4521  return ACLCHECK_NO_PRIV;
4522 }
AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3884

◆ pg_language_aclmask()

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

Definition at line 3884 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_language_aclcheck().

3886 {
3887  AclMode result;
3888  HeapTuple tuple;
3889  Datum aclDatum;
3890  bool isNull;
3891  Acl *acl;
3892  Oid ownerId;
3893 
3894  /* Superusers bypass all permission checking. */
3895  if (superuser_arg(roleid))
3896  return mask;
3897 
3898  /*
3899  * Get the language's ACL from pg_language
3900  */
3901  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
3902  if (!HeapTupleIsValid(tuple))
3903  ereport(ERROR,
3904  (errcode(ERRCODE_UNDEFINED_OBJECT),
3905  errmsg("language with OID %u does not exist", lang_oid)));
3906 
3907  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
3908 
3909  aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
3910  &isNull);
3911  if (isNull)
3912  {
3913  /* No ACL, so build default ACL */
3914  acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId);
3915  aclDatum = (Datum) 0;
3916  }
3917  else
3918  {
3919  /* detoast ACL if necessary */
3920  acl = DatumGetAclP(aclDatum);
3921  }
3922 
3923  result = aclmask(acl, roleid, ownerId, mask, how);
3924 
3925  /* if we have a detoasted copy, free it */
3926  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3927  pfree(acl);
3928 
3929  ReleaseSysCache(tuple);
3930 
3931  return result;
3932 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define DatumGetAclP(X)
Definition: acl.h:121
#define Anum_pg_language_lanacl
Definition: pg_language.h:65
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:70
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:555
FormData_pg_language * Form_pg_language
Definition: pg_language.h:51
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_language_ownercheck()

bool pg_language_ownercheck ( Oid  lan_oid,
Oid  roleid 
)

Definition at line 4708 of file aclchk.c.

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

Referenced by check_object_ownership(), and create_proc_lang().

4709 {
4710  HeapTuple tuple;
4711  Oid ownerId;
4712 
4713  /* Superusers bypass all permission checking. */
4714  if (superuser_arg(roleid))
4715  return true;
4716 
4717  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid));
4718  if (!HeapTupleIsValid(tuple))
4719  ereport(ERROR,
4720  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4721  errmsg("language with OID %u does not exist", lan_oid)));
4722 
4723  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
4724 
4725  ReleaseSysCache(tuple);
4726 
4727  return has_privs_of_role(roleid, ownerId);
4728 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_language * Form_pg_language
Definition: pg_language.h:51
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4528 of file aclchk.c.

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

Referenced by be_lo_put(), and inv_open().

4530 {
4531  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4532  ACLMASK_ANY, snapshot) != 0)
4533  return ACLCHECK_OK;
4534  else
4535  return ACLCHECK_NO_PRIV;
4536 }
AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3947

◆ pg_largeobject_aclmask_snapshot()

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

Definition at line 3947 of file aclchk.c.

References AccessShareLock, ACL_OBJECT_LARGEOBJECT, acldefault(), aclmask(), Anum_pg_largeobject_metadata_lomacl, BTEqualStrategyNumber, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, LargeObjectMetadataOidIndexId, LargeObjectMetadataRelationId, ObjectIdAttributeNumber, ObjectIdGetDatum, pfree(), RelationGetDescr, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().

3950 {
3951  AclMode result;
3952  Relation pg_lo_meta;
3953  ScanKeyData entry[1];
3954  SysScanDesc scan;
3955  HeapTuple tuple;
3956  Datum aclDatum;
3957  bool isNull;
3958  Acl *acl;
3959  Oid ownerId;
3960 
3961  /* Superusers bypass all permission checking. */
3962  if (superuser_arg(roleid))
3963  return mask;
3964 
3965  /*
3966  * Get the largeobject's ACL from pg_language_metadata
3967  */
3969  AccessShareLock);
3970 
3971  ScanKeyInit(&entry[0],
3973  BTEqualStrategyNumber, F_OIDEQ,
3974  ObjectIdGetDatum(lobj_oid));
3975 
3976  scan = systable_beginscan(pg_lo_meta,
3978  snapshot, 1, entry);
3979 
3980  tuple = systable_getnext(scan);
3981  if (!HeapTupleIsValid(tuple))
3982  ereport(ERROR,
3983  (errcode(ERRCODE_UNDEFINED_OBJECT),
3984  errmsg("large object %u does not exist", lobj_oid)));
3985 
3986  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
3987 
3989  RelationGetDescr(pg_lo_meta), &isNull);
3990 
3991  if (isNull)
3992  {
3993  /* No ACL, so build default ACL */
3994  acl = acldefault(ACL_OBJECT_LARGEOBJECT, ownerId);
3995  aclDatum = (Datum) 0;
3996  }
3997  else
3998  {
3999  /* detoast ACL if necessary */
4000  acl = DatumGetAclP(aclDatum);
4001  }
4002 
4003  result = aclmask(acl, roleid, ownerId, mask, how);
4004 
4005  /* if we have a detoasted copy, free it */
4006  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4007  pfree(acl);
4008 
4009  systable_endscan(scan);
4010 
4011  heap_close(pg_lo_meta, AccessShareLock);
4012 
4013  return result;
4014 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RelationGetDescr(relation)
Definition: rel.h:437
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define DatumGetAclP(X)
Definition: acl.h:121
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
#define AccessShareLock
Definition: lockdefs.h:36
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:748
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
uint32 AclMode
Definition: parsenodes.h:70
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:936
char * Pointer
Definition: c.h:283
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define LargeObjectMetadataOidIndexId
Definition: indexing.h:183
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define LargeObjectMetadataRelationId
#define DatumGetPointer(X)
Definition: postgres.h:555
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define Anum_pg_largeobject_metadata_lomacl
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ pg_largeobject_ownercheck()

bool pg_largeobject_ownercheck ( Oid  lobj_oid,
Oid  roleid 
)

Definition at line 4737 of file aclchk.c.

References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), heap_close, heap_open(), HeapTupleIsValid, LargeObjectMetadataOidIndexId, LargeObjectMetadataRelationId, ObjectIdAttributeNumber, ObjectIdGetDatum, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by be_lo_unlink(), and check_object_ownership().

4738 {
4739  Relation pg_lo_meta;
4740  ScanKeyData entry[1];
4741  SysScanDesc scan;
4742  HeapTuple tuple;
4743  Oid ownerId;
4744 
4745  /* Superusers bypass all permission checking. */
4746  if (superuser_arg(roleid))
4747  return true;
4748 
4749  /* There's no syscache for pg_largeobject_metadata */
4751  AccessShareLock);
4752 
4753  ScanKeyInit(&entry[0],
4755  BTEqualStrategyNumber, F_OIDEQ,
4756  ObjectIdGetDatum(lobj_oid));
4757 
4758  scan = systable_beginscan(pg_lo_meta,
4760  NULL, 1, entry);
4761 
4762  tuple = systable_getnext(scan);
4763  if (!HeapTupleIsValid(tuple))
4764  ereport(ERROR,
4765  (errcode(ERRCODE_UNDEFINED_OBJECT),
4766  errmsg("large object %u does not exist", lobj_oid)));
4767 
4768  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
4769 
4770  systable_endscan(scan);
4771  heap_close(pg_lo_meta, AccessShareLock);
4772 
4773  return has_privs_of_role(roleid, ownerId);
4774 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4833
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define LargeObjectMetadataOidIndexId
Definition: indexing.h:183
FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define LargeObjectMetadataRelationId
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ pg_namespace_aclcheck()