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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

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

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

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

Functions

Aclacldefault (ObjectType objtype, Oid ownerId)
 
Aclget_user_default_acl (ObjectType objtype, Oid ownerId, Oid nsp_oid)
 
void recordDependencyOnNewAcl (Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
 
Aclaclupdate (const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
 
Aclaclnewowner (const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
 
Aclmake_empty_acl (void)
 
Aclaclcopy (const Acl *orig_acl)
 
Aclaclconcat (const Acl *left_acl, const Acl *right_acl)
 
Aclaclmerge (const Acl *left_acl, const Acl *right_acl, Oid ownerId)
 
void aclitemsort (Acl *acl)
 
bool aclequal (const Acl *left_acl, const Acl *right_acl)
 
AclMode aclmask (const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
 
int aclmembers (const Acl *acl, Oid **roleids)
 
bool has_privs_of_role (Oid member, Oid role)
 
bool is_member_of_role (Oid member, Oid role)
 
bool is_member_of_role_nosuper (Oid member, Oid role)
 
bool is_admin_of_role (Oid member, Oid role)
 
void check_is_member_of_role (Oid member, Oid role)
 
Oid get_role_oid (const char *rolename, bool missing_ok)
 
Oid get_role_oid_or_public (const char *rolename)
 
Oid get_rolespec_oid (const RoleSpec *role, bool missing_ok)
 
void check_rolespec_name (const RoleSpec *role, const char *detail_msg)
 
HeapTuple get_rolespec_tuple (const RoleSpec *role)
 
char * get_rolespec_name (const RoleSpec *role)
 
void select_best_grantor (Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
AclMode pg_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_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, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
bool pg_class_ownercheck (Oid class_oid, Oid roleid)
 
bool pg_type_ownercheck (Oid type_oid, Oid roleid)
 
bool pg_oper_ownercheck (Oid oper_oid, Oid roleid)
 
bool pg_proc_ownercheck (Oid proc_oid, Oid roleid)
 
bool pg_language_ownercheck (Oid lan_oid, Oid roleid)
 
bool pg_largeobject_ownercheck (Oid lobj_oid, Oid roleid)
 
bool pg_namespace_ownercheck (Oid nsp_oid, Oid roleid)
 
bool pg_tablespace_ownercheck (Oid spc_oid, Oid roleid)
 
bool pg_opclass_ownercheck (Oid opc_oid, Oid roleid)
 
bool pg_opfamily_ownercheck (Oid opf_oid, Oid roleid)
 
bool pg_database_ownercheck (Oid db_oid, Oid roleid)
 
bool pg_collation_ownercheck (Oid coll_oid, Oid roleid)
 
bool pg_conversion_ownercheck (Oid conv_oid, Oid roleid)
 
bool pg_ts_dict_ownercheck (Oid dict_oid, Oid roleid)
 
bool pg_ts_config_ownercheck (Oid cfg_oid, Oid roleid)
 
bool pg_foreign_data_wrapper_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_foreign_server_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_event_trigger_ownercheck (Oid et_oid, Oid roleid)
 
bool pg_extension_ownercheck (Oid ext_oid, Oid roleid)
 
bool pg_publication_ownercheck (Oid pub_oid, Oid roleid)
 
bool pg_subscription_ownercheck (Oid sub_oid, Oid roleid)
 
bool pg_statistics_object_ownercheck (Oid stat_oid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 156 of file acl.h.

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 159 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 160 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 163 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_RELATION

◆ ACL_ALL_RIGHTS_SCHEMA

◆ ACL_ALL_RIGHTS_SEQUENCE

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTc"

Definition at line 151 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 148 of file acl.h.

Referenced by aclparse().

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

Referenced by aclparse().

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 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 144 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 129 of file acl.h.

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

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 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 131 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 110 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 71 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 142 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 111 of file acl.h.

Referenced by aclupdate(), and check_circularity().

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

Referenced by aclparse().

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

Referenced by aclparse().

◆ ACL_UPDATE_CHR

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

Definition at line 139 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 145 of file acl.h.

Referenced by aclparse().

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

Referenced by aclmask(), and aclmask_direct().

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

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

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 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 68 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:72

Definition at line 76 of file acl.h.

◆ ACLITEM_SET_PRIVS

#define ACLITEM_SET_PRIVS (   item,
  privs 
)
Value:
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \
((AclMode) (privs) & 0xFFFF))
uint32 AclMode
Definition: parsenodes.h:72

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

#define ACLITEM_SET_PRIVS_GOPTIONS (   item,
  privs,
  goptions 
)
Value:
((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \
(((AclMode) (goptions) & 0xFFFF) << 16))
uint32 AclMode
Definition: parsenodes.h:72

Definition at line 82 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 79 of file acl.h.

Referenced by aclnewowner(), and aclupdate().

◆ DatumGetAclItemP

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

Definition at line 116 of file acl.h.

◆ DatumGetAclP

◆ DatumGetAclPCopy

◆ PG_GETARG_ACL_P

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

Definition at line 122 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 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 117 of file acl.h.

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

Referenced by aclitemin(), and makeaclitem().

Typedef Documentation

◆ Acl

typedef struct ArrayType Acl

Definition at line 106 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 170 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 177 of file acl.h.

178 {
179  ACLCHECK_OK = 0,
182 } AclResult;
AclResult
Definition: acl.h:177

Function Documentation

◆ aclcheck_error()

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

Definition at line 3294 of file aclchk.c.

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

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateTransform(), 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(), ExecBuildGroupingEqual(), ExecCheckRTPerms(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), get_rel_from_relname(), gin_clean_pending_list(), HandleFunctionRequest(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), 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_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

3296 {
3297  switch (aclerr)
3298  {
3299  case ACLCHECK_OK:
3300  /* no error, so return to caller */
3301  break;
3302  case ACLCHECK_NO_PRIV:
3303  {
3304  const char *msg = "???";
3305 
3306  switch (objtype)
3307  {
3308  case OBJECT_AGGREGATE:
3309  msg = gettext_noop("permission denied for aggregate %s");
3310  break;
3311  case OBJECT_COLLATION:
3312  msg = gettext_noop("permission denied for collation %s");
3313  break;
3314  case OBJECT_COLUMN:
3315  msg = gettext_noop("permission denied for column %s");
3316  break;
3317  case OBJECT_CONVERSION:
3318  msg = gettext_noop("permission denied for conversion %s");
3319  break;
3320  case OBJECT_DATABASE:
3321  msg = gettext_noop("permission denied for database %s");
3322  break;
3323  case OBJECT_DOMAIN:
3324  msg = gettext_noop("permission denied for domain %s");
3325  break;
3326  case OBJECT_EVENT_TRIGGER:
3327  msg = gettext_noop("permission denied for event trigger %s");
3328  break;
3329  case OBJECT_EXTENSION:
3330  msg = gettext_noop("permission denied for extension %s");
3331  break;
3332  case OBJECT_FDW:
3333  msg = gettext_noop("permission denied for foreign-data wrapper %s");
3334  break;
3335  case OBJECT_FOREIGN_SERVER:
3336  msg = gettext_noop("permission denied for foreign server %s");
3337  break;
3338  case OBJECT_FOREIGN_TABLE:
3339  msg = gettext_noop("permission denied for foreign table %s");
3340  break;
3341  case OBJECT_FUNCTION:
3342  msg = gettext_noop("permission denied for function %s");
3343  break;
3344  case OBJECT_INDEX:
3345  msg = gettext_noop("permission denied for index %s");
3346  break;
3347  case OBJECT_LANGUAGE:
3348  msg = gettext_noop("permission denied for language %s");
3349  break;
3350  case OBJECT_LARGEOBJECT:
3351  msg = gettext_noop("permission denied for large object %s");
3352  break;
3353  case OBJECT_MATVIEW:
3354  msg = gettext_noop("permission denied for materialized view %s");
3355  break;
3356  case OBJECT_OPCLASS:
3357  msg = gettext_noop("permission denied for operator class %s");
3358  break;
3359  case OBJECT_OPERATOR:
3360  msg = gettext_noop("permission denied for operator %s");
3361  break;
3362  case OBJECT_OPFAMILY:
3363  msg = gettext_noop("permission denied for operator family %s");
3364  break;
3365  case OBJECT_POLICY:
3366  msg = gettext_noop("permission denied for policy %s");
3367  break;
3368  case OBJECT_PROCEDURE:
3369  msg = gettext_noop("permission denied for procedure %s");
3370  break;
3371  case OBJECT_PUBLICATION:
3372  msg = gettext_noop("permission denied for publication %s");
3373  break;
3374  case OBJECT_ROUTINE:
3375  msg = gettext_noop("permission denied for routine %s");
3376  break;
3377  case OBJECT_SCHEMA:
3378  msg = gettext_noop("permission denied for schema %s");
3379  break;
3380  case OBJECT_SEQUENCE:
3381  msg = gettext_noop("permission denied for sequence %s");
3382  break;
3383  case OBJECT_STATISTIC_EXT:
3384  msg = gettext_noop("permission denied for statistics object %s");
3385  break;
3386  case OBJECT_SUBSCRIPTION:
3387  msg = gettext_noop("permission denied for subscription %s");
3388  break;
3389  case OBJECT_TABLE:
3390  msg = gettext_noop("permission denied for table %s");
3391  break;
3392  case OBJECT_TABLESPACE:
3393  msg = gettext_noop("permission denied for tablespace %s");
3394  break;
3396  msg = gettext_noop("permission denied for text search configuration %s");
3397  break;
3398  case OBJECT_TSDICTIONARY:
3399  msg = gettext_noop("permission denied for text search dictionary %s");
3400  break;
3401  case OBJECT_TYPE:
3402  msg = gettext_noop("permission denied for type %s");
3403  break;
3404  case OBJECT_VIEW:
3405  msg = gettext_noop("permission denied for view %s");
3406  break;
3407  /* these currently aren't used */
3408  case OBJECT_ACCESS_METHOD:
3409  case OBJECT_AMOP:
3410  case OBJECT_AMPROC:
3411  case OBJECT_ATTRIBUTE:
3412  case OBJECT_CAST:
3413  case OBJECT_DEFAULT:
3414  case OBJECT_DEFACL:
3415  case OBJECT_DOMCONSTRAINT:
3417  case OBJECT_ROLE:
3418  case OBJECT_RULE:
3419  case OBJECT_TABCONSTRAINT:
3420  case OBJECT_TRANSFORM:
3421  case OBJECT_TRIGGER:
3422  case OBJECT_TSPARSER:
3423  case OBJECT_TSTEMPLATE:
3424  case OBJECT_USER_MAPPING:
3425  elog(ERROR, "unsupported object type %d", objtype);
3426  }
3427 
3428  ereport(ERROR,
3429  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3430  errmsg(msg, objectname)));
3431  break;
3432  }
3433  case ACLCHECK_NOT_OWNER:
3434  {
3435  const char *msg = "???";
3436 
3437  switch (objtype)
3438  {
3439  case OBJECT_AGGREGATE:
3440  msg = gettext_noop("must be owner of aggregate %s");
3441  break;
3442  case OBJECT_COLLATION:
3443  msg = gettext_noop("must be owner of collation %s");
3444  break;
3445  case OBJECT_CONVERSION:
3446  msg = gettext_noop("must be owner of conversion %s");
3447  break;
3448  case OBJECT_DATABASE:
3449  msg = gettext_noop("must be owner of database %s");
3450  break;
3451  case OBJECT_DOMAIN:
3452  msg = gettext_noop("must be owner of domain %s");
3453  break;
3454  case OBJECT_EVENT_TRIGGER:
3455  msg = gettext_noop("must be owner of event trigger %s");
3456  break;
3457  case OBJECT_EXTENSION:
3458  msg = gettext_noop("must be owner of extension %s");
3459  break;
3460  case OBJECT_FDW:
3461  msg = gettext_noop("must be owner of foreign-data wrapper %s");
3462  break;
3463  case OBJECT_FOREIGN_SERVER:
3464  msg = gettext_noop("must be owner of foreign server %s");
3465  break;
3466  case OBJECT_FOREIGN_TABLE:
3467  msg = gettext_noop("must be owner of foreign table %s");
3468  break;
3469  case OBJECT_FUNCTION:
3470  msg = gettext_noop("must be owner of function %s");
3471  break;
3472  case OBJECT_INDEX:
3473  msg = gettext_noop("must be owner of index %s");
3474  break;
3475  case OBJECT_LANGUAGE:
3476  msg = gettext_noop("must be owner of language %s");
3477  break;
3478  case OBJECT_LARGEOBJECT:
3479  msg = gettext_noop("must be owner of large object %s");
3480  break;
3481  case OBJECT_MATVIEW:
3482  msg = gettext_noop("must be owner of materialized view %s");
3483  break;
3484  case OBJECT_OPCLASS:
3485  msg = gettext_noop("must be owner of operator class %s");
3486  break;
3487  case OBJECT_OPERATOR:
3488  msg = gettext_noop("must be owner of operator %s");
3489  break;
3490  case OBJECT_OPFAMILY:
3491  msg = gettext_noop("must be owner of operator family %s");
3492  break;
3493  case OBJECT_PROCEDURE:
3494  msg = gettext_noop("must be owner of procedure %s");
3495  break;
3496  case OBJECT_PUBLICATION:
3497  msg = gettext_noop("must be owner of publication %s");
3498  break;
3499  case OBJECT_ROUTINE:
3500  msg = gettext_noop("must be owner of routine %s");
3501  break;
3502  case OBJECT_SEQUENCE:
3503  msg = gettext_noop("must be owner of sequence %s");
3504  break;
3505  case OBJECT_SUBSCRIPTION:
3506  msg = gettext_noop("must be owner of subscription %s");
3507  break;
3508  case OBJECT_TABLE:
3509  msg = gettext_noop("must be owner of table %s");
3510  break;
3511  case OBJECT_TYPE:
3512  msg = gettext_noop("must be owner of type %s");
3513  break;
3514  case OBJECT_VIEW:
3515  msg = gettext_noop("must be owner of view %s");
3516  break;
3517  case OBJECT_SCHEMA:
3518  msg = gettext_noop("must be owner of schema %s");
3519  break;
3520  case OBJECT_STATISTIC_EXT:
3521  msg = gettext_noop("must be owner of statistics object %s");
3522  break;
3523  case OBJECT_TABLESPACE:
3524  msg = gettext_noop("must be owner of tablespace %s");
3525  break;
3527  msg = gettext_noop("must be owner of text search configuration %s");
3528  break;
3529  case OBJECT_TSDICTIONARY:
3530  msg = gettext_noop("must be owner of text search dictionary %s");
3531  break;
3532 
3533  /*
3534  * Special cases: For these, the error message talks
3535  * about "relation", because that's where the
3536  * ownership is attached. See also
3537  * check_object_ownership().
3538  */
3539  case OBJECT_COLUMN:
3540  case OBJECT_POLICY:
3541  case OBJECT_RULE:
3542  case OBJECT_TABCONSTRAINT:
3543  case OBJECT_TRIGGER:
3544  msg = gettext_noop("must be owner of relation %s");
3545  break;
3546  /* these currently aren't used */
3547  case OBJECT_ACCESS_METHOD:
3548  case OBJECT_AMOP:
3549  case OBJECT_AMPROC:
3550  case OBJECT_ATTRIBUTE:
3551  case OBJECT_CAST:
3552  case OBJECT_DEFAULT:
3553  case OBJECT_DEFACL:
3554  case OBJECT_DOMCONSTRAINT:
3556  case OBJECT_ROLE:
3557  case OBJECT_TRANSFORM:
3558  case OBJECT_TSPARSER:
3559  case OBJECT_TSTEMPLATE:
3560  case OBJECT_USER_MAPPING:
3561  elog(ERROR, "unsupported object type %d", objtype);
3562  }
3563 
3564  ereport(ERROR,
3565  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3566  errmsg(msg, objectname)));
3567  break;
3568  }
3569  default:
3570  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3571  break;
3572  }
3573 }
#define gettext_noop(x)
Definition: c.h:1166
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ aclcheck_error_col()

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

Definition at line 3577 of file aclchk.c.

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

Referenced by restrict_and_check_grant().

3579 {
3580  switch (aclerr)
3581  {
3582  case ACLCHECK_OK:
3583  /* no error, so return to caller */
3584  break;
3585  case ACLCHECK_NO_PRIV:
3586  ereport(ERROR,
3587  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3588  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3589  colname, objectname)));
3590  break;
3591  case ACLCHECK_NOT_OWNER:
3592  /* relation msg is OK since columns don't have separate owners */
3593  aclcheck_error(aclerr, objtype, objectname);
3594  break;
3595  default:
3596  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3597  break;
3598  }
3599 }
int errcode(int sqlerrcode)
Definition: elog.c:610
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ aclcheck_error_type()

void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

Definition at line 3607 of file aclchk.c.

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

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

3608 {
3609  Oid element_type = get_element_type(typeOid);
3610 
3611  aclcheck_error(aclerr, OBJECT_TYPE, format_type_be(element_type ? element_type : typeOid));
3612 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2636
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294

◆ aclconcat()

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

Definition at line 420 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

421 {
422  Acl *result_acl;
423 
424  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
425 
426  memcpy(ACL_DAT(result_acl),
427  ACL_DAT(left_acl),
428  ACL_NUM(left_acl) * sizeof(AclItem));
429 
430  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
431  ACL_DAT(right_acl),
432  ACL_NUM(right_acl) * sizeof(AclItem));
433 
434  return result_acl;
435 }
static Acl * allocacl(int n)
Definition: acl.c:369
#define ACL_NUM(ACL)
Definition: acl.h:108
#define ACL_DAT(ACL)
Definition: acl.h:109
Definition: acl.h:54

◆ aclcopy()

Acl* aclcopy ( const Acl orig_acl)

Definition at line 400 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

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

401 {
402  Acl *result_acl;
403 
404  result_acl = allocacl(ACL_NUM(orig_acl));
405 
406  memcpy(ACL_DAT(result_acl),
407  ACL_DAT(orig_acl),
408  ACL_NUM(orig_acl) * sizeof(AclItem));
409 
410  return result_acl;
411 }
static Acl * allocacl(int n)
Definition: acl.c:369
#define ACL_NUM(ACL)
Definition: acl.h:108
#define ACL_DAT(ACL)
Definition: acl.h:109
Definition: acl.h:54

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 741 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_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog, ERROR, OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

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

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

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 502 of file acl.c.

References ACL_DAT, and ACL_NUM.

Referenced by get_user_default_acl(), and SetDefaultACL().

503 {
504  /* Check for cases where one or both are empty/null */
505  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
506  {
507  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
508  return true;
509  else
510  return false;
511  }
512  else
513  {
514  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
515  return false;
516  }
517 
518  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
519  return false;
520 
521  if (memcmp(ACL_DAT(left_acl),
522  ACL_DAT(right_acl),
523  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
524  return true;
525 
526  return false;
527 }
#define ACL_NUM(ACL)
Definition: acl.h:108
#define ACL_DAT(ACL)
Definition: acl.h:109
Definition: acl.h:54

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 488 of file acl.c.

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

Referenced by get_user_default_acl(), and SetDefaultACL().

489 {
490  if (acl != NULL && ACL_NUM(acl) > 1)
491  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
492 }
#define ACL_NUM(ACL)
Definition: acl.h:108
#define ACL_DAT(ACL)
Definition: acl.h:109
Definition: acl.h:54
#define qsort(a, b, c, d)
Definition: port.h:479
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:662

◆ aclmask()

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

Definition at line 1313 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().

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

◆ aclmembers()

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

Definition at line 1465 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(), qsort, and qunique().

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

1466 {
1467  Oid *list;
1468  const AclItem *acldat;
1469  int i,
1470  j;
1471 
1472  if (acl == NULL || ACL_NUM(acl) == 0)
1473  {
1474  *roleids = NULL;
1475  return 0;
1476  }
1477 
1478  check_acl(acl);
1479 
1480  /* Allocate the worst-case space requirement */
1481  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1482  acldat = ACL_DAT(acl);
1483 
1484  /*
1485  * Walk the ACL collecting mentioned RoleIds.
1486  */
1487  j = 0;
1488  for (i = 0; i < ACL_NUM(acl); i++)
1489  {
1490  const AclItem *ai = &acldat[i];
1491 
1492  if (ai->ai_grantee != ACL_ID_PUBLIC)
1493  list[j++] = ai->ai_grantee;
1494  /* grantor is currently never PUBLIC, but let's check anyway */
1495  if (ai->ai_grantor != ACL_ID_PUBLIC)
1496  list[j++] = ai->ai_grantor;
1497  }
1498 
1499  /* Sort the array */
1500  qsort(list, j, sizeof(Oid), oid_cmp);
1501 
1502  /*
1503  * We could repalloc the array down to minimum size, but it's hardly worth
1504  * it since it's only transient memory.
1505  */
1506  *roleids = list;
1507 
1508  /* Remove duplicates from the array */
1509  return qunique(list, j, sizeof(Oid), oid_cmp);
1510 }
Oid ai_grantee
Definition: acl.h:56
unsigned int Oid
Definition: postgres_ext.h:31
Oid ai_grantor
Definition: acl.h:57
#define ACL_NUM(ACL)
Definition: acl.h:108
#define ACL_DAT(ACL)
Definition: acl.h:109
Definition: acl.h:54
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:336
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
void * palloc(Size size)
Definition: mcxt.c:949
int i
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define qsort(a, b, c, d)
Definition: port.h:479
static void check_acl(const Acl *acl)
Definition: acl.c:533

◆ aclmerge()

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

Definition at line 444 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().

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

◆ aclnewowner()

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

Definition at line 1044 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().

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

◆ aclupdate()

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

Definition at line 923 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(), recursive_revoke(), and SET_VARSIZE.

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

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

◆ check_is_member_of_role()

void check_is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4938 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().

4939 {
4940  if (!is_member_of_role(member, role))
4941  ereport(ERROR,
4942  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4943  errmsg("must be member of role \"%s\"",
4944  GetUserNameFromId(role, false))));
4945 }
int errcode(int sqlerrcode)
Definition: elog.c:610
Oid member
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4916
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ check_rolespec_name()

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

Definition at line 5314 of file acl.c.

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

Referenced by AlterRole(), and AlterRoleSet().

5315 {
5316  if (!role)
5317  return;
5318 
5319  if (role->roletype != ROLESPEC_CSTRING)
5320  return;
5321 
5322  if (IsReservedName(role->rolename))
5323  {
5324  if (detail_msg)
5325  ereport(ERROR,
5326  (errcode(ERRCODE_RESERVED_NAME),
5327  errmsg("role name \"%s\" is reserved",
5328  role->rolename),
5329  errdetail("%s", detail_msg)));
5330  else
5331  ereport(ERROR,
5332  (errcode(ERRCODE_RESERVED_NAME),
5333  errmsg("role name \"%s\" is reserved",
5334  role->rolename)));
5335  }
5336 }
int errcode(int sqlerrcode)
Definition: elog.c:610
bool IsReservedName(const char *name)
Definition: catalog.c:212
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:957
RoleSpecType roletype
Definition: parsenodes.h:329
#define ereport(elevel,...)
Definition: elog.h:144
char * rolename
Definition: parsenodes.h:330
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

Definition at line 888 of file aclchk.c.

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, generate_unaccent_rules::action, AlterDefaultPrivilegesStmt::action, InternalDefaultACL::all_privs, DefElem::arg, InternalDefaultACL::behavior, 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, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, 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().

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

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 359 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_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, 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, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), 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().

360 {
361  InternalGrant istmt;
362  ListCell *cell;
363  const char *errormsg;
364  AclMode all_privileges;
365 
366  /*
367  * Turn the regular GrantStmt into the InternalGrant form.
368  */
369  istmt.is_grant = stmt->is_grant;
370  istmt.objtype = stmt->objtype;
371 
372  /* Collect the OIDs of the target objects */
373  switch (stmt->targtype)
374  {
375  case ACL_TARGET_OBJECT:
376  istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
377  break;
379  istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
380  break;
381  /* ACL_TARGET_DEFAULTS should not be seen here */
382  default:
383  elog(ERROR, "unrecognized GrantStmt.targtype: %d",
384  (int) stmt->targtype);
385  }
386 
387  /* all_privs to be filled below */
388  /* privileges to be filled below */
389  istmt.col_privs = NIL; /* may get filled below */
390  istmt.grantees = NIL; /* filled below */
391  istmt.grant_option = stmt->grant_option;
392  istmt.behavior = stmt->behavior;
393 
394  /*
395  * Convert the RoleSpec list into an Oid list. Note that at this point we
396  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
397  * there shouldn't be any additional work needed to support this case.
398  */
399  foreach(cell, stmt->grantees)
400  {
401  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
402  Oid grantee_uid;
403 
404  switch (grantee->roletype)
405  {
406  case ROLESPEC_PUBLIC:
407  grantee_uid = ACL_ID_PUBLIC;
408  break;
409  default:
410  grantee_uid = get_rolespec_oid(grantee, false);
411  break;
412  }
413  istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
414  }
415 
416  /*
417  * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
418  * bitmask. Note: objtype can't be OBJECT_COLUMN.
419  */
420  switch (stmt->objtype)
421  {
422  case OBJECT_TABLE:
423 
424  /*
425  * Because this might be a sequence, we test both relation and
426  * sequence bits, and later do a more limited test when we know
427  * the object type.
428  */
430  errormsg = gettext_noop("invalid privilege type %s for relation");
431  break;
432  case OBJECT_SEQUENCE:
433  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
434  errormsg = gettext_noop("invalid privilege type %s for sequence");
435  break;
436  case OBJECT_DATABASE:
437  all_privileges = ACL_ALL_RIGHTS_DATABASE;
438  errormsg = gettext_noop("invalid privilege type %s for database");
439  break;
440  case OBJECT_DOMAIN:
441  all_privileges = ACL_ALL_RIGHTS_TYPE;
442  errormsg = gettext_noop("invalid privilege type %s for domain");
443  break;
444  case OBJECT_FUNCTION:
445  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
446  errormsg = gettext_noop("invalid privilege type %s for function");
447  break;
448  case OBJECT_LANGUAGE:
449  all_privileges = ACL_ALL_RIGHTS_LANGUAGE;
450  errormsg = gettext_noop("invalid privilege type %s for language");
451  break;
452  case OBJECT_LARGEOBJECT:
453  all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
454  errormsg = gettext_noop("invalid privilege type %s for large object");
455  break;
456  case OBJECT_SCHEMA:
457  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
458  errormsg = gettext_noop("invalid privilege type %s for schema");
459  break;
460  case OBJECT_PROCEDURE:
461  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
462  errormsg = gettext_noop("invalid privilege type %s for procedure");
463  break;
464  case OBJECT_ROUTINE:
465  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
466  errormsg = gettext_noop("invalid privilege type %s for routine");
467  break;
468  case OBJECT_TABLESPACE:
469  all_privileges = ACL_ALL_RIGHTS_TABLESPACE;
470  errormsg = gettext_noop("invalid privilege type %s for tablespace");
471  break;
472  case OBJECT_TYPE:
473  all_privileges = ACL_ALL_RIGHTS_TYPE;
474  errormsg = gettext_noop("invalid privilege type %s for type");
475  break;
476  case OBJECT_FDW:
477  all_privileges = ACL_ALL_RIGHTS_FDW;
478  errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
479  break;
481  all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER;
482  errormsg = gettext_noop("invalid privilege type %s for foreign server");
483  break;
484  default:
485  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
486  (int) stmt->objtype);
487  /* keep compiler quiet */
488  all_privileges = ACL_NO_RIGHTS;
489  errormsg = NULL;
490  }
491 
492  if (stmt->privileges == NIL)
493  {
494  istmt.all_privs = true;
495 
496  /*
497  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
498  * depending on the object type
499  */
500  istmt.privileges = ACL_NO_RIGHTS;
501  }
502  else
503  {
504  istmt.all_privs = false;
505  istmt.privileges = ACL_NO_RIGHTS;
506 
507  foreach(cell, stmt->privileges)
508  {
509  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
510  AclMode priv;
511 
512  /*
513  * If it's a column-level specification, we just set it aside in
514  * col_privs for the moment; but insist it's for a relation.
515  */
516  if (privnode->cols)
517  {
518  if (stmt->objtype != OBJECT_TABLE)
519  ereport(ERROR,
520  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
521  errmsg("column privileges are only valid for relations")));
522  istmt.col_privs = lappend(istmt.col_privs, privnode);
523  continue;
524  }
525 
526  if (privnode->priv_name == NULL) /* parser mistake? */
527  elog(ERROR, "AccessPriv node must specify privilege or columns");
528  priv = string_to_privilege(privnode->priv_name);
529 
530  if (priv & ~((AclMode) all_privileges))
531  ereport(ERROR,
532  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
533  errmsg(errormsg, privilege_to_string(priv))));
534 
535  istmt.privileges |= priv;
536  }
537  }
538 
539  ExecGrantStmt_oids(&istmt);
540 }
#define NIL
Definition: pg_list.h:65
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:162
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:3216
AclMode privileges
bool grant_option
Definition: parsenodes.h:1935
#define gettext_noop(x)
Definition: c.h:1166
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:166
List * cols
Definition: parsenodes.h:1965
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:163
uint32 AclMode
Definition: parsenodes.h:72
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:88
#define ACL_ALL_RIGHTS_SCHEMA
Definition: acl.h:165
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:167
List * lappend(List *list, void *datum)
Definition: list.c:321
bool is_grant
Definition: parsenodes.h:1927
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition: aclchk.c:548
static List * objectNamesToOids(ObjectType objtype, List *objnames)
Definition: aclchk.c:612
RoleSpecType roletype
Definition: parsenodes.h:329
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5209
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:158
List * privileges
Definition: parsenodes.h:1932
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition: aclchk.c:761
#define ereport(elevel,...)
Definition: elog.h:144
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:164
DropBehavior behavior
DropBehavior behavior
Definition: parsenodes.h:1936
#define lfirst(lc)
Definition: pg_list.h:190
List * objects
Definition: parsenodes.h:1930
ObjectType objtype
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:159
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:161
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:157
ObjectType objtype
Definition: parsenodes.h:1929
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:160
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:3253
List * grantees
Definition: parsenodes.h:1934
GrantTargetType targtype
Definition: parsenodes.h:1928
char * priv_name
Definition: parsenodes.h:1964

◆ get_role_oid()

Oid get_role_oid ( const char *  rolename,
bool  missing_ok 
)

Definition at line 5175 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().

5176 {
5177  Oid oid;
5178 
5179  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5181  if (!OidIsValid(oid) && !missing_ok)
5182  ereport(ERROR,
5183  (errcode(ERRCODE_UNDEFINED_OBJECT),
5184  errmsg("role \"%s\" does not exist", rolname)));
5185  return oid;
5186 }
NameData rolname
Definition: pg_authid.h:34
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:651
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5292 of file acl.c.

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

Referenced by AddRoleMems(), and DelRoleMems().

5293 {
5294  HeapTuple tp;
5295  Form_pg_authid authForm;
5296  char *rolename;
5297 
5298  tp = get_rolespec_tuple(role);
5299  authForm = (Form_pg_authid) GETSTRUCT(tp);
5300  rolename = pstrdup(NameStr(authForm->rolname));
5301  ReleaseSysCache(tp);
5302 
5303  return rolename;
5304 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char * pstrdup(const char *in)
Definition: mcxt.c:1186
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5247
#define NameStr(name)
Definition: c.h:622

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

Definition at line 5209 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().

5210 {
5211  Oid oid;
5212 
5213  switch (role->roletype)
5214  {
5215  case ROLESPEC_CSTRING:
5216  Assert(role->rolename);
5217  oid = get_role_oid(role->rolename, missing_ok);
5218  break;
5219 
5220  case ROLESPEC_CURRENT_USER:
5221  oid = GetUserId();
5222  break;
5223 
5224  case ROLESPEC_SESSION_USER:
5225  oid = GetSessionUserId();
5226  break;
5227 
5228  case ROLESPEC_PUBLIC:
5229  ereport(ERROR,
5230  (errcode(ERRCODE_UNDEFINED_OBJECT),
5231  errmsg("role \"%s\" does not exist", "public")));
5232  oid = InvalidOid; /* make compiler happy */
5233  break;
5234 
5235  default:
5236  elog(ERROR, "unexpected role type %d", role->roletype);
5237  }
5238 
5239  return oid;
5240 }
Oid GetUserId(void)
Definition: miscinit.c:448
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:482
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5175
#define ERROR
Definition: elog.h:43
RoleSpecType roletype
Definition: parsenodes.h:329
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:745
char * rolename
Definition: parsenodes.h:330
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

Definition at line 5247 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().

5248 {
5249  HeapTuple tuple;
5250 
5251  switch (role->roletype)
5252  {
5253  case ROLESPEC_CSTRING:
5254  Assert(role->rolename);
5256  if (!HeapTupleIsValid(tuple))
5257  ereport(ERROR,
5258  (errcode(ERRCODE_UNDEFINED_OBJECT),
5259  errmsg("role \"%s\" does not exist", role->rolename)));
5260  break;
5261 
5262  case ROLESPEC_CURRENT_USER:
5263  tuple = SearchSysCache1(AUTHOID, GetUserId());
5264  if (!HeapTupleIsValid(tuple))
5265  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5266  break;
5267 
5268  case ROLESPEC_SESSION_USER:
5270  if (!HeapTupleIsValid(tuple))
5271  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5272  break;
5273 
5274  case ROLESPEC_PUBLIC:
5275  ereport(ERROR,
5276  (errcode(ERRCODE_UNDEFINED_OBJECT),
5277  errmsg("role \"%s\" does not exist", "public")));
5278  tuple = NULL; /* make compiler happy */
5279  break;
5280 
5281  default:
5282  elog(ERROR, "unexpected role type %d", role->roletype);
5283  }
5284 
5285  return tuple;
5286 }
Oid GetUserId(void)
Definition: miscinit.c:448
int errcode(int sqlerrcode)
Definition: elog.c:610
Oid GetSessionUserId(void)
Definition: miscinit.c:482
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
RoleSpecType roletype
Definition: parsenodes.h:329
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:745
char * rolename
Definition: parsenodes.h:330
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ get_user_default_acl()

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

Definition at line 5390 of file aclchk.c.

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

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

5391 {
5392  Acl *result;
5393  Acl *glob_acl;
5394  Acl *schema_acl;
5395  Acl *def_acl;
5396  char defaclobjtype;
5397 
5398  /*
5399  * Use NULL during bootstrap, since pg_default_acl probably isn't there
5400  * yet.
5401  */
5403  return NULL;
5404 
5405  /* Check if object type is supported in pg_default_acl */
5406  switch (objtype)
5407  {
5408  case OBJECT_TABLE:
5409  defaclobjtype = DEFACLOBJ_RELATION;
5410  break;
5411 
5412  case OBJECT_SEQUENCE:
5413  defaclobjtype = DEFACLOBJ_SEQUENCE;
5414  break;
5415 
5416  case OBJECT_FUNCTION:
5417  defaclobjtype = DEFACLOBJ_FUNCTION;
5418  break;
5419 
5420  case OBJECT_TYPE:
5421  defaclobjtype = DEFACLOBJ_TYPE;
5422  break;
5423 
5424  case OBJECT_SCHEMA:
5425  defaclobjtype = DEFACLOBJ_NAMESPACE;
5426  break;
5427 
5428  default:
5429  return NULL;
5430  }
5431 
5432  /* Look up the relevant pg_default_acl entries */
5433  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5434  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5435 
5436  /* Quick out if neither entry exists */
5437  if (glob_acl == NULL && schema_acl == NULL)
5438  return NULL;
5439 
5440  /* We need to know the hard-wired default value, too */
5441  def_acl = acldefault(objtype, ownerId);
5442 
5443  /* If there's no global entry, substitute the hard-wired default */
5444  if (glob_acl == NULL)
5445  glob_acl = def_acl;
5446 
5447  /* Merge in any per-schema privileges */
5448  result = aclmerge(glob_acl, schema_acl, ownerId);
5449 
5450  /*
5451  * For efficiency, we want to return NULL if the result equals default.
5452  * This requires sorting both arrays to get an accurate comparison.
5453  */
5454  aclitemsort(result);
5455  aclitemsort(def_acl);
5456  if (aclequal(result, def_acl))
5457  result = NULL;
5458 
5459  return result;
5460 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:5355
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:502
#define InvalidOid
Definition: postgres_ext.h:36
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:444
void aclitemsort(Acl *acl)
Definition: acl.c:488
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:392

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 5331 of file aclchk.c.

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

Referenced by check_enable_rls(), and RI_Initial_Check().

5332 {
5333  bool result = false;
5334  HeapTuple utup;
5335 
5336  /* Superusers bypass all permission checking. */
5337  if (superuser_arg(roleid))
5338  return true;
5339 
5340  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5341  if (HeapTupleIsValid(utup))
5342  {
5343  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
5344  ReleaseSysCache(utup);
5345  }
5346  return result;
5347 }
bool rolbypassrls
Definition: pg_authid.h:41
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 5312 of file aclchk.c.

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

Referenced by check_object_ownership(), and have_createrole_privilege().

5313 {
5314  bool result = false;
5315  HeapTuple utup;
5316 
5317  /* Superusers bypass all permission checking. */
5318  if (superuser_arg(roleid))
5319  return true;
5320 
5321  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5322  if (HeapTupleIsValid(utup))
5323  {
5324  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
5325  ReleaseSysCache(utup);
5326  }
5327  return result;
5328 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
bool rolcreaterole
Definition: pg_authid.h:37
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4892 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_statistics_object_ownercheck(), pg_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), ReassignOwnedObjects(), and TerminateOtherDBBackends().

4893 {
4894  /* Fast path for simple case */
4895  if (member == role)
4896  return true;
4897 
4898  /* Superusers have every privilege, so are part of every role */
4899  if (superuser_arg(member))
4900  return true;
4901 
4902  /*
4903  * Find all the roles that member has the privileges of, including
4904  * multi-level recursion, then see if target role is any one of them.
4905  */
4906  return list_member_oid(roles_has_privs_of(member), role);
4907 }
Oid member
static List * roles_has_privs_of(Oid roleid)
Definition: acl.c:4732
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4673 of file acl.c.

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

Referenced by InitPostgres().

4674 {
4676  {
4677  /*
4678  * In normal mode, set a callback on any syscache invalidation of
4679  * pg_auth_members rows
4680  */
4683  (Datum) 0);
4684  }
4685 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1426
uintptr_t Datum
Definition: postgres.h:367
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4692
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:392

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 4974 of file acl.c.

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

4975 {
4976  bool result = false;
4977  List *roles_list;
4978  ListCell *l;
4979 
4980  if (superuser_arg(member))
4981  return true;
4982 
4983  if (member == role)
4984 
4985  /*
4986  * A role can admin itself when it matches the session user and we're
4987  * outside any security-restricted operation, SECURITY DEFINER or
4988  * similar context. SQL-standard roles cannot self-admin. However,
4989  * SQL-standard users are distinct from roles, and they are not
4990  * grantable like roles: PostgreSQL's role-user duality extends the
4991  * standard. Checking for a session user match has the effect of
4992  * letting a role self-admin only when it's conspicuously behaving
4993  * like a user. Note that allowing self-admin under a mere SET ROLE
4994  * would make WITH ADMIN OPTION largely irrelevant; any member could
4995  * SET ROLE to issue the otherwise-forbidden command.
4996  *
4997  * Withholding self-admin in a security-restricted operation prevents
4998  * object owners from harnessing the session user identity during
4999  * administrative maintenance. Suppose Alice owns a database, has
5000  * issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
5001  * an alice-owned SECURITY DEFINER function that issues "REVOKE alice
5002  * FROM carol". If he creates an expression index calling that
5003  * function, Alice will attempt the REVOKE during each ANALYZE.
5004  * Checking InSecurityRestrictedOperation() thwarts that attack.
5005  *
5006  * Withholding self-admin in SECURITY DEFINER functions makes their
5007  * behavior independent of the calling user. There's no security or
5008  * SQL-standard-conformance need for that restriction, though.
5009  *
5010  * A role cannot have actual WITH ADMIN OPTION on itself, because that
5011  * would imply a membership loop. Therefore, we're done either way.
5012  */
5013  return member == GetSessionUserId() &&
5015 
5016  /*
5017  * Find all the roles that member is a member of, including multi-level
5018  * recursion. We build a list in the same way that is_member_of_role does
5019  * to track visited and unvisited roles.
5020  */
5021  roles_list = list_make1_oid(member);
5022 
5023  foreach(l, roles_list)
5024  {
5025  Oid memberid = lfirst_oid(l);
5026  CatCList *memlist;
5027  int i;
5028 
5029  /* Find roles that memberid is directly a member of */
5031  ObjectIdGetDatum(memberid));
5032  for (i = 0; i < memlist->n_members; i++)
5033  {
5034  HeapTuple tup = &memlist->members[i]->tuple;
5035  Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid;
5036 
5037  if (otherid == role &&
5039  {
5040  /* Found what we came for, so can stop searching */
5041  result = true;
5042  break;
5043  }
5044 
5045  roles_list = list_append_unique_oid(roles_list, otherid);
5046  }
5047  ReleaseSysCacheList(memlist);
5048  if (result)
5049  break;
5050  }
5051 
5052  list_free(roles_list);
5053 
5054  return result;
5055 }
bool InLocalUserIdChange(void)
Definition: miscinit.c:571
int n_members
Definition: catcache.h:176
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1217
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:482
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
Oid member
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
#define ReleaseSysCacheList(x)
Definition: syscache.h:217
#define list_make1_oid(x1)
Definition: pg_list.h:249
FormData_pg_auth_members * Form_pg_auth_members
bool admin_option
bool InSecurityRestrictedOperation(void)
Definition: miscinit.c:580
void list_free(List *list)
Definition: list.c:1376
int i
HeapTupleData tuple
Definition: catcache.h:121
Definition: pg_list.h:50
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 4916 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(), convert_and_check_filename(), DoCopy(), file_fdw_validator(), get_explain_guc_options(), GetConfigOption(), GetConfigOptionByName(), GetConfigOptionByNum(), GetConfigOptionResetString(), pg_role_aclcheck(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), and ShowAllGUCConfig().

4917 {
4918  /* Fast path for simple case */
4919  if (member == role)
4920  return true;
4921 
4922  /* Superusers have every privilege, so are part of every role */
4923  if (superuser_arg(member))
4924  return true;
4925 
4926  /*
4927  * Find all the roles that member is a member of, including multi-level
4928  * recursion, then see if target role is any one of them.
4929  */
4930  return list_member_oid(roles_is_member_of(member), role);
4931 }
Oid member
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4815
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)

Definition at line 4954 of file acl.c.

References list_member_oid(), and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

4955 {
4956  /* Fast path for simple case */
4957  if (member == role)
4958  return true;
4959 
4960  /*
4961  * Find all the roles that member is a member of, including multi-level
4962  * recursion, then see if target role is any one of them.
4963  */
4964  return list_member_oid(roles_is_member_of(member), role);
4965 }
Oid member
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4815
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674

◆ make_empty_acl()

Acl* make_empty_acl ( void  )

Definition at line 391 of file acl.c.

References allocacl().

Referenced by SetDefaultACL().

392 {
393  return allocacl(0);
394 }
static Acl * allocacl(int n)
Definition: acl.c:369

◆ pg_attribute_aclcheck()

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

Definition at line 4449 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(), ri_ReportViolation(), and statext_is_compatible_clause().

4451 {
4452  if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0)
4453  return ACLCHECK_OK;
4454  else
4455  return ACLCHECK_NO_PRIV;
4456 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3687
int16 attnum
Definition: pg_attribute.h:79

◆ pg_attribute_aclcheck_all()

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

Definition at line 4478 of file aclchk.c.

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

4480 {
4481  AclResult result;
4482  HeapTuple classTuple;
4483  Form_pg_class classForm;
4484  AttrNumber nattrs;
4485  AttrNumber curr_att;
4486 
4487  /*
4488  * Must fetch pg_class row to check number of attributes. As in
4489  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4490  * throwing an error if we get any unexpected lookup errors.
4491  */
4492  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4493  if (!HeapTupleIsValid(classTuple))
4494  return ACLCHECK_NO_PRIV;
4495  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4496 
4497  nattrs = classForm->relnatts;
4498 
4499  ReleaseSysCache(classTuple);
4500 
4501  /*
4502  * Initialize result in case there are no non-dropped columns. We want to
4503  * report failure in such cases for either value of 'how'.
4504  */
4505  result = ACLCHECK_NO_PRIV;
4506 
4507  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4508  {
4509  HeapTuple attTuple;
4510  AclMode attmask;
4511 
4512  attTuple = SearchSysCache2(ATTNUM,
4513  ObjectIdGetDatum(table_oid),
4514  Int16GetDatum(curr_att));
4515  if (!HeapTupleIsValid(attTuple))
4516  continue;
4517 
4518  /* ignore dropped columns */
4519  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4520  {
4521  ReleaseSysCache(attTuple);
4522  continue;
4523  }
4524 
4525  /*
4526  * Here we hard-wire knowledge that the default ACL for a column
4527  * grants no privileges, so that we can fall out quickly in the very
4528  * common case where attacl is null.
4529  */
4530  if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
4531  attmask = 0;
4532  else
4533  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4534  mode, ACLMASK_ANY);
4535 
4536  ReleaseSysCache(attTuple);
4537 
4538  if (attmask != 0)
4539  {
4540  result = ACLCHECK_OK;
4541  if (how == ACLMASK_ANY)
4542  break; /* succeed on any success */
4543  }
4544  else
4545  {
4546  result = ACLCHECK_NO_PRIV;
4547  if (how == ACLMASK_ALL)
4548  break; /* fail on any failure */
4549  }
4550  }
4551 
4552  return result;
4553 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3687
#define Int16GetDatum(X)
Definition: postgres.h:451
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
uint32 AclMode
Definition: parsenodes.h:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
AclResult
Definition: acl.h:177
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1127
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
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 3687 of file aclchk.c.

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

3689 {
3690  AclMode result;
3691  HeapTuple classTuple;
3692  HeapTuple attTuple;
3693  Form_pg_class classForm;
3694  Form_pg_attribute attributeForm;
3695  Datum aclDatum;
3696  bool isNull;
3697  Acl *acl;
3698  Oid ownerId;
3699 
3700  /*
3701  * First, get the column's ACL from its pg_attribute entry
3702  */
3703  attTuple = SearchSysCache2(ATTNUM,
3704  ObjectIdGetDatum(table_oid),
3706  if (!HeapTupleIsValid(attTuple))
3707  ereport(ERROR,
3708  (errcode(ERRCODE_UNDEFINED_COLUMN),
3709  errmsg("attribute %d of relation with OID %u does not exist",
3710  attnum, table_oid)));
3711  attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
3712 
3713  /* Throw error on dropped columns, too */
3714  if (attributeForm->attisdropped)
3715  ereport(ERROR,
3716  (errcode(ERRCODE_UNDEFINED_COLUMN),
3717  errmsg("attribute %d of relation with OID %u does not exist",
3718  attnum, table_oid)));
3719 
3720  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3721  &isNull);
3722 
3723  /*
3724  * Here we hard-wire knowledge that the default ACL for a column grants no
3725  * privileges, so that we can fall out quickly in the very common case
3726  * where attacl is null.
3727  */
3728  if (isNull)
3729  {
3730  ReleaseSysCache(attTuple);
3731  return 0;
3732  }
3733 
3734  /*
3735  * Must get the relation's ownerId from pg_class. Since we already found
3736  * a pg_attribute entry, the only likely reason for this to fail is that a
3737  * concurrent DROP of the relation committed since then (which could only
3738  * happen if we don't have lock on the relation). We prefer to report "no
3739  * privileges" rather than failing in such a case, so as to avoid unwanted
3740  * failures in has_column_privilege() tests.
3741  */
3742  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3743  if (!HeapTupleIsValid(classTuple))
3744  {
3745  ReleaseSysCache(attTuple);
3746  return 0;
3747  }
3748  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3749 
3750  ownerId = classForm->relowner;
3751 
3752  ReleaseSysCache(classTuple);
3753 
3754  /* detoast column's ACL if necessary */
3755  acl = DatumGetAclP(aclDatum);
3756 
3757  result = aclmask(acl, roleid, ownerId, mask, how);
3758 
3759  /* if we have a detoasted copy, free it */
3760  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3761  pfree(acl);
3762 
3763  ReleaseSysCache(attTuple);
3764 
3765  return result;
3766 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
#define Int16GetDatum(X)
Definition: postgres.h:451
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1127
#define DatumGetPointer(X)
Definition: postgres.h:549
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_class_aclcheck()

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

Definition at line 4563 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(), statext_is_compatible_clause(), transformTableLikeClause(), and truncate_check_perms().

4564 {
4565  if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
4566  return ACLCHECK_OK;
4567  else
4568  return ACLCHECK_NO_PRIV;
4569 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3772

◆ pg_class_aclmask()

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

Definition at line 3772 of file aclchk.c.

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

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

3774 {
3775  AclMode result;
3776  HeapTuple tuple;
3777  Form_pg_class classForm;
3778  Datum aclDatum;
3779  bool isNull;
3780  Acl *acl;
3781  Oid ownerId;
3782 
3783  /*
3784  * Must get the relation's tuple from pg_class
3785  */
3786  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3787  if (!HeapTupleIsValid(tuple))
3788  ereport(ERROR,
3790  errmsg("relation with OID %u does not exist",
3791  table_oid)));
3792  classForm = (Form_pg_class) GETSTRUCT(tuple);
3793 
3794  /*
3795  * Deny anyone permission to update a system catalog unless
3796  * pg_authid.rolsuper is set.
3797  *
3798  * As of 7.4 we have some updatable system views; those shouldn't be
3799  * protected in this way. Assume the view rules can take care of
3800  * themselves. ACL_USAGE is if we ever have system sequences.
3801  */
3802  if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3803  IsSystemClass(table_oid, classForm) &&
3804  classForm->relkind != RELKIND_VIEW &&
3805  !superuser_arg(roleid))
3807 
3808  /*
3809  * Otherwise, superusers bypass all permission-checking.
3810  */
3811  if (superuser_arg(roleid))
3812  {
3813  ReleaseSysCache(tuple);
3814  return mask;
3815  }
3816 
3817  /*
3818  * Normal case: get the relation's ACL from pg_class
3819  */
3820  ownerId = classForm->relowner;
3821 
3822  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
3823  &isNull);
3824  if (isNull)
3825  {
3826  /* No ACL, so build default ACL */
3827  switch (classForm->relkind)
3828  {
3829  case RELKIND_SEQUENCE:
3830  acl = acldefault(OBJECT_SEQUENCE, ownerId);
3831  break;
3832  default:
3833  acl = acldefault(OBJECT_TABLE, ownerId);
3834  break;
3835  }
3836  aclDatum = (Datum) 0;
3837  }
3838  else
3839  {
3840  /* detoast rel's ACL if necessary */
3841  acl = DatumGetAclP(aclDatum);
3842  }
3843 
3844  result = aclmask(acl, roleid, ownerId, mask, how);
3845 
3846  /* if we have a detoasted copy, free it */
3847  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3848  pfree(acl);
3849 
3850  ReleaseSysCache(tuple);
3851 
3852  return result;
3853 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:73
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
int errcode(int sqlerrcode)
Definition: elog.c:610
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
#define ACL_DELETE
Definition: parsenodes.h:77
unsigned int Oid
Definition: postgres_ext.h:31
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition: catalog.c:80
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_USAGE
Definition: parsenodes.h:82
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
#define ACL_UPDATE
Definition: parsenodes.h:76
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ACL_INSERT
Definition: parsenodes.h:74
#define DatumGetPointer(X)
Definition: postgres.h:549
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define ACL_TRUNCATE
Definition: parsenodes.h:78

◆ pg_class_ownercheck()

bool pg_class_ownercheck ( Oid  class_oid,
Oid  roleid 
)

Definition at line 4687 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(), ATExecChangeOwner(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), cluster_rel(), CreateStatistics(), DefineQueryRewrite(), EnableDisableRule(), ExecuteTruncateGuts(), get_tables_to_cluster(), gin_clean_pending_list(), MergeAttributes(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveRoleFromObjectPolicy(), renameatt_check(), RI_Initial_Check(), and vacuum_is_relation_owner().

4688 {
4689  HeapTuple tuple;
4690  Oid ownerId;
4691 
4692  /* Superusers bypass all permission checking. */
4693  if (superuser_arg(roleid))
4694  return true;
4695 
4696  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
4697  if (!HeapTupleIsValid(tuple))
4698  ereport(ERROR,
4700  errmsg("relation with OID %u does not exist", class_oid)));
4701 
4702  ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
4703 
4704  ReleaseSysCache(tuple);
4705 
4706  return has_privs_of_role(roleid, ownerId);
4707 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:73
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_collation_ownercheck()

bool pg_collation_ownercheck ( Oid  coll_oid,
Oid  roleid 
)

Definition at line 5131 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().

5132 {
5133  HeapTuple tuple;
5134  Oid ownerId;
5135 
5136  /* Superusers bypass all permission checking. */
5137  if (superuser_arg(roleid))
5138  return true;
5139 
5140  tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid));
5141  if (!HeapTupleIsValid(tuple))
5142  ereport(ERROR,
5143  (errcode(ERRCODE_UNDEFINED_OBJECT),
5144  errmsg("collation with OID %u does not exist", coll_oid)));
5145 
5146  ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner;
5147 
5148  ReleaseSysCache(tuple);
5149 
5150  return has_privs_of_role(roleid, ownerId);
5151 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_conversion_ownercheck()

bool pg_conversion_ownercheck ( Oid  conv_oid,
Oid  roleid 
)

Definition at line 5157 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().

5158 {
5159  HeapTuple tuple;
5160  Oid ownerId;
5161 
5162  /* Superusers bypass all permission checking. */
5163  if (superuser_arg(roleid))
5164  return true;
5165 
5166  tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid));
5167  if (!HeapTupleIsValid(tuple))
5168  ereport(ERROR,
5169  (errcode(ERRCODE_UNDEFINED_OBJECT),
5170  errmsg("conversion with OID %u does not exist", conv_oid)));
5171 
5172  ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
5173 
5174  ReleaseSysCache(tuple);
5175 
5176  return has_privs_of_role(roleid, ownerId);
5177 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:61
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_database_aclcheck()

◆ pg_database_aclmask()

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

Definition at line 3859 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_database_aclcheck().

3861 {
3862  AclMode result;
3863  HeapTuple tuple;
3864  Datum aclDatum;
3865  bool isNull;
3866  Acl *acl;
3867  Oid ownerId;
3868 
3869  /* Superusers bypass all permission checking. */
3870  if (superuser_arg(roleid))
3871  return mask;
3872 
3873  /*
3874  * Get the database's ACL from pg_database
3875  */
3876  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
3877  if (!HeapTupleIsValid(tuple))
3878  ereport(ERROR,
3879  (errcode(ERRCODE_UNDEFINED_DATABASE),
3880  errmsg("database with OID %u does not exist", db_oid)));
3881 
3882  ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
3883 
3884  aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
3885  &isNull);
3886  if (isNull)
3887  {
3888  /* No ACL, so build default ACL */
3889  acl = acldefault(OBJECT_DATABASE, ownerId);
3890  aclDatum = (Datum) 0;
3891  }
3892  else
3893  {
3894  /* detoast ACL if necessary */
3895  acl = DatumGetAclP(aclDatum);
3896  }
3897 
3898  result = aclmask(acl, roleid, ownerId, mask, how);
3899 
3900  /* if we have a detoasted copy, free it */
3901  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3902  pfree(acl);
3903 
3904  ReleaseSysCache(tuple);
3905 
3906  return result;
3907 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_database * Form_pg_database
Definition: pg_database.h:81
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
int errcode(int sqlerrcode)
Definition: elog.c:610
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_database_ownercheck()

bool pg_database_ownercheck ( Oid  db_oid,
Oid  roleid 
)

Definition at line 5105 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(), check_object_ownership(), createdb(), dropdb(), movedb(), ReindexMultipleTables(), RenameDatabase(), and vacuum_is_relation_owner().

5106 {
5107  HeapTuple tuple;
5108  Oid dba;
5109 
5110  /* Superusers bypass all permission checking. */
5111  if (superuser_arg(roleid))
5112  return true;
5113 
5114  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
5115  if (!HeapTupleIsValid(tuple))
5116  ereport(ERROR,
5117  (errcode(ERRCODE_UNDEFINED_DATABASE),
5118  errmsg("database with OID %u does not exist", db_oid)));
5119 
5120  dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
5121 
5122  ReleaseSysCache(tuple);
5123 
5124  return has_privs_of_role(roleid, dba);
5125 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_database * Form_pg_database
Definition: pg_database.h:81
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_event_trigger_ownercheck()

bool pg_event_trigger_ownercheck ( Oid  et_oid,
Oid  roleid 
)

Definition at line 5078 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().

5079 {
5080  HeapTuple tuple;
5081  Oid ownerId;
5082 
5083  /* Superusers bypass all permission checking. */
5084  if (superuser_arg(roleid))
5085  return true;
5086 
5088  if (!HeapTupleIsValid(tuple))
5089  ereport(ERROR,
5090  (errcode(ERRCODE_UNDEFINED_OBJECT),
5091  errmsg("event trigger with OID %u does not exist",
5092  et_oid)));
5093 
5094  ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner;
5095 
5096  ReleaseSysCache(tuple);
5097 
5098  return has_privs_of_role(roleid, ownerId);
5099 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_extension_ownercheck()

bool pg_extension_ownercheck ( Oid  ext_oid,
Oid  roleid 
)

Definition at line 5183 of file aclchk.c.

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

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

5184 {
5185  Relation pg_extension;
5186  ScanKeyData entry[1];
5187  SysScanDesc scan;
5188  HeapTuple tuple;
5189  Oid ownerId;
5190 
5191  /* Superusers bypass all permission checking. */
5192  if (superuser_arg(roleid))
5193  return true;
5194 
5195  /* There's no syscache for pg_extension, so do it the hard way */
5196  pg_extension = table_open(ExtensionRelationId, AccessShareLock);
5197 
5198  ScanKeyInit(&entry[0],
5199  Anum_pg_extension_oid,
5200  BTEqualStrategyNumber, F_OIDEQ,
5201  ObjectIdGetDatum(ext_oid));
5202 
5203  scan = systable_beginscan(pg_extension,
5204  ExtensionOidIndexId, true,
5205  NULL, 1, entry);
5206 
5207  tuple = systable_getnext(scan);
5208  if (!HeapTupleIsValid(tuple))
5209  ereport(ERROR,
5210  (errcode(ERRCODE_UNDEFINED_OBJECT),
5211  errmsg("extension with OID %u does not exist", ext_oid)));
5212 
5213  ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner;
5214 
5215  systable_endscan(scan);
5216  table_close(pg_extension, AccessShareLock);
5217 
5218  return has_privs_of_role(roleid, ownerId);
5219 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
#define ExtensionOidIndexId
Definition: indexing.h:323
FormData_pg_extension * Form_pg_extension
Definition: pg_extension.h:50
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#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 4242 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_foreign_data_wrapper_aclcheck().

4244 {
4245  AclMode result;
4246  HeapTuple tuple;
4247  Datum aclDatum;
4248  bool isNull;
4249  Acl *acl;
4250  Oid ownerId;
4251 
4253 
4254  /* Bypass permission checks for superusers */
4255  if (superuser_arg(roleid))
4256  return mask;
4257 
4258  /*
4259  * Must get the FDW's tuple from pg_foreign_data_wrapper
4260  */
4262  if (!HeapTupleIsValid(tuple))
4263  ereport(ERROR,
4264  (errcode(ERRCODE_UNDEFINED_OBJECT),
4265  errmsg("foreign-data wrapper with OID %u does not exist",
4266  fdw_oid)));
4267  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
4268 
4269  /*
4270  * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
4271  */
4272  ownerId = fdwForm->fdwowner;
4273 
4274  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
4275  Anum_pg_foreign_data_wrapper_fdwacl, &isNull);
4276  if (isNull)
4277  {
4278  /* No ACL, so build default ACL */
4279  acl = acldefault(OBJECT_FDW, ownerId);
4280  aclDatum = (Datum) 0;
4281  }
4282  else
4283  {
4284  /* detoast rel's ACL if necessary */
4285  acl = DatumGetAclP(aclDatum);
4286  }
4287 
4288  result = aclmask(acl, roleid, ownerId, mask, how);
4289 
4290  /* if we have a detoasted copy, free it */
4291  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4292  pfree(acl);
4293 
4294  ReleaseSysCache(tuple);
4295 
4296  return result;
4297 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
int errcode(int sqlerrcode)
Definition: elog.c:610
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_foreign_data_wrapper_ownercheck()

bool pg_foreign_data_wrapper_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 5024 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().

5025 {
5026  HeapTuple tuple;
5027  Oid ownerId;
5028 
5029  /* Superusers bypass all permission checking. */
5030  if (superuser_arg(roleid))
5031  return true;
5032 
5034  if (!HeapTupleIsValid(tuple))
5035  ereport(ERROR,
5036  (errcode(ERRCODE_UNDEFINED_OBJECT),
5037  errmsg("foreign-data wrapper with OID %u does not exist",
5038  srv_oid)));
5039 
5040  ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner;
5041 
5042  ReleaseSysCache(tuple);
5043 
5044  return has_privs_of_role(roleid, ownerId);
5045 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_foreign_server_aclcheck()

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

Definition at line 4663 of file aclchk.c.

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

Referenced by CreateForeignTable(), get_connect_string(), has_server_privilege_id(), has_server_privilege_id_id(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_id(), has_server_privilege_name_name(), ImportForeignSchema(), and user_mapping_ddl_aclcheck().

4664 {
4665  if (pg_foreign_server_aclmask(srv_oid, roleid, mode, ACLMASK_ANY) != 0)
4666  return ACLCHECK_OK;
4667  else
4668  return ACLCHECK_NO_PRIV;
4669 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:4304

◆ pg_foreign_server_aclmask()

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

Definition at line 4304 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_foreign_server_aclcheck().

4306 {
4307  AclMode result;
4308  HeapTuple tuple;
4309  Datum aclDatum;
4310  bool isNull;
4311  Acl *acl;
4312  Oid ownerId;
4313 
4314  Form_pg_foreign_server srvForm;
4315 
4316  /* Bypass permission checks for superusers */
4317  if (superuser_arg(roleid))
4318  return mask;
4319 
4320  /*
4321  * Must get the FDW's tuple from pg_foreign_data_wrapper
4322  */
4324  if (!HeapTupleIsValid(tuple))
4325  ereport(ERROR,
4326  (errcode(ERRCODE_UNDEFINED_OBJECT),
4327  errmsg("foreign server with OID %u does not exist",
4328  srv_oid)));
4329  srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
4330 
4331  /*
4332  * Normal case: get the foreign server's ACL from pg_foreign_server
4333  */
4334  ownerId = srvForm->srvowner;
4335 
4336  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
4337  Anum_pg_foreign_server_srvacl, &isNull);
4338  if (isNull)
4339  {
4340  /* No ACL, so build default ACL */
4341  acl = acldefault(OBJECT_FOREIGN_SERVER, ownerId);
4342  aclDatum = (Datum) 0;
4343  }
4344  else
4345  {
4346  /* detoast rel's ACL if necessary */
4347  acl = DatumGetAclP(aclDatum);
4348  }
4349 
4350  result = aclmask(acl, roleid, ownerId, mask, how);
4351 
4352  /* if we have a detoasted copy, free it */
4353  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4354  pfree(acl);
4355 
4356  ReleaseSysCache(tuple);
4357 
4358  return result;
4359 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
int errcode(int sqlerrcode)
Definition: elog.c:610
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
FormData_pg_foreign_server * Form_pg_foreign_server
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_foreign_server_ownercheck()

bool pg_foreign_server_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

Definition at line 5051 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().

5052 {
5053  HeapTuple tuple;
5054  Oid ownerId;
5055 
5056  /* Superusers bypass all permission checking. */
5057  if (superuser_arg(roleid))
5058  return true;
5059 
5061  if (!HeapTupleIsValid(tuple))
5062  ereport(ERROR,
5063  (errcode(ERRCODE_UNDEFINED_OBJECT),
5064  errmsg("foreign server with OID %u does not exist",
5065  srv_oid)));
5066 
5067  ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner;
5068 
5069  ReleaseSysCache(tuple);
5070 
5071  return has_privs_of_role(roleid, ownerId);
5072 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_foreign_server * Form_pg_foreign_server
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_language_aclcheck()

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

Definition at line 4599 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().

4600 {
4601  if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
4602  return ACLCHECK_OK;
4603  else
4604  return ACLCHECK_NO_PRIV;
4605 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3967

◆ pg_language_aclmask()

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

Definition at line 3967 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_language_aclcheck().

3969 {
3970  AclMode result;
3971  HeapTuple tuple;
3972  Datum aclDatum;
3973  bool isNull;
3974  Acl *acl;
3975  Oid ownerId;
3976 
3977  /* Superusers bypass all permission checking. */
3978  if (superuser_arg(roleid))
3979  return mask;
3980 
3981  /*
3982  * Get the language's ACL from pg_language
3983  */
3984  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
3985  if (!HeapTupleIsValid(tuple))
3986  ereport(ERROR,
3987  (errcode(ERRCODE_UNDEFINED_OBJECT),
3988  errmsg("language with OID %u does not exist", lang_oid)));
3989 
3990  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
3991 
3992  aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
3993  &isNull);
3994  if (isNull)
3995  {
3996  /* No ACL, so build default ACL */
3997  acl = acldefault(OBJECT_LANGUAGE, ownerId);
3998  aclDatum = (Datum) 0;
3999  }
4000  else
4001  {
4002  /* detoast ACL if necessary */
4003  acl = DatumGetAclP(aclDatum);
4004  }
4005 
4006  result = aclmask(acl, roleid, ownerId, mask, how);
4007 
4008  /* if we have a detoasted copy, free it */
4009  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4010  pfree(acl);
4011 
4012  ReleaseSysCache(tuple);
4013 
4014  return result;
4015 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1313
int errcode(int sqlerrcode)
Definition: elog.c:610
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:741
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:351
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define DatumGetPointer(X)
Definition: postgres.h:549
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_language_ownercheck()

bool pg_language_ownercheck ( Oid  lan_oid,
Oid  roleid 
)

Definition at line 4791 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 CreateProceduralLanguage().

4792 {
4793  HeapTuple tuple;
4794  Oid ownerId;
4795 
4796  /* Superusers bypass all permission checking. */
4797  if (superuser_arg(roleid))
4798  return true;
4799 
4800  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid));
4801  if (!HeapTupleIsValid(tuple))
4802  ereport(ERROR,
4803  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4804  errmsg("language with OID %u does not exist", lan_oid)));
4805 
4806  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
4807 
4808  ReleaseSysCache(tuple);
4809 
4810  return has_privs_of_role(roleid, ownerId);
4811 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4892
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
bool superuser_arg(Oid roleid)
Definition: superuser.c:56
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_language * Form_pg_language
Definition: pg_language.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4611 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().

4613 {
4614  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4615  ACLMASK_ANY, snapshot) != 0)
4616  return ACLCHECK_OK;
4617  else
4618  return ACLCHECK_NO_PRIV;
4619 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:4030

◆ pg_largeobject_aclmask_snapshot()

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

Definition at line 4030 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().

4033 {
4034  AclMode result;
4035  Relation pg_lo_meta;
4036  ScanKeyData entry[1];
4037  SysScanDesc scan;
4038  HeapTuple tuple;
4039  Datum aclDatum;
4040  bool isNull;
4041  Acl *acl;
4042  Oid ownerId;
4043 
4044  /* Superusers bypass all permission checking. */
4045  if (superuser_arg(roleid))
4046  return mask;
4047 
4048  /*
4049  * Get the largeobject's ACL from pg_largeobject_metadata
4050  */
4051  pg_lo_meta = table_open(LargeObjectMetadataRelationId,
4052  AccessShareLock);
4053 
4054  ScanKeyInit(&entry[0],
4055  Anum_pg_largeobject_metadata_oid,
4056  BTEqualStrategyNumber, F_OIDEQ,
4057  ObjectIdGetDatum(lobj_oid));
4058 
4059  scan = systable_beginscan(pg_lo_meta,
4061  snapshot, 1, entry);
4062 
4063  tuple = systable_getnext(scan);
4064  if (!HeapTupleIsValid(tuple))
4065  ereport(ERROR,
4066  (errcode(ERRCODE_UNDEFINED_OBJECT),
4067  errmsg("large object %u does not exist", lobj_oid)));
4068 
4069  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
4070 
4071  aclDatum = heap_getattr(tuple, Anum_pg_largeobject_metadata_lomacl,
4072  RelationGetDescr(pg_lo_meta), &isNull);
4073 
4074  if (isNull)
4075  {
4076  /* No ACL, so build default ACL */
4077  acl = acldefault(OBJECT_LARGEOBJECT, ownerId);
4078  aclDatum = (Datum) 0;
4079  }
4080  else
4081  {
4082  /* detoast ACL if necessary */
4083  acl = DatumGetAclP(aclDatum);
4084  }
4085 
4086  result = aclmask(acl, roleid, ownerId, mask, how);
4087 
4088  /* if we have a detoasted copy, free it */
4089  if (acl && (Pointer) acl !=