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)
 
void RemoveDefaultACLById (Oid defaclOid)
 
AclMode pg_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_database_aclmask (Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_proc_aclmask (Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_language_aclmask (Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_largeobject_aclmask_snapshot (Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
 
AclMode pg_namespace_aclmask (Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_tablespace_aclmask (Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_data_wrapper_aclmask (Oid fdw_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_server_aclmask (Oid srv_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_type_aclmask (Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_database_aclcheck (Oid db_oid, Oid roleid, AclMode mode)
 
AclResult pg_proc_aclcheck (Oid proc_oid, Oid roleid, AclMode mode)
 
AclResult pg_language_aclcheck (Oid lang_oid, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lang_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
AclResult pg_namespace_aclcheck (Oid nsp_oid, Oid roleid, AclMode mode)
 
AclResult pg_tablespace_aclcheck (Oid spc_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_data_wrapper_aclcheck (Oid fdw_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_server_aclcheck (Oid srv_oid, Oid roleid, AclMode mode)
 
AclResult pg_type_aclcheck (Oid type_oid, Oid roleid, AclMode mode)
 
void aclcheck_error (AclResult aclerr, 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 3353 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(), ATPrepSetStatistics(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), create_proc_lang(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateTransform(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), 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(), LockTableRecurse(), 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_rel(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

3355 {
3356  switch (aclerr)
3357  {
3358  case ACLCHECK_OK:
3359  /* no error, so return to caller */
3360  break;
3361  case ACLCHECK_NO_PRIV:
3362  {
3363  const char *msg = "???";
3364 
3365  switch (objtype)
3366  {
3367  case OBJECT_AGGREGATE:
3368  msg = gettext_noop("permission denied for aggregate %s");
3369  break;
3370  case OBJECT_COLLATION:
3371  msg = gettext_noop("permission denied for collation %s");
3372  break;
3373  case OBJECT_COLUMN:
3374  msg = gettext_noop("permission denied for column %s");
3375  break;
3376  case OBJECT_CONVERSION:
3377  msg = gettext_noop("permission denied for conversion %s");
3378  break;
3379  case OBJECT_DATABASE:
3380  msg = gettext_noop("permission denied for database %s");
3381  break;
3382  case OBJECT_DOMAIN:
3383  msg = gettext_noop("permission denied for domain %s");
3384  break;
3385  case OBJECT_EVENT_TRIGGER:
3386  msg = gettext_noop("permission denied for event trigger %s");
3387  break;
3388  case OBJECT_EXTENSION:
3389  msg = gettext_noop("permission denied for extension %s");
3390  break;
3391  case OBJECT_FDW:
3392  msg = gettext_noop("permission denied for foreign-data wrapper %s");
3393  break;
3394  case OBJECT_FOREIGN_SERVER:
3395  msg = gettext_noop("permission denied for foreign server %s");
3396  break;
3397  case OBJECT_FOREIGN_TABLE:
3398  msg = gettext_noop("permission denied for foreign table %s");
3399  break;
3400  case OBJECT_FUNCTION:
3401  msg = gettext_noop("permission denied for function %s");
3402  break;
3403  case OBJECT_INDEX:
3404  msg = gettext_noop("permission denied for index %s");
3405  break;
3406  case OBJECT_LANGUAGE:
3407  msg = gettext_noop("permission denied for language %s");
3408  break;
3409  case OBJECT_LARGEOBJECT:
3410  msg = gettext_noop("permission denied for large object %s");
3411  break;
3412  case OBJECT_MATVIEW:
3413  msg = gettext_noop("permission denied for materialized view %s");
3414  break;
3415  case OBJECT_OPCLASS:
3416  msg = gettext_noop("permission denied for operator class %s");
3417  break;
3418  case OBJECT_OPERATOR:
3419  msg = gettext_noop("permission denied for operator %s");
3420  break;
3421  case OBJECT_OPFAMILY:
3422  msg = gettext_noop("permission denied for operator family %s");
3423  break;
3424  case OBJECT_POLICY:
3425  msg = gettext_noop("permission denied for policy %s");
3426  break;
3427  case OBJECT_PROCEDURE:
3428  msg = gettext_noop("permission denied for procedure %s");
3429  break;
3430  case OBJECT_PUBLICATION:
3431  msg = gettext_noop("permission denied for publication %s");
3432  break;
3433  case OBJECT_ROUTINE:
3434  msg = gettext_noop("permission denied for routine %s");
3435  break;
3436  case OBJECT_SCHEMA:
3437  msg = gettext_noop("permission denied for schema %s");
3438  break;
3439  case OBJECT_SEQUENCE:
3440  msg = gettext_noop("permission denied for sequence %s");
3441  break;
3442  case OBJECT_STATISTIC_EXT:
3443  msg = gettext_noop("permission denied for statistics object %s");
3444  break;
3445  case OBJECT_SUBSCRIPTION:
3446  msg = gettext_noop("permission denied for subscription %s");
3447  break;
3448  case OBJECT_TABLE:
3449  msg = gettext_noop("permission denied for table %s");
3450  break;
3451  case OBJECT_TABLESPACE:
3452  msg = gettext_noop("permission denied for tablespace %s");
3453  break;
3455  msg = gettext_noop("permission denied for text search configuration %s");
3456  break;
3457  case OBJECT_TSDICTIONARY:
3458  msg = gettext_noop("permission denied for text search dictionary %s");
3459  break;
3460  case OBJECT_TYPE:
3461  msg = gettext_noop("permission denied for type %s");
3462  break;
3463  case OBJECT_VIEW:
3464  msg = gettext_noop("permission denied for view %s");
3465  break;
3466  /* these currently aren't used */
3467  case OBJECT_ACCESS_METHOD:
3468  case OBJECT_AMOP:
3469  case OBJECT_AMPROC:
3470  case OBJECT_ATTRIBUTE:
3471  case OBJECT_CAST:
3472  case OBJECT_DEFAULT:
3473  case OBJECT_DEFACL:
3474  case OBJECT_DOMCONSTRAINT:
3476  case OBJECT_ROLE:
3477  case OBJECT_RULE:
3478  case OBJECT_TABCONSTRAINT:
3479  case OBJECT_TRANSFORM:
3480  case OBJECT_TRIGGER:
3481  case OBJECT_TSPARSER:
3482  case OBJECT_TSTEMPLATE:
3483  case OBJECT_USER_MAPPING:
3484  elog(ERROR, "unsupported object type %d", objtype);
3485  }
3486 
3487  ereport(ERROR,
3488  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3489  errmsg(msg, objectname)));
3490  break;
3491  }
3492  case ACLCHECK_NOT_OWNER:
3493  {
3494  const char *msg = "???";
3495 
3496  switch (objtype)
3497  {
3498  case OBJECT_AGGREGATE:
3499  msg = gettext_noop("must be owner of aggregate %s");
3500  break;
3501  case OBJECT_COLLATION:
3502  msg = gettext_noop("must be owner of collation %s");
3503  break;
3504  case OBJECT_CONVERSION:
3505  msg = gettext_noop("must be owner of conversion %s");
3506  break;
3507  case OBJECT_DATABASE:
3508  msg = gettext_noop("must be owner of database %s");
3509  break;
3510  case OBJECT_DOMAIN:
3511  msg = gettext_noop("must be owner of domain %s");
3512  break;
3513  case OBJECT_EVENT_TRIGGER:
3514  msg = gettext_noop("must be owner of event trigger %s");
3515  break;
3516  case OBJECT_EXTENSION:
3517  msg = gettext_noop("must be owner of extension %s");
3518  break;
3519  case OBJECT_FDW:
3520  msg = gettext_noop("must be owner of foreign-data wrapper %s");
3521  break;
3522  case OBJECT_FOREIGN_SERVER:
3523  msg = gettext_noop("must be owner of foreign server %s");
3524  break;
3525  case OBJECT_FOREIGN_TABLE:
3526  msg = gettext_noop("must be owner of foreign table %s");
3527  break;
3528  case OBJECT_FUNCTION:
3529  msg = gettext_noop("must be owner of function %s");
3530  break;
3531  case OBJECT_INDEX:
3532  msg = gettext_noop("must be owner of index %s");
3533  break;
3534  case OBJECT_LANGUAGE:
3535  msg = gettext_noop("must be owner of language %s");
3536  break;
3537  case OBJECT_LARGEOBJECT:
3538  msg = gettext_noop("must be owner of large object %s");
3539  break;
3540  case OBJECT_MATVIEW:
3541  msg = gettext_noop("must be owner of materialized view %s");
3542  break;
3543  case OBJECT_OPCLASS:
3544  msg = gettext_noop("must be owner of operator class %s");
3545  break;
3546  case OBJECT_OPERATOR:
3547  msg = gettext_noop("must be owner of operator %s");
3548  break;
3549  case OBJECT_OPFAMILY:
3550  msg = gettext_noop("must be owner of operator family %s");
3551  break;
3552  case OBJECT_PROCEDURE:
3553  msg = gettext_noop("must be owner of procedure %s");
3554  break;
3555  case OBJECT_PUBLICATION:
3556  msg = gettext_noop("must be owner of publication %s");
3557  break;
3558  case OBJECT_ROUTINE:
3559  msg = gettext_noop("must be owner of routine %s");
3560  break;
3561  case OBJECT_SEQUENCE:
3562  msg = gettext_noop("must be owner of sequence %s");
3563  break;
3564  case OBJECT_SUBSCRIPTION:
3565  msg = gettext_noop("must be owner of subscription %s");
3566  break;
3567  case OBJECT_TABLE:
3568  msg = gettext_noop("must be owner of table %s");
3569  break;
3570  case OBJECT_TYPE:
3571  msg = gettext_noop("must be owner of type %s");
3572  break;
3573  case OBJECT_VIEW:
3574  msg = gettext_noop("must be owner of view %s");
3575  break;
3576  case OBJECT_SCHEMA:
3577  msg = gettext_noop("must be owner of schema %s");
3578  break;
3579  case OBJECT_STATISTIC_EXT:
3580  msg = gettext_noop("must be owner of statistics object %s");
3581  break;
3582  case OBJECT_TABLESPACE:
3583  msg = gettext_noop("must be owner of tablespace %s");
3584  break;
3586  msg = gettext_noop("must be owner of text search configuration %s");
3587  break;
3588  case OBJECT_TSDICTIONARY:
3589  msg = gettext_noop("must be owner of text search dictionary %s");
3590  break;
3591 
3592  /*
3593  * Special cases: For these, the error message talks
3594  * about "relation", because that's where the
3595  * ownership is attached. See also
3596  * check_object_ownership().
3597  */
3598  case OBJECT_COLUMN:
3599  case OBJECT_POLICY:
3600  case OBJECT_RULE:
3601  case OBJECT_TABCONSTRAINT:
3602  case OBJECT_TRIGGER:
3603  msg = gettext_noop("must be owner of relation %s");
3604  break;
3605  /* these currently aren't used */
3606  case OBJECT_ACCESS_METHOD:
3607  case OBJECT_AMOP:
3608  case OBJECT_AMPROC:
3609  case OBJECT_ATTRIBUTE:
3610  case OBJECT_CAST:
3611  case OBJECT_DEFAULT:
3612  case OBJECT_DEFACL:
3613  case OBJECT_DOMCONSTRAINT:
3615  case OBJECT_ROLE:
3616  case OBJECT_TRANSFORM:
3617  case OBJECT_TSPARSER:
3618  case OBJECT_TSTEMPLATE:
3619  case OBJECT_USER_MAPPING:
3620  elog(ERROR, "unsupported object type %d", objtype);
3621  }
3622 
3623  ereport(ERROR,
3624  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3625  errmsg(msg, objectname)));
3626  break;
3627  }
3628  default:
3629  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3630  break;
3631  }
3632 }
#define gettext_noop(x)
Definition: c.h:1117
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ aclcheck_error_col()

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

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

3638 {
3639  switch (aclerr)
3640  {
3641  case ACLCHECK_OK:
3642  /* no error, so return to caller */
3643  break;
3644  case ACLCHECK_NO_PRIV:
3645  ereport(ERROR,
3646  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3647  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3648  colname, objectname)));
3649  break;
3650  case ACLCHECK_NOT_OWNER:
3651  /* relation msg is OK since columns don't have separate owners */
3652  aclcheck_error(aclerr, objtype, objectname);
3653  break;
3654  default:
3655  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3656  break;
3657  }
3658 }
int errcode(int sqlerrcode)
Definition: elog.c:570
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ aclcheck_error_type()

void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

Definition at line 3666 of file aclchk.c.

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

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

3667 {
3668  Oid element_type = get_element_type(typeOid);
3669 
3670  aclcheck_error(aclerr, OBJECT_TYPE, format_type_be(element_type ? element_type : typeOid));
3671 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2526
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353

◆ aclconcat()

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

Definition at line 428 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

429 {
430  Acl *result_acl;
431 
432  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
433 
434  memcpy(ACL_DAT(result_acl),
435  ACL_DAT(left_acl),
436  ACL_NUM(left_acl) * sizeof(AclItem));
437 
438  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
439  ACL_DAT(right_acl),
440  ACL_NUM(right_acl) * sizeof(AclItem));
441 
442  return result_acl;
443 }
static Acl * allocacl(int n)
Definition: acl.c:377
#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 408 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

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

409 {
410  Acl *result_acl;
411 
412  result_acl = allocacl(ACL_NUM(orig_acl));
413 
414  memcpy(ACL_DAT(result_acl),
415  ACL_DAT(orig_acl),
416  ACL_NUM(orig_acl) * sizeof(AclItem));
417 
418  return result_acl;
419 }
static Acl * allocacl(int n)
Definition: acl.c:377
#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 749 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().

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

References ACL_DAT, and ACL_NUM.

Referenced by get_user_default_acl(), and SetDefaultACL().

511 {
512  /* Check for cases where one or both are empty/null */
513  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
514  {
515  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
516  return true;
517  else
518  return false;
519  }
520  else
521  {
522  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
523  return false;
524  }
525 
526  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
527  return false;
528 
529  if (memcmp(ACL_DAT(left_acl),
530  ACL_DAT(right_acl),
531  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
532  return true;
533 
534  return false;
535 }
#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 496 of file acl.c.

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

Referenced by get_user_default_acl(), and SetDefaultACL().

497 {
498  if (acl != NULL && ACL_NUM(acl) > 1)
499  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
500 }
#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:492
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:670

◆ aclmask()

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

Definition at line 1321 of file acl.c.

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

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

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

◆ aclmembers()

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

Definition at line 1473 of file acl.c.

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

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

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

◆ aclmerge()

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

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

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

◆ aclnewowner()

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

Definition at line 1052 of file acl.c.

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

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

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

◆ aclupdate()

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

Definition at line 931 of file acl.c.

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

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

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

◆ check_is_member_of_role()

void check_is_member_of_role ( Oid  member,
Oid  role 
)

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

4955 {
4956  if (!is_member_of_role(member, role))
4957  ereport(ERROR,
4958  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4959  errmsg("must be member of role \"%s\"",
4960  GetUserNameFromId(role, false))));
4961 }
int errcode(int sqlerrcode)
Definition: elog.c:570
Oid member
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4932
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:795
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ check_rolespec_name()

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

Definition at line 5330 of file acl.c.

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

Referenced by AlterRole(), and AlterRoleSet().

5331 {
5332  if (!role)
5333  return;
5334 
5335  if (role->roletype != ROLESPEC_CSTRING)
5336  return;
5337 
5338  if (IsReservedName(role->rolename))
5339  {
5340  if (detail_msg)
5341  ereport(ERROR,
5342  (errcode(ERRCODE_RESERVED_NAME),
5343  errmsg("role name \"%s\" is reserved",
5344  role->rolename),
5345  errdetail("%s", detail_msg)));
5346  else
5347  ereport(ERROR,
5348  (errcode(ERRCODE_RESERVED_NAME),
5349  errmsg("role name \"%s\" is reserved",
5350  role->rolename)));
5351  }
5352 }
int errcode(int sqlerrcode)
Definition: elog.c:570
bool IsReservedName(const char *name)
Definition: catalog.c:214
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
RoleSpecType roletype
Definition: parsenodes.h:328
char * rolename
Definition: parsenodes.h:329
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

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

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

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 385 of file aclchk.c.

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_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().

386 {
387  InternalGrant istmt;
388  ListCell *cell;
389  const char *errormsg;
390  AclMode all_privileges;
391 
392  /*
393  * Turn the regular GrantStmt into the InternalGrant form.
394  */
395  istmt.is_grant = stmt->is_grant;
396  istmt.objtype = stmt->objtype;
397 
398  /* Collect the OIDs of the target objects */
399  switch (stmt->targtype)
400  {
401  case ACL_TARGET_OBJECT:
402  istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
403  break;
405  istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
406  break;
407  /* ACL_TARGET_DEFAULTS should not be seen here */
408  default:
409  elog(ERROR, "unrecognized GrantStmt.targtype: %d",
410  (int) stmt->targtype);
411  }
412 
413  /* all_privs to be filled below */
414  /* privileges to be filled below */
415  istmt.col_privs = NIL; /* may get filled below */
416  istmt.grantees = NIL; /* filled below */
417  istmt.grant_option = stmt->grant_option;
418  istmt.behavior = stmt->behavior;
419 
420  /*
421  * Convert the RoleSpec list into an Oid list. Note that at this point we
422  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
423  * there shouldn't be any additional work needed to support this case.
424  */
425  foreach(cell, stmt->grantees)
426  {
427  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
428  Oid grantee_uid;
429 
430  switch (grantee->roletype)
431  {
432  case ROLESPEC_PUBLIC:
433  grantee_uid = ACL_ID_PUBLIC;
434  break;
435  default:
436  grantee_uid = get_rolespec_oid(grantee, false);
437  break;
438  }
439  istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
440  }
441 
442  /*
443  * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
444  * bitmask. Note: objtype can't be OBJECT_COLUMN.
445  */
446  switch (stmt->objtype)
447  {
448  case OBJECT_TABLE:
449 
450  /*
451  * Because this might be a sequence, we test both relation and
452  * sequence bits, and later do a more limited test when we know
453  * the object type.
454  */
456  errormsg = gettext_noop("invalid privilege type %s for relation");
457  break;
458  case OBJECT_SEQUENCE:
459  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
460  errormsg = gettext_noop("invalid privilege type %s for sequence");
461  break;
462  case OBJECT_DATABASE:
463  all_privileges = ACL_ALL_RIGHTS_DATABASE;
464  errormsg = gettext_noop("invalid privilege type %s for database");
465  break;
466  case OBJECT_DOMAIN:
467  all_privileges = ACL_ALL_RIGHTS_TYPE;
468  errormsg = gettext_noop("invalid privilege type %s for domain");
469  break;
470  case OBJECT_FUNCTION:
471  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
472  errormsg = gettext_noop("invalid privilege type %s for function");
473  break;
474  case OBJECT_LANGUAGE:
475  all_privileges = ACL_ALL_RIGHTS_LANGUAGE;
476  errormsg = gettext_noop("invalid privilege type %s for language");
477  break;
478  case OBJECT_LARGEOBJECT:
479  all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
480  errormsg = gettext_noop("invalid privilege type %s for large object");
481  break;
482  case OBJECT_SCHEMA:
483  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
484  errormsg = gettext_noop("invalid privilege type %s for schema");
485  break;
486  case OBJECT_PROCEDURE:
487  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
488  errormsg = gettext_noop("invalid privilege type %s for procedure");
489  break;
490  case OBJECT_ROUTINE:
491  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
492  errormsg = gettext_noop("invalid privilege type %s for routine");
493  break;
494  case OBJECT_TABLESPACE:
495  all_privileges = ACL_ALL_RIGHTS_TABLESPACE;
496  errormsg = gettext_noop("invalid privilege type %s for tablespace");
497  break;
498  case OBJECT_TYPE:
499  all_privileges = ACL_ALL_RIGHTS_TYPE;
500  errormsg = gettext_noop("invalid privilege type %s for type");
501  break;
502  case OBJECT_FDW:
503  all_privileges = ACL_ALL_RIGHTS_FDW;
504  errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
505  break;
507  all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER;
508  errormsg = gettext_noop("invalid privilege type %s for foreign server");
509  break;
510  default:
511  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
512  (int) stmt->objtype);
513  /* keep compiler quiet */
514  all_privileges = ACL_NO_RIGHTS;
515  errormsg = NULL;
516  }
517 
518  if (stmt->privileges == NIL)
519  {
520  istmt.all_privs = true;
521 
522  /*
523  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
524  * depending on the object type
525  */
526  istmt.privileges = ACL_NO_RIGHTS;
527  }
528  else
529  {
530  istmt.all_privs = false;
531  istmt.privileges = ACL_NO_RIGHTS;
532 
533  foreach(cell, stmt->privileges)
534  {
535  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
536  AclMode priv;
537 
538  /*
539  * If it's a column-level specification, we just set it aside in
540  * col_privs for the moment; but insist it's for a relation.
541  */
542  if (privnode->cols)
543  {
544  if (stmt->objtype != OBJECT_TABLE)
545  ereport(ERROR,
546  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
547  errmsg("column privileges are only valid for relations")));
548  istmt.col_privs = lappend(istmt.col_privs, privnode);
549  continue;
550  }
551 
552  if (privnode->priv_name == NULL) /* parser mistake? */
553  elog(ERROR, "AccessPriv node must specify privilege or columns");
554  priv = string_to_privilege(privnode->priv_name);
555 
556  if (priv & ~((AclMode) all_privileges))
557  ereport(ERROR,
558  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
559  errmsg(errormsg, privilege_to_string(priv))));
560 
561  istmt.privileges |= priv;
562  }
563  }
564 
565  ExecGrantStmt_oids(&istmt);
566 }
#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:3275
AclMode privileges
bool grant_option
Definition: parsenodes.h:1912
#define gettext_noop(x)
Definition: c.h:1117
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:166
List * cols
Definition: parsenodes.h:1942
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
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:321
bool is_grant
Definition: parsenodes.h:1904
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition: aclchk.c:574
static List * objectNamesToOids(ObjectType objtype, List *objnames)
Definition: aclchk.c:638
RoleSpecType roletype
Definition: parsenodes.h:328
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5225
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:158
List * privileges
Definition: parsenodes.h:1909
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition: aclchk.c:787
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:164
DropBehavior behavior
DropBehavior behavior
Definition: parsenodes.h:1913
#define lfirst(lc)
Definition: pg_list.h:190
List * objects
Definition: parsenodes.h:1907
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:784
#define elog(elevel,...)
Definition: elog.h:226
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:157
ObjectType objtype
Definition: parsenodes.h:1906
#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:3312
List * grantees
Definition: parsenodes.h:1911
GrantTargetType targtype
Definition: parsenodes.h:1905
char * priv_name
Definition: parsenodes.h:1941

◆ get_role_oid()

Oid get_role_oid ( const char *  rolename,
bool  missing_ok 
)

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

5192 {
5193  Oid oid;
5194 
5195  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5197  if (!OidIsValid(oid) && !missing_ok)
5198  ereport(ERROR,
5199  (errcode(ERRCODE_UNDEFINED_OBJECT),
5200  errmsg("role \"%s\" does not exist", rolname)));
5201  return oid;
5202 }
NameData rolname
Definition: pg_authid.h:34
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:192
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5308 of file acl.c.

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

Referenced by AddRoleMems(), and DelRoleMems().

5309 {
5310  HeapTuple tp;
5311  Form_pg_authid authForm;
5312  char *rolename;
5313 
5314  tp = get_rolespec_tuple(role);
5315  authForm = (Form_pg_authid) GETSTRUCT(tp);
5316  rolename = pstrdup(NameStr(authForm->rolname));
5317  ReleaseSysCache(tp);
5318 
5319  return rolename;
5320 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char * pstrdup(const char *in)
Definition: mcxt.c:1161
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5263
#define NameStr(name)
Definition: c.h:609

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

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

5226 {
5227  Oid oid;
5228 
5229  switch (role->roletype)
5230  {
5231  case ROLESPEC_CSTRING:
5232  Assert(role->rolename);
5233  oid = get_role_oid(role->rolename, missing_ok);
5234  break;
5235 
5236  case ROLESPEC_CURRENT_USER:
5237  oid = GetUserId();
5238  break;
5239 
5240  case ROLESPEC_SESSION_USER:
5241  oid = GetSessionUserId();
5242  break;
5243 
5244  case ROLESPEC_PUBLIC:
5245  ereport(ERROR,
5246  (errcode(ERRCODE_UNDEFINED_OBJECT),
5247  errmsg("role \"%s\" does not exist", "public")));
5248  oid = InvalidOid; /* make compiler happy */
5249  break;
5250 
5251  default:
5252  elog(ERROR, "unexpected role type %d", role->roletype);
5253  }
5254 
5255  return oid;
5256 }
Oid GetUserId(void)
Definition: miscinit.c:380
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:414
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5191
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
RoleSpecType roletype
Definition: parsenodes.h:328
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:732
char * rolename
Definition: parsenodes.h:329
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

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

5264 {
5265  HeapTuple tuple;
5266 
5267  switch (role->roletype)
5268  {
5269  case ROLESPEC_CSTRING:
5270  Assert(role->rolename);
5272  if (!HeapTupleIsValid(tuple))
5273  ereport(ERROR,
5274  (errcode(ERRCODE_UNDEFINED_OBJECT),
5275  errmsg("role \"%s\" does not exist", role->rolename)));
5276  break;
5277 
5278  case ROLESPEC_CURRENT_USER:
5279  tuple = SearchSysCache1(AUTHOID, GetUserId());
5280  if (!HeapTupleIsValid(tuple))
5281  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5282  break;
5283 
5284  case ROLESPEC_SESSION_USER:
5286  if (!HeapTupleIsValid(tuple))
5287  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5288  break;
5289 
5290  case ROLESPEC_PUBLIC:
5291  ereport(ERROR,
5292  (errcode(ERRCODE_UNDEFINED_OBJECT),
5293  errmsg("role \"%s\" does not exist", "public")));
5294  tuple = NULL; /* make compiler happy */
5295  break;
5296 
5297  default:
5298  elog(ERROR, "unexpected role type %d", role->roletype);
5299  }
5300 
5301  return tuple;
5302 }
Oid GetUserId(void)
Definition: miscinit.c:380
int errcode(int sqlerrcode)
Definition: elog.c:570
Oid GetSessionUserId(void)
Definition: miscinit.c:414
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
RoleSpecType roletype
Definition: parsenodes.h:328
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:732
char * rolename
Definition: parsenodes.h:329
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ get_user_default_acl()

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

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

5459 {
5460  Acl *result;
5461  Acl *glob_acl;
5462  Acl *schema_acl;
5463  Acl *def_acl;
5464  char defaclobjtype;
5465 
5466  /*
5467  * Use NULL during bootstrap, since pg_default_acl probably isn't there
5468  * yet.
5469  */
5471  return NULL;
5472 
5473  /* Check if object type is supported in pg_default_acl */
5474  switch (objtype)
5475  {
5476  case OBJECT_TABLE:
5477  defaclobjtype = DEFACLOBJ_RELATION;
5478  break;
5479 
5480  case OBJECT_SEQUENCE:
5481  defaclobjtype = DEFACLOBJ_SEQUENCE;
5482  break;
5483 
5484  case OBJECT_FUNCTION:
5485  defaclobjtype = DEFACLOBJ_FUNCTION;
5486  break;
5487 
5488  case OBJECT_TYPE:
5489  defaclobjtype = DEFACLOBJ_TYPE;
5490  break;
5491 
5492  case OBJECT_SCHEMA:
5493  defaclobjtype = DEFACLOBJ_NAMESPACE;
5494  break;
5495 
5496  default:
5497  return NULL;
5498  }
5499 
5500  /* Look up the relevant pg_default_acl entries */
5501  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5502  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5503 
5504  /* Quick out if neither entry exists */
5505  if (glob_acl == NULL && schema_acl == NULL)
5506  return NULL;
5507 
5508  /* We need to know the hard-wired default value, too */
5509  def_acl = acldefault(objtype, ownerId);
5510 
5511  /* If there's no global entry, substitute the hard-wired default */
5512  if (glob_acl == NULL)
5513  glob_acl = def_acl;
5514 
5515  /* Merge in any per-schema privileges */
5516  result = aclmerge(glob_acl, schema_acl, ownerId);
5517 
5518  /*
5519  * For efficiency, we want to return NULL if the result equals default.
5520  * This requires sorting both arrays to get an accurate comparison.
5521  */
5522  aclitemsort(result);
5523  aclitemsort(def_acl);
5524  if (aclequal(result, def_acl))
5525  result = NULL;
5526 
5527  return result;
5528 }
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:749
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:5423
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:510
#define InvalidOid
Definition: postgres_ext.h:36
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:452
void aclitemsort(Acl *acl)
Definition: acl.c:496
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 5399 of file aclchk.c.

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

Referenced by check_enable_rls(), and RI_Initial_Check().

5400 {
5401  bool result = false;
5402  HeapTuple utup;
5403 
5404  /* Superusers bypass all permission checking. */
5405  if (superuser_arg(roleid))
5406  return true;
5407 
5408  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5409  if (HeapTupleIsValid(utup))
5410  {
5411  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
5412  ReleaseSysCache(utup);
5413  }
5414  return result;
5415 }
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:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 5380 of file aclchk.c.

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

Referenced by check_object_ownership(), and have_createrole_privilege().

5381 {
5382  bool result = false;
5383  HeapTuple utup;
5384 
5385  /* Superusers bypass all permission checking. */
5386  if (superuser_arg(roleid))
5387  return true;
5388 
5389  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5390  if (HeapTupleIsValid(utup))
5391  {
5392  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
5393  ReleaseSysCache(utup);
5394  }
5395  return result;
5396 }
#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:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4908 of file acl.c.

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

Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), check_role_for_policy(), DropOwnedObjects(), pg_class_ownercheck(), pg_collation_ownercheck(), pg_conversion_ownercheck(), pg_database_ownercheck(), pg_event_trigger_ownercheck(), pg_extension_ownercheck(), pg_foreign_data_wrapper_ownercheck(), pg_foreign_server_ownercheck(), pg_language_ownercheck(), pg_largeobject_ownercheck(), pg_namespace_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_publication_ownercheck(), pg_role_aclcheck(), pg_signal_backend(), pg_stat_get_activity(), pg_stat_get_backend_activity(), pg_stat_get_backend_activity_start(), pg_stat_get_backend_client_addr(), pg_stat_get_backend_client_port(), pg_stat_get_backend_start(), pg_stat_get_backend_wait_event(), pg_stat_get_backend_wait_event_type(), pg_stat_get_backend_xact_start(), pg_stat_get_progress_info(), pg_statistics_object_ownercheck(), pg_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), and ReassignOwnedObjects().

4909 {
4910  /* Fast path for simple case */
4911  if (member == role)
4912  return true;
4913 
4914  /* Superusers have every privilege, so are part of every role */
4915  if (superuser_arg(member))
4916  return true;
4917 
4918  /*
4919  * Find all the roles that member has the privileges of, including
4920  * multi-level recursion, then see if target role is any one of them.
4921  */
4922  return list_member_oid(roles_has_privs_of(member), role);
4923 }
Oid member
static List * roles_has_privs_of(Oid roleid)
Definition: acl.c:4748
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4689 of file acl.c.

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

Referenced by InitPostgres().

4690 {
4692  {
4693  /*
4694  * In normal mode, set a callback on any syscache invalidation of
4695  * pg_auth_members rows
4696  */
4699  (Datum) 0);
4700  }
4701 }
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:4708
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:374

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

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

4991 {
4992  bool result = false;
4993  List *roles_list;
4994  ListCell *l;
4995 
4996  if (superuser_arg(member))
4997  return true;
4998 
4999  if (member == role)
5000 
5001  /*
5002  * A role can admin itself when it matches the session user and we're
5003  * outside any security-restricted operation, SECURITY DEFINER or
5004  * similar context. SQL-standard roles cannot self-admin. However,
5005  * SQL-standard users are distinct from roles, and they are not
5006  * grantable like roles: PostgreSQL's role-user duality extends the
5007  * standard. Checking for a session user match has the effect of
5008  * letting a role self-admin only when it's conspicuously behaving
5009  * like a user. Note that allowing self-admin under a mere SET ROLE
5010  * would make WITH ADMIN OPTION largely irrelevant; any member could
5011  * SET ROLE to issue the otherwise-forbidden command.
5012  *
5013  * Withholding self-admin in a security-restricted operation prevents
5014  * object owners from harnessing the session user identity during
5015  * administrative maintenance. Suppose Alice owns a database, has
5016  * issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
5017  * an alice-owned SECURITY DEFINER function that issues "REVOKE alice
5018  * FROM carol". If he creates an expression index calling that
5019  * function, Alice will attempt the REVOKE during each ANALYZE.
5020  * Checking InSecurityRestrictedOperation() thwarts that attack.
5021  *
5022  * Withholding self-admin in SECURITY DEFINER functions makes their
5023  * behavior independent of the calling user. There's no security or
5024  * SQL-standard-conformance need for that restriction, though.
5025  *
5026  * A role cannot have actual WITH ADMIN OPTION on itself, because that
5027  * would imply a membership loop. Therefore, we're done either way.
5028  */
5029  return member == GetSessionUserId() &&
5031 
5032  /*
5033  * Find all the roles that member is a member of, including multi-level
5034  * recursion. We build a list in the same way that is_member_of_role does
5035  * to track visited and unvisited roles.
5036  */
5037  roles_list = list_make1_oid(member);
5038 
5039  foreach(l, roles_list)
5040  {
5041  Oid memberid = lfirst_oid(l);
5042  CatCList *memlist;
5043  int i;
5044 
5045  /* Find roles that memberid is directly a member of */
5047  ObjectIdGetDatum(memberid));
5048  for (i = 0; i < memlist->n_members; i++)
5049  {
5050  HeapTuple tup = &memlist->members[i]->tuple;
5051  Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid;
5052 
5053  if (otherid == role &&
5055  {
5056  /* Found what we came for, so can stop searching */
5057  result = true;
5058  break;
5059  }
5060 
5061  roles_list = list_append_unique_oid(roles_list, otherid);
5062  }
5063  ReleaseSysCacheList(memlist);
5064  if (result)
5065  break;
5066  }
5067 
5068  list_free(roles_list);
5069 
5070  return result;
5071 }
bool InLocalUserIdChange(void)
Definition: miscinit.c:503
int n_members
Definition: catcache.h:176
List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1214
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
Oid GetSessionUserId(void)
Definition: miscinit.c:414
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:57
#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:512
void list_free(List *list)
Definition: list.c:1373
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 4932 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_activity(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), and ShowAllGUCConfig().

4933 {
4934  /* Fast path for simple case */
4935  if (member == role)
4936  return true;
4937 
4938  /* Superusers have every privilege, so are part of every role */
4939  if (superuser_arg(member))
4940  return true;
4941 
4942  /*
4943  * Find all the roles that member is a member of, including multi-level
4944  * recursion, then see if target role is any one of them.
4945  */
4946  return list_member_oid(roles_is_member_of(member), role);
4947 }
Oid member
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4831
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
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 4970 of file acl.c.

References list_member_oid(), and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

4971 {
4972  /* Fast path for simple case */
4973  if (member == role)
4974  return true;
4975 
4976  /*
4977  * Find all the roles that member is a member of, including multi-level
4978  * recursion, then see if target role is any one of them.
4979  */
4980  return list_member_oid(roles_is_member_of(member), role);
4981 }
Oid member
static List * roles_is_member_of(Oid roleid)
Definition: acl.c:4831
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:674

◆ make_empty_acl()

Acl* make_empty_acl ( void  )

Definition at line 399 of file acl.c.

References allocacl().

Referenced by SetDefaultACL().

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

◆ pg_attribute_aclcheck()

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

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

4519 {
4520  if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0)
4521  return ACLCHECK_OK;
4522  else
4523  return ACLCHECK_NO_PRIV;
4524 }
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:3746
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 4546 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().

4548 {
4549  AclResult result;
4550  HeapTuple classTuple;
4551  Form_pg_class classForm;
4552  AttrNumber nattrs;
4553  AttrNumber curr_att;
4554 
4555  /*
4556  * Must fetch pg_class row to check number of attributes. As in
4557  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4558  * throwing an error if we get any unexpected lookup errors.
4559  */
4560  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4561  if (!HeapTupleIsValid(classTuple))
4562  return ACLCHECK_NO_PRIV;
4563  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4564 
4565  nattrs = classForm->relnatts;
4566 
4567  ReleaseSysCache(classTuple);
4568 
4569  /*
4570  * Initialize result in case there are no non-dropped columns. We want to
4571  * report failure in such cases for either value of 'how'.
4572  */
4573  result = ACLCHECK_NO_PRIV;
4574 
4575  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4576  {
4577  HeapTuple attTuple;
4578  AclMode attmask;
4579 
4580  attTuple = SearchSysCache2(ATTNUM,
4581  ObjectIdGetDatum(table_oid),
4582  Int16GetDatum(curr_att));
4583  if (!HeapTupleIsValid(attTuple))
4584  continue;
4585 
4586  /* ignore dropped columns */
4587  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4588  {
4589  ReleaseSysCache(attTuple);
4590  continue;
4591  }
4592 
4593  /*
4594  * Here we hard-wire knowledge that the default ACL for a column
4595  * grants no privileges, so that we can fall out quickly in the very
4596  * common case where attacl is null.
4597  */
4598  if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
4599  attmask = 0;
4600  else
4601  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4602  mode, ACLMASK_ANY);
4603 
4604  ReleaseSysCache(attTuple);
4605 
4606  if (attmask != 0)
4607  {
4608  result = ACLCHECK_OK;
4609  if (how == ACLMASK_ANY)
4610  break; /* succeed on any success */
4611  }
4612  else
4613  {
4614  result = ACLCHECK_NO_PRIV;
4615  if (how == ACLMASK_ALL)
4616  break; /* fail on any failure */
4617  }
4618  }
4619 
4620  return result;
4621 }
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:3746
#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:200
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
AclResult
Definition: acl.h:177
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1135
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
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 3746 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().

3748 {
3749  AclMode result;
3750  HeapTuple classTuple;
3751  HeapTuple attTuple;
3752  Form_pg_class classForm;
3753  Form_pg_attribute attributeForm;
3754  Datum aclDatum;
3755  bool isNull;
3756  Acl *acl;
3757  Oid ownerId;
3758 
3759  /*
3760  * First, get the column's ACL from its pg_attribute entry
3761  */
3762  attTuple = SearchSysCache2(ATTNUM,
3763  ObjectIdGetDatum(table_oid),
3765  if (!HeapTupleIsValid(attTuple))
3766  ereport(ERROR,
3767  (errcode(ERRCODE_UNDEFINED_COLUMN),
3768  errmsg("attribute %d of relation with OID %u does not exist",
3769  attnum, table_oid)));
3770  attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
3771 
3772  /* Throw error on dropped columns, too */
3773  if (attributeForm->attisdropped)
3774  ereport(ERROR,
3775  (errcode(ERRCODE_UNDEFINED_COLUMN),
3776  errmsg("attribute %d of relation with OID %u does not exist",
3777  attnum, table_oid)));
3778 
3779  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3780  &isNull);
3781 
3782  /*
3783  * Here we hard-wire knowledge that the default ACL for a column grants no
3784  * privileges, so that we can fall out quickly in the very common case
3785  * where attacl is null.
3786  */
3787  if (isNull)
3788  {
3789  ReleaseSysCache(attTuple);
3790  return 0;
3791  }
3792 
3793  /*
3794  * Must get the relation's ownerId from pg_class. Since we already found
3795  * a pg_attribute entry, the only likely reason for this to fail is that a
3796  * concurrent DROP of the relation committed since then (which could only
3797  * happen if we don't have lock on the relation). We prefer to report "no
3798  * privileges" rather than failing in such a case, so as to avoid unwanted
3799  * failures in has_column_privilege() tests.
3800  */
3801  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3802  if (!HeapTupleIsValid(classTuple))
3803  {
3804  ReleaseSysCache(attTuple);
3805  return 0;
3806  }
3807  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3808 
3809  ownerId = classForm->relowner;
3810 
3811  ReleaseSysCache(classTuple);
3812 
3813  /* detoast column's ACL if necessary */
3814  acl = DatumGetAclP(aclDatum);
3815 
3816  result = aclmask(acl, roleid, ownerId, mask, how);
3817 
3818  /* if we have a detoasted copy, free it */
3819  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3820  pfree(acl);
3821 
3822  ReleaseSysCache(attTuple);
3823 
3824  return result;
3825 }
#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:1321
#define Int16GetDatum(X)
Definition: postgres.h:451
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1031
char * Pointer
Definition: c.h:335
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
#define ereport(elevel, rest)
Definition: elog.h:141
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
int16 attnum
Definition: pg_attribute.h:79
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1135
#define DatumGetPointer(X)
Definition: postgres.h:549
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_class_aclcheck()

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

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

4632 {
4633  if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
4634  return ACLCHECK_OK;
4635  else
4636  return ACLCHECK_NO_PRIV;
4637 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3831

◆ pg_class_aclmask()

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

Definition at line 3831 of file aclchk.c.

References ACL_DELETE, ACL_INSERT, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), allowSystemTableMods, DatumGetAclP, DatumGetPointer, DEBUG2, elog, 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().

3833 {
3834  AclMode result;
3835  HeapTuple tuple;
3836  Form_pg_class classForm;
3837  Datum aclDatum;
3838  bool isNull;
3839  Acl *acl;
3840  Oid ownerId;
3841 
3842  /*
3843  * Must get the relation's tuple from pg_class
3844  */
3845  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3846  if (!HeapTupleIsValid(tuple))
3847  ereport(ERROR,
3849  errmsg("relation with OID %u does not exist",
3850  table_oid)));
3851  classForm = (Form_pg_class) GETSTRUCT(tuple);
3852 
3853  /*
3854  * Deny anyone permission to update a system catalog unless
3855  * pg_authid.rolsuper is set. Also allow it if allowSystemTableMods.
3856  *
3857  * As of 7.4 we have some updatable system views; those shouldn't be
3858  * protected in this way. Assume the view rules can take care of
3859  * themselves. ACL_USAGE is if we ever have system sequences.
3860  */
3861  if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3862  IsSystemClass(table_oid, classForm) &&
3863  classForm->relkind != RELKIND_VIEW &&
3864  !superuser_arg(roleid) &&
3866  {
3867 #ifdef ACLDEBUG
3868  elog(DEBUG2, "permission denied for system catalog update");
3869 #endif
3871  }
3872 
3873  /*
3874  * Otherwise, superusers bypass all permission-checking.
3875  */
3876  if (superuser_arg(roleid))
3877  {
3878 #ifdef ACLDEBUG
3879  elog(DEBUG2, "OID %u is superuser, home free", roleid);
3880 #endif
3881  ReleaseSysCache(tuple);
3882  return mask;
3883  }
3884 
3885  /*
3886  * Normal case: get the relation's ACL from pg_class
3887  */
3888  ownerId = classForm->relowner;
3889 
3890  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
3891  &isNull);
3892  if (isNull)
3893  {
3894  /* No ACL, so build default ACL */
3895  switch (classForm->relkind)
3896  {
3897  case RELKIND_SEQUENCE:
3898  acl = acldefault(OBJECT_SEQUENCE, ownerId);
3899  break;
3900  default:
3901  acl = acldefault(OBJECT_TABLE, ownerId);
3902  break;
3903  }
3904  aclDatum = (Datum) 0;
3905  }
3906  else
3907  {
3908  /* detoast rel's ACL if necessary */
3909  acl = DatumGetAclP(aclDatum);
3910  }
3911 
3912  result = aclmask(acl, roleid, ownerId, mask, how);
3913 
3914  /* if we have a detoasted copy, free it */
3915  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3916  pfree(acl);
3917 
3918  ReleaseSysCache(tuple);
3919 
3920  return result;
3921 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:72
#define DatumGetAclP(X)
Definition: acl.h:120
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:570
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:749
#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:82
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1031
char * Pointer
Definition: c.h:335
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define DEBUG2
Definition: elog.h:24
#define ACL_USAGE
Definition: parsenodes.h:82
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
#define ACL_UPDATE
Definition: parsenodes.h:76
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
bool allowSystemTableMods
Definition: globals.c:120
#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:150
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define ACL_TRUNCATE
Definition: parsenodes.h:78

◆ pg_class_ownercheck()

bool pg_class_ownercheck ( Oid  class_oid,
Oid  roleid 
)

Definition at line 4755 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(), ATPrepSetStatistics(), 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().

4756 {
4757  HeapTuple tuple;
4758  Oid ownerId;
4759 
4760  /* Superusers bypass all permission checking. */
4761  if (superuser_arg(roleid))
4762  return true;
4763 
4764  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
4765  if (!HeapTupleIsValid(tuple))
4766  ereport(ERROR,
4768  errmsg("relation with OID %u does not exist", class_oid)));
4769 
4770  ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
4771 
4772  ReleaseSysCache(tuple);
4773 
4774  return has_privs_of_role(roleid, ownerId);
4775 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:72
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_collation_ownercheck()

bool pg_collation_ownercheck ( Oid  coll_oid,
Oid  roleid 
)

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

5200 {
5201  HeapTuple tuple;
5202  Oid ownerId;
5203 
5204  /* Superusers bypass all permission checking. */
5205  if (superuser_arg(roleid))
5206  return true;
5207 
5208  tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid));
5209  if (!HeapTupleIsValid(tuple))
5210  ereport(ERROR,
5211  (errcode(ERRCODE_UNDEFINED_OBJECT),
5212  errmsg("collation with OID %u does not exist", coll_oid)));
5213 
5214  ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner;
5215 
5216  ReleaseSysCache(tuple);
5217 
5218  return has_privs_of_role(roleid, ownerId);
5219 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#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:784

◆ pg_conversion_ownercheck()

bool pg_conversion_ownercheck ( Oid  conv_oid,
Oid  roleid 
)

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

5226 {
5227  HeapTuple tuple;
5228  Oid ownerId;
5229 
5230  /* Superusers bypass all permission checking. */
5231  if (superuser_arg(roleid))
5232  return true;
5233 
5234  tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid));
5235  if (!HeapTupleIsValid(tuple))
5236  ereport(ERROR,
5237  (errcode(ERRCODE_UNDEFINED_OBJECT),
5238  errmsg("conversion with OID %u does not exist", conv_oid)));
5239 
5240  ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
5241 
5242  ReleaseSysCache(tuple);
5243 
5244  return has_privs_of_role(roleid, ownerId);
5245 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:62
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_database_aclcheck()

◆ pg_database_aclmask()

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

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

3929 {
3930  AclMode result;
3931  HeapTuple tuple;
3932  Datum aclDatum;
3933  bool isNull;
3934  Acl *acl;
3935  Oid ownerId;
3936 
3937  /* Superusers bypass all permission checking. */
3938  if (superuser_arg(roleid))
3939  return mask;
3940 
3941  /*
3942  * Get the database's ACL from pg_database
3943  */
3944  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
3945  if (!HeapTupleIsValid(tuple))
3946  ereport(ERROR,
3947  (errcode(ERRCODE_UNDEFINED_DATABASE),
3948  errmsg("database with OID %u does not exist", db_oid)));
3949 
3950  ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
3951 
3952  aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl,
3953  &isNull);
3954  if (isNull)
3955  {
3956  /* No ACL, so build default ACL */
3957  acl = acldefault(OBJECT_DATABASE, ownerId);
3958  aclDatum = (Datum) 0;
3959  }
3960  else
3961  {
3962  /* detoast ACL if necessary */
3963  acl = DatumGetAclP(aclDatum);
3964  }
3965 
3966  result = aclmask(acl, roleid, ownerId, mask, how);
3967 
3968  /* if we have a detoasted copy, free it */
3969  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3970  pfree(acl);
3971 
3972  ReleaseSysCache(tuple);
3973 
3974  return result;
3975 }
#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:1321
int errcode(int sqlerrcode)
Definition: elog.c:570
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:749
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1031
char * Pointer
Definition: c.h:335
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_database_ownercheck()

bool pg_database_ownercheck ( Oid  db_oid,
Oid  roleid 
)

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

5174 {
5175  HeapTuple tuple;
5176  Oid dba;
5177 
5178  /* Superusers bypass all permission checking. */
5179  if (superuser_arg(roleid))
5180  return true;
5181 
5182  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
5183  if (!HeapTupleIsValid(tuple))
5184  ereport(ERROR,
5185  (errcode(ERRCODE_UNDEFINED_DATABASE),
5186  errmsg("database with OID %u does not exist", db_oid)));
5187 
5188  dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
5189 
5190  ReleaseSysCache(tuple);
5191 
5192  return has_privs_of_role(roleid, dba);
5193 }
#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:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_event_trigger_ownercheck()

bool pg_event_trigger_ownercheck ( Oid  et_oid,
Oid  roleid 
)

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

5147 {
5148  HeapTuple tuple;
5149  Oid ownerId;
5150 
5151  /* Superusers bypass all permission checking. */
5152  if (superuser_arg(roleid))
5153  return true;
5154 
5156  if (!HeapTupleIsValid(tuple))
5157  ereport(ERROR,
5158  (errcode(ERRCODE_UNDEFINED_OBJECT),
5159  errmsg("event trigger with OID %u does not exist",
5160  et_oid)));
5161 
5162  ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner;
5163 
5164  ReleaseSysCache(tuple);
5165 
5166  return has_privs_of_role(roleid, ownerId);
5167 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_extension_ownercheck()

bool pg_extension_ownercheck ( Oid  ext_oid,
Oid  roleid 
)

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

5252 {
5253  Relation pg_extension;
5254  ScanKeyData entry[1];
5255  SysScanDesc scan;
5256  HeapTuple tuple;
5257  Oid ownerId;
5258 
5259  /* Superusers bypass all permission checking. */
5260  if (superuser_arg(roleid))
5261  return true;
5262 
5263  /* There's no syscache for pg_extension, so do it the hard way */
5264  pg_extension = table_open(ExtensionRelationId, AccessShareLock);
5265 
5266  ScanKeyInit(&entry[0],
5267  Anum_pg_extension_oid,
5268  BTEqualStrategyNumber, F_OIDEQ,
5269  ObjectIdGetDatum(ext_oid));
5270 
5271  scan = systable_beginscan(pg_extension,
5272  ExtensionOidIndexId, true,
5273  NULL, 1, entry);
5274 
5275  tuple = systable_getnext(scan);
5276  if (!HeapTupleIsValid(tuple))
5277  ereport(ERROR,
5278  (errcode(ERRCODE_UNDEFINED_OBJECT),
5279  errmsg("extension with OID %u does not exist", ext_oid)));
5280 
5281  ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner;
5282 
5283  systable_endscan(scan);
5284  table_close(pg_extension, AccessShareLock);
5285 
5286  return has_privs_of_role(roleid, ownerId);
5287 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:570
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define ExtensionOidIndexId
Definition: indexing.h:326
FormData_pg_extension * Form_pg_extension
Definition: pg_extension.h:50
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784
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 4310 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().

4312 {
4313  AclMode result;
4314  HeapTuple tuple;
4315  Datum aclDatum;
4316  bool isNull;
4317  Acl *acl;
4318  Oid ownerId;
4319 
4321 
4322  /* Bypass permission checks for superusers */
4323  if (superuser_arg(roleid))
4324  return mask;
4325 
4326  /*
4327  * Must get the FDW's tuple from pg_foreign_data_wrapper
4328  */
4330  if (!HeapTupleIsValid(tuple))
4331  ereport(ERROR,
4332  (errcode(ERRCODE_UNDEFINED_OBJECT),
4333  errmsg("foreign-data wrapper with OID %u does not exist",
4334  fdw_oid)));
4335  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
4336 
4337  /*
4338  * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
4339  */
4340  ownerId = fdwForm->fdwowner;
4341 
4342  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
4343  Anum_pg_foreign_data_wrapper_fdwacl, &isNull);
4344  if (isNull)
4345  {
4346  /* No ACL, so build default ACL */
4347  acl = acldefault(OBJECT_FDW, ownerId);
4348  aclDatum = (Datum) 0;
4349  }
4350  else
4351  {
4352  /* detoast rel's ACL if necessary */
4353  acl = DatumGetAclP(aclDatum);
4354  }
4355 
4356  result = aclmask(acl, roleid, ownerId, mask, how);
4357 
4358  /* if we have a detoasted copy, free it */
4359  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4360  pfree(acl);
4361 
4362  ReleaseSysCache(tuple);
4363 
4364  return result;
4365 }
#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:1321
int errcode(int sqlerrcode)
Definition: elog.c:570
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:749
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1031
char * Pointer
Definition: c.h:335
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
#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:784

◆ pg_foreign_data_wrapper_ownercheck()

bool pg_foreign_data_wrapper_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

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

5093 {
5094  HeapTuple tuple;
5095  Oid ownerId;
5096 
5097  /* Superusers bypass all permission checking. */
5098  if (superuser_arg(roleid))
5099  return true;
5100 
5102  if (!HeapTupleIsValid(tuple))
5103  ereport(ERROR,
5104  (errcode(ERRCODE_UNDEFINED_OBJECT),
5105  errmsg("foreign-data wrapper with OID %u does not exist",
5106  srv_oid)));
5107 
5108  ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner;
5109 
5110  ReleaseSysCache(tuple);
5111 
5112  return has_privs_of_role(roleid, ownerId);
5113 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#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:784

◆ pg_foreign_server_aclcheck()

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

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

4732 {
4733  if (pg_foreign_server_aclmask(srv_oid, roleid, mode, ACLMASK_ANY) != 0)
4734  return ACLCHECK_OK;
4735  else
4736  return ACLCHECK_NO_PRIV;
4737 }
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:4372

◆ pg_foreign_server_aclmask()

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

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

4374 {
4375  AclMode result;
4376  HeapTuple tuple;
4377  Datum aclDatum;
4378  bool isNull;
4379  Acl *acl;
4380  Oid ownerId;
4381 
4382  Form_pg_foreign_server srvForm;
4383 
4384  /* Bypass permission checks for superusers */
4385  if (superuser_arg(roleid))
4386  return mask;
4387 
4388  /*
4389  * Must get the FDW's tuple from pg_foreign_data_wrapper
4390  */
4392  if (!HeapTupleIsValid(tuple))
4393  ereport(ERROR,
4394  (errcode(ERRCODE_UNDEFINED_OBJECT),
4395  errmsg("foreign server with OID %u does not exist",
4396  srv_oid)));
4397  srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
4398 
4399  /*
4400  * Normal case: get the foreign server's ACL from pg_foreign_server
4401  */
4402  ownerId = srvForm->srvowner;
4403 
4404  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
4405  Anum_pg_foreign_server_srvacl, &isNull);
4406  if (isNull)
4407  {
4408  /* No ACL, so build default ACL */
4409  acl = acldefault(OBJECT_FOREIGN_SERVER, ownerId);
4410  aclDatum = (Datum) 0;
4411  }
4412  else
4413  {
4414  /* detoast rel's ACL if necessary */
4415  acl = DatumGetAclP(aclDatum);
4416  }
4417 
4418  result = aclmask(acl, roleid, ownerId, mask, how);
4419 
4420  /* if we have a detoasted copy, free it */
4421  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4422  pfree(acl);
4423 
4424  ReleaseSysCache(tuple);
4425 
4426  return result;
4427 }
#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:1321
int errcode(int sqlerrcode)
Definition: elog.c:570
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:749
unsigned int Oid
Definition: postgres_ext.h:31
uint32 AclMode
Definition: parsenodes.h:72
void pfree(void *pointer)
Definition: mcxt.c:1031
char * Pointer
Definition: c.h:335
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1385
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define DatumGetPointer(X)
Definition: postgres.h:549
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_foreign_server_ownercheck()

bool pg_foreign_server_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

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

5120 {
5121  HeapTuple tuple;
5122  Oid ownerId;
5123 
5124  /* Superusers bypass all permission checking. */
5125  if (superuser_arg(roleid))
5126  return true;
5127 
5129  if (!HeapTupleIsValid(tuple))
5130  ereport(ERROR,
5131  (errcode(ERRCODE_UNDEFINED_OBJECT),
5132  errmsg("foreign server with OID %u does not exist",
5133  srv_oid)));
5134 
5135  ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner;
5136 
5137  ReleaseSysCache(tuple);
5138 
5139  return has_privs_of_role(roleid, ownerId);
5140 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4908
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_language_aclcheck()

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

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

4668 {
4669  if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
4670  return ACLCHECK_OK;
4671  else
4672  return ACLCHECK_NO_PRIV;
4673 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:4035

◆ pg_language_aclmask()

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

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

4037 {
4038  AclMode result;
4039  HeapTuple tuple;
4040  Datum aclDatum;
4041  bool isNull;
4042  Acl *acl;
4043  Oid ownerId;
4044 
4045  /* Superusers bypass all permission checking. */
4046  if (superuser_arg(roleid))
4047  return mask;
4