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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

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

Typedefs

typedef struct AclItem AclItem
 
typedef ArrayType Acl
 
typedef enum AclObjectKind AclObjectKind
 

Enumerations

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

Functions

Aclacldefault (GrantObjectType objtype, Oid ownerId)
 
Aclget_user_default_acl (GrantObjectType objtype, Oid ownerId, Oid nsp_oid)
 
Aclaclupdate (const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
 
Aclaclnewowner (const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
 
Aclmake_empty_acl (void)
 
Aclaclcopy (const Acl *orig_acl)
 
Aclaclconcat (const Acl *left_acl, const Acl *right_acl)
 
Aclaclmerge (const Acl *left_acl, const Acl *right_acl, Oid ownerId)
 
void aclitemsort (Acl *acl)
 
bool aclequal (const Acl *left_acl, const Acl *right_acl)
 
AclMode aclmask (const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
 
int aclmembers (const Acl *acl, Oid **roleids)
 
bool has_privs_of_role (Oid member, Oid role)
 
bool is_member_of_role (Oid member, Oid role)
 
bool is_member_of_role_nosuper (Oid member, Oid role)
 
bool is_admin_of_role (Oid member, Oid role)
 
void check_is_member_of_role (Oid member, Oid role)
 
Oid get_role_oid (const char *rolename, bool missing_ok)
 
Oid get_role_oid_or_public (const char *rolename)
 
Oid get_rolespec_oid (const RoleSpec *role, bool missing_ok)
 
void check_rolespec_name (const RoleSpec *role, const char *detail_msg)
 
HeapTuple get_rolespec_tuple (const RoleSpec *role)
 
char * get_rolespec_name (const RoleSpec *role)
 
void select_best_grantor (Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
void RemoveDefaultACLById (Oid defaclOid)
 
AclMode pg_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_database_aclmask (Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_proc_aclmask (Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_language_aclmask (Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_largeobject_aclmask_snapshot (Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
 
AclMode pg_namespace_aclmask (Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_tablespace_aclmask (Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_data_wrapper_aclmask (Oid fdw_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_foreign_server_aclmask (Oid srv_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclMode pg_type_aclmask (Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_database_aclcheck (Oid db_oid, Oid roleid, AclMode mode)
 
AclResult pg_proc_aclcheck (Oid proc_oid, Oid roleid, AclMode mode)
 
AclResult pg_language_aclcheck (Oid lang_oid, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lang_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
AclResult pg_namespace_aclcheck (Oid nsp_oid, Oid roleid, AclMode mode)
 
AclResult pg_tablespace_aclcheck (Oid spc_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_data_wrapper_aclcheck (Oid fdw_oid, Oid roleid, AclMode mode)
 
AclResult pg_foreign_server_aclcheck (Oid srv_oid, Oid roleid, AclMode mode)
 
AclResult pg_type_aclcheck (Oid type_oid, Oid roleid, AclMode mode)
 
void aclcheck_error (AclResult aclerr, AclObjectKind objectkind, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, AclObjectKind objectkind, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
bool pg_class_ownercheck (Oid class_oid, Oid roleid)
 
bool pg_type_ownercheck (Oid type_oid, Oid roleid)
 
bool pg_oper_ownercheck (Oid oper_oid, Oid roleid)
 
bool pg_proc_ownercheck (Oid proc_oid, Oid roleid)
 
bool pg_language_ownercheck (Oid lan_oid, Oid roleid)
 
bool pg_largeobject_ownercheck (Oid lobj_oid, Oid roleid)
 
bool pg_namespace_ownercheck (Oid nsp_oid, Oid roleid)
 
bool pg_tablespace_ownercheck (Oid spc_oid, Oid roleid)
 
bool pg_opclass_ownercheck (Oid opc_oid, Oid roleid)
 
bool pg_opfamily_ownercheck (Oid opf_oid, Oid roleid)
 
bool pg_database_ownercheck (Oid db_oid, Oid roleid)
 
bool pg_collation_ownercheck (Oid coll_oid, Oid roleid)
 
bool pg_conversion_ownercheck (Oid conv_oid, Oid roleid)
 
bool pg_ts_dict_ownercheck (Oid dict_oid, Oid roleid)
 
bool pg_ts_config_ownercheck (Oid cfg_oid, Oid roleid)
 
bool pg_foreign_data_wrapper_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_foreign_server_ownercheck (Oid srv_oid, Oid roleid)
 
bool pg_event_trigger_ownercheck (Oid et_oid, Oid roleid)
 
bool pg_extension_ownercheck (Oid ext_oid, Oid roleid)
 
bool pg_publication_ownercheck (Oid pub_oid, Oid roleid)
 
bool pg_subscription_ownercheck (Oid sub_oid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

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

Definition at line 149 of file acl.h.

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

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 152 of file acl.h.

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

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 153 of file acl.h.

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

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)
#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)
#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 156 of file acl.h.

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

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)
#define ACL_ALL_RIGHTS_NAMESPACE   (ACL_USAGE|ACL_CREATE)
#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTc"

Definition at line 144 of file acl.h.

Referenced by aclitemout(), and aclparse().

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)
#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)
#define ACL_CONNECT_CHR   'c'

Definition at line 141 of file acl.h.

Referenced by aclparse().

#define ACL_CREATE_CHR   'C'

Definition at line 139 of file acl.h.

Referenced by aclparse().

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 140 of file acl.h.

Referenced by aclparse().

#define ACL_DELETE_CHR   'd'
#define ACL_EXECUTE_CHR   'X'

Definition at line 137 of file acl.h.

Referenced by aclparse().

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

Definition at line 122 of file acl.h.

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

#define ACL_MODECHG_DEL   2

Definition at line 123 of file acl.h.

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

#define ACL_MODECHG_EQL   3

Definition at line 124 of file acl.h.

Referenced by aclupdate().

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

Definition at line 103 of file acl.h.

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

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

Definition at line 64 of file acl.h.

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

#define ACL_REFERENCES_CHR   'x'

Definition at line 135 of file acl.h.

Referenced by aclparse().

#define ACL_SELECT_CHR   'r' /* formerly known as "read" */
#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 104 of file acl.h.

Referenced by aclupdate(), and check_circularity().

#define ACL_TRIGGER_CHR   't'

Definition at line 136 of file acl.h.

Referenced by aclparse().

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

Definition at line 134 of file acl.h.

Referenced by aclparse().

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

Definition at line 132 of file acl.h.

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

#define ACL_USAGE_CHR   'U'

Definition at line 138 of file acl.h.

Referenced by aclparse().

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

Definition at line 81 of file acl.h.

Referenced by aclmask(), and aclmask_direct().

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFF)

Definition at line 80 of file acl.h.

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

Definition at line 60 of file acl.h.

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

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

Definition at line 59 of file acl.h.

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

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

Definition at line 61 of file acl.h.

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

#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:63

Definition at line 69 of file acl.h.

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

Definition at line 66 of file acl.h.

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

Definition at line 75 of file acl.h.

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

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

Definition at line 72 of file acl.h.

Referenced by aclnewowner(), and aclupdate().

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

Definition at line 109 of file acl.h.

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

Definition at line 115 of file acl.h.

Referenced by aclcontains(), and aclexplode().

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

Definition at line 116 of file acl.h.

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

Definition at line 110 of file acl.h.

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

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 117 of file acl.h.

Referenced by acldefault_sql().

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 111 of file acl.h.

Referenced by aclitemin(), and makeaclitem().

Typedef Documentation

Definition at line 99 of file acl.h.

Enumeration Type Documentation

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 163 of file acl.h.

164 {
165  ACLMASK_ALL, /* normal case: compute all bits */
166  ACLMASK_ANY /* return when result is known nonzero */
167 } AclMaskHow;
AclMaskHow
Definition: acl.h:163
Enumerator
ACL_KIND_COLUMN 
ACL_KIND_CLASS 
ACL_KIND_SEQUENCE 
ACL_KIND_DATABASE 
ACL_KIND_PROC 
ACL_KIND_OPER 
ACL_KIND_TYPE 
ACL_KIND_LANGUAGE 
ACL_KIND_LARGEOBJECT 
ACL_KIND_NAMESPACE 
ACL_KIND_OPCLASS 
ACL_KIND_OPFAMILY 
ACL_KIND_COLLATION 
ACL_KIND_CONVERSION 
ACL_KIND_TABLESPACE 
ACL_KIND_TSDICTIONARY 
ACL_KIND_TSCONFIGURATION 
ACL_KIND_FDW 
ACL_KIND_FOREIGN_SERVER 
ACL_KIND_EVENT_TRIGGER 
ACL_KIND_EXTENSION 
ACL_KIND_PUBLICATION 
ACL_KIND_SUBSCRIPTION 
MAX_ACL_KIND 

Definition at line 179 of file acl.h.

180 {
181  ACL_KIND_COLUMN, /* pg_attribute */
182  ACL_KIND_CLASS, /* pg_class */
183  ACL_KIND_SEQUENCE, /* pg_sequence */
184  ACL_KIND_DATABASE, /* pg_database */
185  ACL_KIND_PROC, /* pg_proc */
186  ACL_KIND_OPER, /* pg_operator */
187  ACL_KIND_TYPE, /* pg_type */
188  ACL_KIND_LANGUAGE, /* pg_language */
189  ACL_KIND_LARGEOBJECT, /* pg_largeobject */
190  ACL_KIND_NAMESPACE, /* pg_namespace */
191  ACL_KIND_OPCLASS, /* pg_opclass */
192  ACL_KIND_OPFAMILY, /* pg_opfamily */
193  ACL_KIND_COLLATION, /* pg_collation */
194  ACL_KIND_CONVERSION, /* pg_conversion */
195  ACL_KIND_TABLESPACE, /* pg_tablespace */
196  ACL_KIND_TSDICTIONARY, /* pg_ts_dict */
197  ACL_KIND_TSCONFIGURATION, /* pg_ts_config */
198  ACL_KIND_FDW, /* pg_foreign_data_wrapper */
199  ACL_KIND_FOREIGN_SERVER, /* pg_foreign_server */
200  ACL_KIND_EVENT_TRIGGER, /* pg_event_trigger */
201  ACL_KIND_EXTENSION, /* pg_extension */
202  ACL_KIND_PUBLICATION, /* pg_publication */
203  ACL_KIND_SUBSCRIPTION, /* pg_subscription */
204  MAX_ACL_KIND /* MUST BE LAST */
205 } AclObjectKind;
AclObjectKind
Definition: acl.h:179
enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 170 of file acl.h.

171 {
172  ACLCHECK_OK = 0,
175 } AclResult;
AclResult
Definition: acl.h:170

Function Documentation

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

Definition at line 3378 of file aclchk.c.

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

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

3380 {
3381  switch (aclerr)
3382  {
3383  case ACLCHECK_OK:
3384  /* no error, so return to caller */
3385  break;
3386  case ACLCHECK_NO_PRIV:
3387  ereport(ERROR,
3388  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3389  errmsg(no_priv_msg[objectkind], objectname)));
3390  break;
3391  case ACLCHECK_NOT_OWNER:
3392  ereport(ERROR,
3393  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3394  errmsg(not_owner_msg[objectkind], objectname)));
3395  break;
3396  default:
3397  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3398  break;
3399  }
3400 }
static const char *const no_priv_msg[MAX_ACL_KIND]
Definition: aclchk.c:3276
static const char *const not_owner_msg[MAX_ACL_KIND]
Definition: aclchk.c:3326
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void aclcheck_error_col ( AclResult  aclerr,
AclObjectKind  objectkind,
const char *  objectname,
const char *  colname 
)

Definition at line 3404 of file aclchk.c.

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

Referenced by restrict_and_check_grant().

3406 {
3407  switch (aclerr)
3408  {
3409  case ACLCHECK_OK:
3410  /* no error, so return to caller */
3411  break;
3412  case ACLCHECK_NO_PRIV:
3413  ereport(ERROR,
3414  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3415  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3416  colname, objectname)));
3417  break;
3418  case ACLCHECK_NOT_OWNER:
3419  /* relation msg is OK since columns don't have separate owners */
3420  ereport(ERROR,
3421  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3422  errmsg(not_owner_msg[objectkind], objectname)));
3423  break;
3424  default:
3425  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3426  break;
3427  }
3428 }
static const char *const not_owner_msg[MAX_ACL_KIND]
Definition: aclchk.c:3326
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

Definition at line 3436 of file aclchk.c.

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

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

3437 {
3438  Oid element_type = get_element_type(typeOid);
3439 
3440  aclcheck_error(aclerr, ACL_KIND_TYPE, format_type_be(element_type ? element_type : typeOid));
3441 }
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2452
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3378
Acl* aclconcat ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 427 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

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

Definition at line 407 of file acl.c.

References ACL_DAT, ACL_NUM, and allocacl().

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

408 {
409  Acl *result_acl;
410 
411  result_acl = allocacl(ACL_NUM(orig_acl));
412 
413  memcpy(ACL_DAT(result_acl),
414  ACL_DAT(orig_acl),
415  ACL_NUM(orig_acl) * sizeof(AclItem));
416 
417  return result_acl;
418 }
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_NUM(ACL)
Definition: acl.h:101
#define ACL_DAT(ACL)
Definition: acl.h:102
Definition: acl.h:47
Acl* acldefault ( GrantObjectType  objtype,
Oid  ownerId 
)

Definition at line 732 of file acl.c.

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_NAMESPACE, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_OBJECT_COLUMN, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog, and ERROR.

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

733 {
734  AclMode world_default;
735  AclMode owner_default;
736  int nacl;
737  Acl *acl;
738  AclItem *aip;
739 
740  switch (objtype)
741  {
742  case ACL_OBJECT_COLUMN:
743  /* by default, columns have no extra privileges */
744  world_default = ACL_NO_RIGHTS;
745  owner_default = ACL_NO_RIGHTS;
746  break;
747  case ACL_OBJECT_RELATION:
748  world_default = ACL_NO_RIGHTS;
749  owner_default = ACL_ALL_RIGHTS_RELATION;
750  break;
751  case ACL_OBJECT_SEQUENCE:
752  world_default = ACL_NO_RIGHTS;
753  owner_default = ACL_ALL_RIGHTS_SEQUENCE;
754  break;
755  case ACL_OBJECT_DATABASE:
756  /* for backwards compatibility, grant some rights by default */
757  world_default = ACL_CREATE_TEMP | ACL_CONNECT;
758  owner_default = ACL_ALL_RIGHTS_DATABASE;
759  break;
760  case ACL_OBJECT_FUNCTION:
761  /* Grant EXECUTE by default, for now */
762  world_default = ACL_EXECUTE;
763  owner_default = ACL_ALL_RIGHTS_FUNCTION;
764  break;
765  case ACL_OBJECT_LANGUAGE:
766  /* Grant USAGE by default, for now */
767  world_default = ACL_USAGE;
768  owner_default = ACL_ALL_RIGHTS_LANGUAGE;
769  break;
771  world_default = ACL_NO_RIGHTS;
772  owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
773  break;
775  world_default = ACL_NO_RIGHTS;
776  owner_default = ACL_ALL_RIGHTS_NAMESPACE;
777  break;
779  world_default = ACL_NO_RIGHTS;
780  owner_default = ACL_ALL_RIGHTS_TABLESPACE;
781  break;
782  case ACL_OBJECT_FDW:
783  world_default = ACL_NO_RIGHTS;
784  owner_default = ACL_ALL_RIGHTS_FDW;
785  break;
787  world_default = ACL_NO_RIGHTS;
788  owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
789  break;
790  case ACL_OBJECT_DOMAIN:
791  case ACL_OBJECT_TYPE:
792  world_default = ACL_USAGE;
793  owner_default = ACL_ALL_RIGHTS_TYPE;
794  break;
795  default:
796  elog(ERROR, "unrecognized objtype: %d", (int) objtype);
797  world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
798  owner_default = ACL_NO_RIGHTS;
799  break;
800  }
801 
802  nacl = 0;
803  if (world_default != ACL_NO_RIGHTS)
804  nacl++;
805  if (owner_default != ACL_NO_RIGHTS)
806  nacl++;
807 
808  acl = allocacl(nacl);
809  aip = ACL_DAT(acl);
810 
811  if (world_default != ACL_NO_RIGHTS)
812  {
813  aip->ai_grantee = ACL_ID_PUBLIC;
814  aip->ai_grantor = ownerId;
815  ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
816  aip++;
817  }
818 
819  /*
820  * Note that the owner's entry shows all ordinary privileges but no grant
821  * options. This is because his grant options come "from the system" and
822  * not from his own efforts. (The SQL spec says that the owner's rights
823  * come from a "_SYSTEM" authid.) However, we do consider that the
824  * owner's ordinary privileges are self-granted; this lets him revoke
825  * them. We implement the owner's grant options without any explicit
826  * "_SYSTEM"-like ACL entry, by internally special-casing the owner
827  * wherever we are testing grant options.
828  */
829  if (owner_default != ACL_NO_RIGHTS)
830  {
831  aip->ai_grantee = ownerId;
832  aip->ai_grantor = ownerId;
833  ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
834  }
835 
836  return acl;
837 }
Oid ai_grantee
Definition: acl.h:49
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:155
static Acl * allocacl(int n)
Definition: acl.c:376
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:159
Oid ai_grantor
Definition: acl.h:50
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:156
uint32 AclMode
Definition: parsenodes.h:63
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:79
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:160
#define ACL_USAGE
Definition: parsenodes.h:73
#define ACL_CONNECT
Definition: parsenodes.h:77
#define ACL_ALL_RIGHTS_NAMESPACE
Definition: acl.h:158
#define ACL_DAT(ACL)
Definition: acl.h:102
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:151
Definition: acl.h:47
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:157
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:152
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:154
#define ACL_EXECUTE
Definition: parsenodes.h:72
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:150
#define ACL_CREATE_TEMP
Definition: parsenodes.h:76
#define ACL_ID_PUBLIC
Definition: acl.h:39
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:153
#define elog
Definition: elog.h:219
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:75
bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 509 of file acl.c.

References ACL_DAT, ACL_NUM, and NULL.

Referenced by get_user_default_acl(), and SetDefaultACL().

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

Definition at line 495 of file acl.c.

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

Referenced by get_user_default_acl(), and SetDefaultACL().

496 {
497  if (acl != NULL && ACL_NUM(acl) > 1)
498  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
499 }
#define ACL_NUM(ACL)
Definition: acl.h:101
#define ACL_DAT(ACL)
Definition: acl.h:102
Definition: acl.h:47
#define NULL
Definition: c.h:226
#define qsort(a, b, c, d)
Definition: port.h:440
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:669
AclMode aclmask ( const Acl acl,
Oid  roleid,
Oid  ownerId,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 1305 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, NULL, 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().

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

Definition at line 1457 of file acl.c.

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

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

1458 {
1459  Oid *list;
1460  const AclItem *acldat;
1461  int i,
1462  j,
1463  k;
1464 
1465  if (acl == NULL || ACL_NUM(acl) == 0)
1466  {
1467  *roleids = NULL;
1468  return 0;
1469  }
1470 
1471  check_acl(acl);
1472 
1473  /* Allocate the worst-case space requirement */
1474  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1475  acldat = ACL_DAT(acl);
1476 
1477  /*
1478  * Walk the ACL collecting mentioned RoleIds.
1479  */
1480  j = 0;
1481  for (i = 0; i < ACL_NUM(acl); i++)
1482  {
1483  const AclItem *ai = &acldat[i];
1484 
1485  if (ai->ai_grantee != ACL_ID_PUBLIC)
1486  list[j++] = ai->ai_grantee;
1487  /* grantor is currently never PUBLIC, but let's check anyway */
1488  if (ai->ai_grantor != ACL_ID_PUBLIC)
1489  list[j++] = ai->ai_grantor;
1490  }
1491 
1492  /* Sort the array */
1493  qsort(list, j, sizeof(Oid), oidComparator);
1494 
1495  /* Remove duplicates from the array */
1496  k = 0;
1497  for (i = 1; i < j; i++)
1498  {
1499  if (list[k] != list[i])
1500  list[++k] = list[i];
1501  }
1502 
1503  /*
1504  * We could repalloc the array down to minimum size, but it's hardly worth
1505  * it since it's only transient memory.
1506  */
1507  *roleids = list;
1508 
1509  return k + 1;
1510 }
Oid ai_grantee
Definition: acl.h:49
unsigned int Oid
Definition: postgres_ext.h:31
Oid ai_grantor
Definition: acl.h:50
#define ACL_NUM(ACL)
Definition: acl.h:101
#define ACL_DAT(ACL)
Definition: acl.h:102
Definition: acl.h:47
#define NULL
Definition: c.h:226
static int oidComparator(const void *arg1, const void *arg2)
Definition: acl.c:1517
tuple list
Definition: sort-test.py:11
void * palloc(Size size)
Definition: mcxt.c:891
int i
#define ACL_ID_PUBLIC
Definition: acl.h:39
#define qsort(a, b, c, d)
Definition: port.h:440
static void check_acl(const Acl *acl)
Definition: acl.c:540
Acl* aclmerge ( const Acl left_acl,
const Acl right_acl,
Oid  ownerId 
)

Definition at line 451 of file acl.c.

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

Referenced by get_user_default_acl().

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

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

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

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

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

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

Definition at line 4877 of file acl.c.

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

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

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

Definition at line 5251 of file acl.c.

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

Referenced by AlterRole(), and AlterRoleSet().

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

Definition at line 863 of file aclchk.c.

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_OBJECT_FUNCTION, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, 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, NULL, 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().

864 {
865  GrantStmt *action = stmt->action;
866  InternalDefaultACL iacls;
867  ListCell *cell;
868  List *rolespecs = NIL;
869  List *nspnames = NIL;
870  DefElem *drolespecs = NULL;
871  DefElem *dnspnames = NULL;
872  AclMode all_privileges;
873  const char *errormsg;
874 
875  /* Deconstruct the "options" part of the statement */
876  foreach(cell, stmt->options)
877  {
878  DefElem *defel = (DefElem *) lfirst(cell);
879 
880  if (strcmp(defel->defname, "schemas") == 0)
881  {
882  if (dnspnames)
883  ereport(ERROR,
884  (errcode(ERRCODE_SYNTAX_ERROR),
885  errmsg("conflicting or redundant options"),
886  parser_errposition(pstate, defel->location)));
887  dnspnames = defel;
888  }
889  else if (strcmp(defel->defname, "roles") == 0)
890  {
891  if (drolespecs)
892  ereport(ERROR,
893  (errcode(ERRCODE_SYNTAX_ERROR),
894  errmsg("conflicting or redundant options"),
895  parser_errposition(pstate, defel->location)));
896  drolespecs = defel;
897  }
898  else
899  elog(ERROR, "option \"%s\" not recognized", defel->defname);
900  }
901 
902  if (dnspnames)
903  nspnames = (List *) dnspnames->arg;
904  if (drolespecs)
905  rolespecs = (List *) drolespecs->arg;
906 
907  /* Prepare the InternalDefaultACL representation of the statement */
908  /* roleid to be filled below */
909  /* nspid to be filled in SetDefaultACLsInSchemas */
910  iacls.is_grant = action->is_grant;
911  iacls.objtype = action->objtype;
912  /* all_privs to be filled below */
913  /* privileges to be filled below */
914  iacls.grantees = NIL; /* filled below */
915  iacls.grant_option = action->grant_option;
916  iacls.behavior = action->behavior;
917 
918  /*
919  * Convert the RoleSpec list into an Oid list. Note that at this point we
920  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
921  * there shouldn't be any additional work needed to support this case.
922  */
923  foreach(cell, action->grantees)
924  {
925  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
926  Oid grantee_uid;
927 
928  switch (grantee->roletype)
929  {
930  case ROLESPEC_PUBLIC:
931  grantee_uid = ACL_ID_PUBLIC;
932  break;
933  default:
934  grantee_uid = get_rolespec_oid(grantee, false);
935  break;
936  }
937  iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
938  }
939 
940  /*
941  * Convert action->privileges, a list of privilege strings, into an
942  * AclMode bitmask.
943  */
944  switch (action->objtype)
945  {
946  case ACL_OBJECT_RELATION:
947  all_privileges = ACL_ALL_RIGHTS_RELATION;
948  errormsg = gettext_noop("invalid privilege type %s for relation");
949  break;
950  case ACL_OBJECT_SEQUENCE:
951  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
952  errormsg = gettext_noop("invalid privilege type %s for sequence");
953  break;
954  case ACL_OBJECT_FUNCTION:
955  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
956  errormsg = gettext_noop("invalid privilege type %s for function");
957  break;
958  case ACL_OBJECT_TYPE:
959  all_privileges = ACL_ALL_RIGHTS_TYPE;
960  errormsg = gettext_noop("invalid privilege type %s for type");
961  break;
962  default:
963  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
964  (int) action->objtype);
965  /* keep compiler quiet */
966  all_privileges = ACL_NO_RIGHTS;
967  errormsg = NULL;
968  }
969 
970  if (action->privileges == NIL)
971  {
972  iacls.all_privs = true;
973 
974  /*
975  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
976  * depending on the object type
977  */
978  iacls.privileges = ACL_NO_RIGHTS;
979  }
980  else
981  {
982  iacls.all_privs = false;
983  iacls.privileges = ACL_NO_RIGHTS;
984 
985  foreach(cell, action->privileges)
986  {
987  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
988  AclMode priv;
989 
990  if (privnode->cols)
991  ereport(ERROR,
992  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
993  errmsg("default privileges cannot be set for columns")));
994 
995  if (privnode->priv_name == NULL) /* parser mistake? */
996  elog(ERROR, "AccessPriv node must specify privilege");
997  priv = string_to_privilege(privnode->priv_name);
998 
999  if (priv & ~((AclMode) all_privileges))
1000  ereport(ERROR,
1001  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1002  errmsg(errormsg, privilege_to_string(priv))));
1003 
1004  iacls.privileges |= priv;
1005  }
1006  }
1007 
1008  if (rolespecs == NIL)
1009  {
1010  /* Set permissions for myself */
1011  iacls.roleid = GetUserId();
1012 
1013  SetDefaultACLsInSchemas(&iacls, nspnames);
1014  }
1015  else
1016  {
1017  /* Look up the role OIDs and do permissions checks */
1018  ListCell *rolecell;
1019 
1020  foreach(rolecell, rolespecs)
1021  {
1022  RoleSpec *rolespec = lfirst(rolecell);
1023 
1024  iacls.roleid = get_rolespec_oid(rolespec, false);
1025 
1026  /*
1027  * We insist that calling user be a member of each target role. If
1028  * he has that, he could become that role anyway via SET ROLE, so
1029  * FOR ROLE is just a syntactic convenience and doesn't give any
1030  * special privileges.
1031  */
1033 
1034  SetDefaultACLsInSchemas(&iacls, nspnames);
1035  }
1036  }
1037 }
#define NIL
Definition: pg_list.h:69
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:155
bool grant_option
Definition: aclchk.c:92
Oid GetUserId(void)
Definition: miscinit.c:282
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:3198
bool grant_option
Definition: parsenodes.h:1761
#define gettext_noop(x)
Definition: c.h:139
int errcode(int sqlerrcode)
Definition: elog.c:575
List * cols
Definition: parsenodes.h:1788
unsigned int Oid
Definition: postgres_ext.h:31
GrantObjectType objtype
Definition: aclchk.c:88
List * grantees
Definition: aclchk.c:91
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
uint32 AclMode
Definition: parsenodes.h:63
#define ERROR
Definition: elog.h:43
#define ACL_NO_RIGHTS
Definition: parsenodes.h:79
int location
Definition: parsenodes.h:678
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:160
void check_is_member_of_role(Oid member, Oid role)
Definition: acl.c:4877
#define ereport(elevel, rest)
Definition: elog.h:122
Node * arg
Definition: parsenodes.h:676
bool is_grant
Definition: parsenodes.h:1753
RoleSpecType roletype
Definition: parsenodes.h:319
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5147
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:151
DropBehavior behavior
Definition: aclchk.c:93
List * privileges
Definition: parsenodes.h:1758
DropBehavior behavior
Definition: parsenodes.h:1762
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:109
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1045
GrantObjectType objtype
Definition: parsenodes.h:1755
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:150
#define ACL_ID_PUBLIC
Definition: acl.h:39
char * defname
Definition: parsenodes.h:675
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:3235
List * grantees
Definition: parsenodes.h:1760
#define elog
Definition: elog.h:219
AclMode privileges
Definition: aclchk.c:90
Definition: pg_list.h:45
char * priv_name
Definition: parsenodes.h:1787
void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 384 of file aclchk.c.

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_NAMESPACE, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, GrantStmt::behavior, InternalGrant::col_privs, AccessPriv::cols, elog, ereport, errcode(), errmsg(), ERROR, ExecGrantStmt_oids(), get_rolespec_oid(), gettext_noop, InternalGrant::grant_option, GrantStmt::grant_option, InternalGrant::grantees, GrantStmt::grantees, InternalGrant::is_grant, GrantStmt::is_grant, lappend(), lappend_oid(), lfirst, NIL, NULL, 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().

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

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

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

Definition at line 5229 of file acl.c.

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

Referenced by AddRoleMems(), and DelRoleMems().

5230 {
5231  HeapTuple tp;
5232  Form_pg_authid authForm;
5233  char *rolename;
5234 
5235  tp = get_rolespec_tuple(role);
5236  authForm = (Form_pg_authid) GETSTRUCT(tp);
5237  rolename = pstrdup(NameStr(authForm->rolname));
5238  ReleaseSysCache(tp);
5239 
5240  return rolename;
5241 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
char * pstrdup(const char *in)
Definition: mcxt.c:1165
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5185
#define NameStr(name)
Definition: c.h:495
Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

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

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

Definition at line 5185 of file acl.c.

References Assert, AUTHNAME, AUTHOID, CStringGetDatum, elog, ereport, errcode(), errmsg(), ERROR, GetSessionUserId(), GetUserId(), HeapTupleIsValid, NULL, 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().

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

Definition at line 5194 of file aclchk.c.

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

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

5195 {
5196  Acl *result;
5197  Acl *glob_acl;
5198  Acl *schema_acl;
5199  Acl *def_acl;
5200  char defaclobjtype;
5201 
5202  /*
5203  * Use NULL during bootstrap, since pg_default_acl probably isn't there
5204  * yet.
5205  */
5207  return NULL;
5208 
5209  /* Check if object type is supported in pg_default_acl */
5210  switch (objtype)
5211  {
5212  case ACL_OBJECT_RELATION:
5213  defaclobjtype = DEFACLOBJ_RELATION;
5214  break;
5215 
5216  case ACL_OBJECT_SEQUENCE:
5217  defaclobjtype = DEFACLOBJ_SEQUENCE;
5218  break;
5219 
5220  case ACL_OBJECT_FUNCTION:
5221  defaclobjtype = DEFACLOBJ_FUNCTION;
5222  break;
5223 
5224  case ACL_OBJECT_TYPE:
5225  defaclobjtype = DEFACLOBJ_TYPE;
5226  break;
5227 
5228  default:
5229  return NULL;
5230  }
5231 
5232  /* Look up the relevant pg_default_acl entries */
5233  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5234  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5235 
5236  /* Quick out if neither entry exists */
5237  if (glob_acl == NULL && schema_acl == NULL)
5238  return NULL;
5239 
5240  /* We need to know the hard-wired default value, too */
5241  def_acl = acldefault(objtype, ownerId);
5242 
5243  /* If there's no global entry, substitute the hard-wired default */
5244  if (glob_acl == NULL)
5245  glob_acl = def_acl;
5246 
5247  /* Merge in any per-schema privileges */
5248  result = aclmerge(glob_acl, schema_acl, ownerId);
5249 
5250  /*
5251  * For efficiency, we want to return NULL if the result equals default.
5252  * This requires sorting both arrays to get an accurate comparison.
5253  */
5254  aclitemsort(result);
5255  aclitemsort(def_acl);
5256  if (aclequal(result, def_acl))
5257  result = NULL;
5258 
5259  return result;
5260 }
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:5162
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:509
#define DEFACLOBJ_SEQUENCE
#define DEFACLOBJ_TYPE
#define InvalidOid
Definition: postgres_ext.h:36
#define DEFACLOBJ_RELATION
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:451
#define NULL
Definition: c.h:226
#define DEFACLOBJ_FUNCTION
void aclitemsort(Acl *acl)
Definition: acl.c:495
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 5138 of file aclchk.c.

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

Referenced by check_enable_rls(), and RI_Initial_Check().

5139 {
5140  bool result = false;
5141  HeapTuple utup;
5142 
5143  /* Superusers bypass all permission checking. */
5144  if (superuser_arg(roleid))
5145  return true;
5146 
5147  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5148  if (HeapTupleIsValid(utup))
5149  {
5150  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
5151  ReleaseSysCache(utup);
5152  }
5153  return result;
5154 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
bool has_createrole_privilege ( Oid  roleid)

Definition at line 5119 of file aclchk.c.

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

Referenced by check_object_ownership(), and have_createrole_privilege().

5120 {
5121  bool result = false;
5122  HeapTuple utup;
5123 
5124  /* Superusers bypass all permission checking. */
5125  if (superuser_arg(roleid))
5126  return true;
5127 
5128  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
5129  if (HeapTupleIsValid(utup))
5130  {
5131  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
5132  ReleaseSysCache(utup);
5133  }
5134  return result;
5135 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:72
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4831 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_subscription_ownercheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), and ReassignOwnedObjects().

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

Definition at line 4612 of file acl.c.

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

Referenced by InitPostgres().

4613 {
4615  {
4616  /*
4617  * In normal mode, set a callback on any syscache invalidation of
4618  * pg_auth_members rows
4619  */
4622  (Datum) 0);
4623  }
4624 }
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1381
uintptr_t Datum
Definition: postgres.h:374
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4631
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 4913 of file acl.c.

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

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

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

Definition at line 4855 of file acl.c.

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

Referenced by check_is_member_of_role(), check_role(), and pg_role_aclcheck().

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

Definition at line 4893 of file acl.c.

References list_member_oid(), and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

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

Definition at line 398 of file acl.c.

References allocacl().

Referenced by SetDefaultACL().

399 {
400  return allocacl(0);
401 }
static Acl * allocacl(int n)
Definition: acl.c:376
AclResult pg_attribute_aclcheck ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mode 
)

Definition at line 4283 of file aclchk.c.

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

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

4285 {
4286  if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0)
4287  return ACLCHECK_OK;
4288  else
4289  return ACLCHECK_NO_PRIV;
4290 }
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3512
AclResult pg_attribute_aclcheck_all ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how 
)

Definition at line 4312 of file aclchk.c.

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

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

4314 {
4315  AclResult result;
4316  HeapTuple classTuple;
4317  Form_pg_class classForm;
4318  AttrNumber nattrs;
4319  AttrNumber curr_att;
4320 
4321  /*
4322  * Must fetch pg_class row to check number of attributes. As in
4323  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4324  * throwing an error if we get any unexpected lookup errors.
4325  */
4326  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4327  if (!HeapTupleIsValid(classTuple))
4328  return ACLCHECK_NO_PRIV;
4329  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4330 
4331  nattrs = classForm->relnatts;
4332 
4333  ReleaseSysCache(classTuple);
4334 
4335  /*
4336  * Initialize result in case there are no non-dropped columns. We want to
4337  * report failure in such cases for either value of 'how'.
4338  */
4339  result = ACLCHECK_NO_PRIV;
4340 
4341  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4342  {
4343  HeapTuple attTuple;
4344  AclMode attmask;
4345 
4346  attTuple = SearchSysCache2(ATTNUM,
4347  ObjectIdGetDatum(table_oid),
4348  Int16GetDatum(curr_att));
4349  if (!HeapTupleIsValid(attTuple))
4350  continue;
4351 
4352  /* ignore dropped columns */
4353  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4354  {
4355  ReleaseSysCache(attTuple);
4356  continue;
4357  }
4358 
4359  /*
4360  * Here we hard-wire knowledge that the default ACL for a column
4361  * grants no privileges, so that we can fall out quickly in the very
4362  * common case where attacl is null.
4363  */
4365  attmask = 0;
4366  else
4367  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4368  mode, ACLMASK_ANY);
4369 
4370  ReleaseSysCache(attTuple);
4371 
4372  if (attmask != 0)
4373  {
4374  result = ACLCHECK_OK;
4375  if (how == ACLMASK_ANY)
4376  break; /* succeed on any success */
4377  }
4378  else
4379  {
4380  result = ACLCHECK_NO_PRIV;
4381  if (how == ACLMASK_ALL)
4382  break; /* fail on any failure */
4383  }
4384  }
4385 
4386  return result;
4387 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3512
#define Int16GetDatum(X)
Definition: postgres.h:459
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:210
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
uint32 AclMode
Definition: parsenodes.h:63
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
bool heap_attisnull(HeapTuple tup, int attnum)
Definition: heaptuple.c:297
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
AclResult
Definition: acl.h:170
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int16 AttrNumber
Definition: attnum.h:21
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151
AclMode pg_attribute_aclmask ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3512 of file aclchk.c.

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

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

3514 {
3515  AclMode result;
3516  HeapTuple classTuple;
3517  HeapTuple attTuple;
3518  Form_pg_class classForm;
3519  Form_pg_attribute attributeForm;
3520  Datum aclDatum;
3521  bool isNull;
3522  Acl *acl;
3523  Oid ownerId;
3524 
3525  /*
3526  * First, get the column's ACL from its pg_attribute entry
3527  */
3528  attTuple = SearchSysCache2(ATTNUM,
3529  ObjectIdGetDatum(table_oid),
3530  Int16GetDatum(attnum));
3531  if (!HeapTupleIsValid(attTuple))
3532  ereport(ERROR,
3533  (errcode(ERRCODE_UNDEFINED_COLUMN),
3534  errmsg("attribute %d of relation with OID %u does not exist",
3535  attnum, table_oid)));
3536  attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple);
3537 
3538  /* Throw error on dropped columns, too */
3539  if (attributeForm->attisdropped)
3540  ereport(ERROR,
3541  (errcode(ERRCODE_UNDEFINED_COLUMN),
3542  errmsg("attribute %d of relation with OID %u does not exist",
3543  attnum, table_oid)));
3544 
3545  aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3546  &isNull);
3547 
3548  /*
3549  * Here we hard-wire knowledge that the default ACL for a column grants no
3550  * privileges, so that we can fall out quickly in the very common case
3551  * where attacl is null.
3552  */
3553  if (isNull)
3554  {
3555  ReleaseSysCache(attTuple);
3556  return 0;
3557  }
3558 
3559  /*
3560  * Must get the relation's ownerId from pg_class. Since we already found
3561  * a pg_attribute entry, the only likely reason for this to fail is that a
3562  * concurrent DROP of the relation committed since then (which could only
3563  * happen if we don't have lock on the relation). We prefer to report "no
3564  * privileges" rather than failing in such a case, so as to avoid unwanted
3565  * failures in has_column_privilege() tests.
3566  */
3567  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3568  if (!HeapTupleIsValid(classTuple))
3569  {
3570  ReleaseSysCache(attTuple);
3571  return 0;
3572  }
3573  classForm = (Form_pg_class) GETSTRUCT(classTuple);
3574 
3575  ownerId = classForm->relowner;
3576 
3577  ReleaseSysCache(classTuple);
3578 
3579  /* detoast column's ACL if necessary */
3580  acl = DatumGetAclP(aclDatum);
3581 
3582  result = aclmask(acl, roleid, ownerId, mask, how);
3583 
3584  /* if we have a detoasted copy, free it */
3585  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3586  pfree(acl);
3587 
3588  ReleaseSysCache(attTuple);
3589 
3590  return result;
3591 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
#define Int16GetDatum(X)
Definition: postgres.h:459
int errcode(int sqlerrcode)
Definition: elog.c:575
#define Anum_pg_attribute_attacl
Definition: pg_attribute.h:210
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:184
#define ereport(elevel, rest)
Definition: elog.h:122
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:557
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define SearchSysCache2(cacheId, key1, key2)
Definition: syscache.h:151
AclResult pg_class_aclcheck ( Oid  table_oid,
Oid  roleid,
AclMode  mode 
)

Definition at line 4397 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(), ExecBuildSlotValueDescription(), get_rel_from_relname(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), lastval(), LockTableAclCheck(), nextval_internal(), pg_prewarm(), pg_sequence_last_value(), pg_sequence_parameters(), pgrowlocks(), ri_ReportViolation(), transformTableLikeClause(), and truncate_check_rel().

4398 {
4399  if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
4400  return ACLCHECK_OK;
4401  else
4402  return ACLCHECK_NO_PRIV;
4403 }
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3597
AclMode pg_class_aclmask ( Oid  table_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3597 of file aclchk.c.

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

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

3599 {
3600  AclMode result;
3601  HeapTuple tuple;
3602  Form_pg_class classForm;
3603  Datum aclDatum;
3604  bool isNull;
3605  Acl *acl;
3606  Oid ownerId;
3607 
3608  /*
3609  * Must get the relation's tuple from pg_class
3610  */
3611  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3612  if (!HeapTupleIsValid(tuple))
3613  ereport(ERROR,
3615  errmsg("relation with OID %u does not exist",
3616  table_oid)));
3617  classForm = (Form_pg_class) GETSTRUCT(tuple);
3618 
3619  /*
3620  * Deny anyone permission to update a system catalog unless
3621  * pg_authid.rolsuper is set. Also allow it if allowSystemTableMods.
3622  *
3623  * As of 7.4 we have some updatable system views; those shouldn't be
3624  * protected in this way. Assume the view rules can take care of
3625  * themselves. ACL_USAGE is if we ever have system sequences.
3626  */
3627  if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3628  IsSystemClass(table_oid, classForm) &&
3629  classForm->relkind != RELKIND_VIEW &&
3630  !superuser_arg(roleid) &&
3632  {
3633 #ifdef ACLDEBUG
3634  elog(DEBUG2, "permission denied for system catalog update");
3635 #endif
3637  }
3638 
3639  /*
3640  * Otherwise, superusers bypass all permission-checking.
3641  */
3642  if (superuser_arg(roleid))
3643  {
3644 #ifdef ACLDEBUG
3645  elog(DEBUG2, "OID %u is superuser, home free", roleid);
3646 #endif
3647  ReleaseSysCache(tuple);
3648  return mask;
3649  }
3650 
3651  /*
3652  * Normal case: get the relation's ACL from pg_class
3653  */
3654  ownerId = classForm->relowner;
3655 
3656  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
3657  &isNull);
3658  if (isNull)
3659  {
3660  /* No ACL, so build default ACL */
3661  switch (classForm->relkind)
3662  {
3663  case RELKIND_SEQUENCE:
3664  acl = acldefault(ACL_OBJECT_SEQUENCE, ownerId);
3665  break;
3666  default:
3667  acl = acldefault(ACL_OBJECT_RELATION, ownerId);
3668  break;
3669  }
3670  aclDatum = (Datum) 0;
3671  }
3672  else
3673  {
3674  /* detoast rel's ACL if necessary */
3675  acl = DatumGetAclP(aclDatum);
3676  }
3677 
3678  result = aclmask(acl, roleid, ownerId, mask, how);
3679 
3680  /* if we have a detoasted copy, free it */
3681  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3682  pfree(acl);
3683 
3684  ReleaseSysCache(tuple);
3685 
3686  return result;
3687 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
#define Anum_pg_class_relacl
Definition: pg_class.h:133
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ACL_DELETE
Definition: parsenodes.h:68
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition: catalog.c:74
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define DEBUG2
Definition: elog.h:24
#define ACL_USAGE
Definition: parsenodes.h:73
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define ACL_UPDATE
Definition: parsenodes.h:67
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
bool allowSystemTableMods
Definition: globals.c:111
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define ACL_INSERT
Definition: parsenodes.h:65
#define DatumGetPointer(X)
Definition: postgres.h:557
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
#define elog
Definition: elog.h:219
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define ACL_TRUNCATE
Definition: parsenodes.h:69
bool pg_class_ownercheck ( Oid  class_oid,
Oid  roleid 
)

Definition at line 4521 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 AlterSequence(), AlterTableMoveAll(), analyze_rel(), ATExecChangeOwner(), ATPrepSetStatistics(), ATSimplePermissions(), brin_summarize_new_values(), check_enable_rls(), check_object_ownership(), cluster_rel(), DefineQueryRewrite(), EnableDisableRule(), ExecuteTruncate(), get_tables_to_cluster(), gin_clean_pending_list(), MergeAttributes(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), RemoveRoleFromObjectPolicy(), renameatt_check(), RI_Initial_Check(), and vacuum_rel().

4522 {
4523  HeapTuple tuple;
4524  Oid ownerId;
4525 
4526  /* Superusers bypass all permission checking. */
4527  if (superuser_arg(roleid))
4528  return true;
4529 
4530  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid));
4531  if (!HeapTupleIsValid(tuple))
4532  ereport(ERROR,
4534  errmsg("relation with OID %u does not exist", class_oid)));
4535 
4536  ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
4537 
4538  ReleaseSysCache(tuple);
4539 
4540  return has_privs_of_role(roleid, ownerId);
4541 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:61
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_collation_ownercheck ( Oid  coll_oid,
Oid  roleid 
)

Definition at line 4965 of file aclchk.c.

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

Referenced by check_object_ownership().

4966 {
4967  HeapTuple tuple;
4968  Oid ownerId;
4969 
4970  /* Superusers bypass all permission checking. */
4971  if (superuser_arg(roleid))
4972  return true;
4973 
4974  tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid));
4975  if (!HeapTupleIsValid(tuple))
4976  ereport(ERROR,
4977  (errcode(ERRCODE_UNDEFINED_OBJECT),
4978  errmsg("collation with OID %u does not exist", coll_oid)));
4979 
4980  ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner;
4981 
4982  ReleaseSysCache(tuple);
4983 
4984  return has_privs_of_role(roleid, ownerId);
4985 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:47
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_conversion_ownercheck ( Oid  conv_oid,
Oid  roleid 
)

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

4992 {
4993  HeapTuple tuple;
4994  Oid ownerId;
4995 
4996  /* Superusers bypass all permission checking. */
4997  if (superuser_arg(roleid))
4998  return true;
4999 
5000  tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid));
5001  if (!HeapTupleIsValid(tuple))
5002  ereport(ERROR,
5003  (errcode(ERRCODE_UNDEFINED_OBJECT),
5004  errmsg("conversion with OID %u does not exist", conv_oid)));
5005 
5006  ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
5007 
5008  ReleaseSysCache(tuple);
5009 
5010  return has_privs_of_role(roleid, ownerId);
5011 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
FormData_pg_conversion * Form_pg_conversion
Definition: pg_conversion.h:56
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
AclMode pg_database_aclmask ( Oid  db_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3693 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_database_aclcheck().

3695 {
3696  AclMode result;
3697  HeapTuple tuple;
3698  Datum aclDatum;
3699  bool isNull;
3700  Acl *acl;
3701  Oid ownerId;
3702 
3703  /* Superusers bypass all permission checking. */
3704  if (superuser_arg(roleid))
3705  return mask;
3706 
3707  /*
3708  * Get the database's ACL from pg_database
3709  */
3710  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
3711  if (!HeapTupleIsValid(tuple))
3712  ereport(ERROR,
3713  (errcode(ERRCODE_UNDEFINED_DATABASE),
3714  errmsg("database with OID %u does not exist", db_oid)));
3715 
3716  ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
3717 
3719  &isNull);
3720  if (isNull)
3721  {
3722  /* No ACL, so build default ACL */
3723  acl = acldefault(ACL_OBJECT_DATABASE, ownerId);
3724  aclDatum = (Datum) 0;
3725  }
3726  else
3727  {
3728  /* detoast ACL if necessary */
3729  acl = DatumGetAclP(aclDatum);
3730  }
3731 
3732  result = aclmask(acl, roleid, ownerId, mask, how);
3733 
3734  /* if we have a detoasted copy, free it */
3735  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3736  pfree(acl);
3737 
3738  ReleaseSysCache(tuple);
3739 
3740  return result;
3741 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define Anum_pg_database_datacl
Definition: pg_database.h:76
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:557
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_database_ownercheck ( Oid  db_oid,
Oid  roleid 
)

Definition at line 4939 of file aclchk.c.

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

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

4940 {
4941  HeapTuple tuple;
4942  Oid dba;
4943 
4944  /* Superusers bypass all permission checking. */
4945  if (superuser_arg(roleid))
4946  return true;
4947 
4948  tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid));
4949  if (!HeapTupleIsValid(tuple))
4950  ereport(ERROR,
4951  (errcode(ERRCODE_UNDEFINED_DATABASE),
4952  errmsg("database with OID %u does not exist", db_oid)));
4953 
4954  dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba;
4955 
4956  ReleaseSysCache(tuple);
4957 
4958  return has_privs_of_role(roleid, dba);
4959 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_event_trigger_ownercheck ( Oid  et_oid,
Oid  roleid 
)

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

4913 {
4914  HeapTuple tuple;
4915  Oid ownerId;
4916 
4917  /* Superusers bypass all permission checking. */
4918  if (superuser_arg(roleid))
4919  return true;
4920 
4922  if (!HeapTupleIsValid(tuple))
4923  ereport(ERROR,
4924  (errcode(ERRCODE_UNDEFINED_OBJECT),
4925  errmsg("event trigger with OID %u does not exist",
4926  et_oid)));
4927 
4928  ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner;
4929 
4930  ReleaseSysCache(tuple);
4931 
4932  return has_privs_of_role(roleid, ownerId);
4933 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
FormData_pg_event_trigger * Form_pg_event_trigger
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_extension_ownercheck ( Oid  ext_oid,
Oid  roleid 
)

Definition at line 5017 of file aclchk.c.

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

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

5018 {
5019  Relation pg_extension;
5020  ScanKeyData entry[1];
5021  SysScanDesc scan;
5022  HeapTuple tuple;
5023  Oid ownerId;
5024 
5025  /* Superusers bypass all permission checking. */
5026  if (superuser_arg(roleid))
5027  return true;
5028 
5029  /* There's no syscache for pg_extension, so do it the hard way */
5031 
5032  ScanKeyInit(&entry[0],
5034  BTEqualStrategyNumber, F_OIDEQ,
5035  ObjectIdGetDatum(ext_oid));
5036 
5037  scan = systable_beginscan(pg_extension,
5038  ExtensionOidIndexId, true,
5039  NULL, 1, entry);
5040 
5041  tuple = systable_getnext(scan);
5042  if (!HeapTupleIsValid(tuple))
5043  ereport(ERROR,
5044  (errcode(ERRCODE_UNDEFINED_OBJECT),
5045  errmsg("extension with OID %u does not exist", ext_oid)));
5046 
5047  ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner;
5048 
5049  systable_endscan(scan);
5050  heap_close(pg_extension, AccessShareLock);
5051 
5052  return has_privs_of_role(roleid, ownerId);
5053 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define ExtensionOidIndexId
Definition: indexing.h:312
FormData_pg_extension * Form_pg_extension
Definition: pg_extension.h:51
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ExtensionRelationId
Definition: pg_extension.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31
AclResult pg_foreign_data_wrapper_aclcheck ( Oid  fdw_oid,
Oid  roleid,
AclMode  mode 
)
AclMode pg_foreign_data_wrapper_aclmask ( Oid  fdw_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4076 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_foreign_data_wrapper_aclcheck().

4078 {
4079  AclMode result;
4080  HeapTuple tuple;
4081  Datum aclDatum;
4082  bool isNull;
4083  Acl *acl;
4084  Oid ownerId;
4085 
4087 
4088  /* Bypass permission checks for superusers */
4089  if (superuser_arg(roleid))
4090  return mask;
4091 
4092  /*
4093  * Must get the FDW's tuple from pg_foreign_data_wrapper
4094  */
4096  if (!HeapTupleIsValid(tuple))
4097  ereport(ERROR,
4098  (errcode(ERRCODE_UNDEFINED_OBJECT),
4099  errmsg("foreign-data wrapper with OID %u does not exist",
4100  fdw_oid)));
4101  fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple);
4102 
4103  /*
4104  * Normal case: get the FDW's ACL from pg_foreign_data_wrapper
4105  */
4106  ownerId = fdwForm->fdwowner;
4107 
4108  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
4110  if (isNull)
4111  {
4112  /* No ACL, so build default ACL */
4113  acl = acldefault(ACL_OBJECT_FDW, ownerId);
4114  aclDatum = (Datum) 0;
4115  }
4116  else
4117  {
4118  /* detoast rel's ACL if necessary */
4119  acl = DatumGetAclP(aclDatum);
4120  }
4121 
4122  result = aclmask(acl, roleid, ownerId, mask, how);
4123 
4124  /* if we have a detoasted copy, free it */
4125  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4126  pfree(acl);
4127 
4128  ReleaseSysCache(tuple);
4129 
4130  return result;
4131 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define Anum_pg_foreign_data_wrapper_fdwacl
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
#define DatumGetPointer(X)
Definition: postgres.h:557
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_foreign_data_wrapper_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

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

4859 {
4860  HeapTuple tuple;
4861  Oid ownerId;
4862 
4863  /* Superusers bypass all permission checking. */
4864  if (superuser_arg(roleid))
4865  return true;
4866 
4868  if (!HeapTupleIsValid(tuple))
4869  ereport(ERROR,
4870  (errcode(ERRCODE_UNDEFINED_OBJECT),
4871  errmsg("foreign-data wrapper with OID %u does not exist",
4872  srv_oid)));
4873 
4874  ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner;
4875 
4876  ReleaseSysCache(tuple);
4877 
4878  return has_privs_of_role(roleid, ownerId);
4879 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_foreign_data_wrapper * Form_pg_foreign_data_wrapper
int errmsg(const char *fmt,...)
Definition: elog.c:797
AclResult pg_foreign_server_aclcheck ( Oid  srv_oid,
Oid  roleid,
AclMode  mode 
)
AclMode pg_foreign_server_aclmask ( Oid  srv_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 4138 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_foreign_server_aclcheck().

4140 {
4141  AclMode result;
4142  HeapTuple tuple;
4143  Datum aclDatum;
4144  bool isNull;
4145  Acl *acl;
4146  Oid ownerId;
4147 
4148  Form_pg_foreign_server srvForm;
4149 
4150  /* Bypass permission checks for superusers */
4151  if (superuser_arg(roleid))
4152  return mask;
4153 
4154  /*
4155  * Must get the FDW's tuple from pg_foreign_data_wrapper
4156  */
4158  if (!HeapTupleIsValid(tuple))
4159  ereport(ERROR,
4160  (errcode(ERRCODE_UNDEFINED_OBJECT),
4161  errmsg("foreign server with OID %u does not exist",
4162  srv_oid)));
4163  srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple);
4164 
4165  /*
4166  * Normal case: get the foreign server's ACL from pg_foreign_server
4167  */
4168  ownerId = srvForm->srvowner;
4169 
4170  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
4172  if (isNull)
4173  {
4174  /* No ACL, so build default ACL */
4175  acl = acldefault(ACL_OBJECT_FOREIGN_SERVER, ownerId);
4176  aclDatum = (Datum) 0;
4177  }
4178  else
4179  {
4180  /* detoast rel's ACL if necessary */
4181  acl = DatumGetAclP(aclDatum);
4182  }
4183 
4184  result = aclmask(acl, roleid, ownerId, mask, how);
4185 
4186  /* if we have a detoasted copy, free it */
4187  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4188  pfree(acl);
4189 
4190  ReleaseSysCache(tuple);
4191 
4192  return result;
4193 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define Anum_pg_foreign_server_srvacl
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:557
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_foreign_server_ownercheck ( Oid  srv_oid,
Oid  roleid 
)

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

4886 {
4887  HeapTuple tuple;
4888  Oid ownerId;
4889 
4890  /* Superusers bypass all permission checking. */
4891  if (superuser_arg(roleid))
4892  return true;
4893 
4895  if (!HeapTupleIsValid(tuple))
4896  ereport(ERROR,
4897  (errcode(ERRCODE_UNDEFINED_OBJECT),
4898  errmsg("foreign server with OID %u does not exist",
4899  srv_oid)));
4900 
4901  ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner;
4902 
4903  ReleaseSysCache(tuple);
4904 
4905  return has_privs_of_role(roleid, ownerId);
4906 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
FormData_pg_foreign_server * Form_pg_foreign_server
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
AclResult pg_language_aclcheck ( Oid  lang_oid,
Oid  roleid,
AclMode  mode 
)

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

4434 {
4435  if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
4436  return ACLCHECK_OK;
4437  else
4438  return ACLCHECK_NO_PRIV;
4439 }
AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3801
AclMode pg_language_aclmask ( Oid  lang_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3801 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_language_aclcheck().

3803 {
3804  AclMode result;
3805  HeapTuple tuple;
3806  Datum aclDatum;
3807  bool isNull;
3808  Acl *acl;
3809  Oid ownerId;
3810 
3811  /* Superusers bypass all permission checking. */
3812  if (superuser_arg(roleid))
3813  return mask;
3814 
3815  /*
3816  * Get the language's ACL from pg_language
3817  */
3818  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid));
3819  if (!HeapTupleIsValid(tuple))
3820  ereport(ERROR,
3821  (errcode(ERRCODE_UNDEFINED_OBJECT),
3822  errmsg("language with OID %u does not exist", lang_oid)));
3823 
3824  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
3825 
3826  aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
3827  &isNull);
3828  if (isNull)
3829  {
3830  /* No ACL, so build default ACL */
3831  acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId);
3832  aclDatum = (Datum) 0;
3833  }
3834  else
3835  {
3836  /* detoast ACL if necessary */
3837  acl = DatumGetAclP(aclDatum);
3838  }
3839 
3840  result = aclmask(acl, roleid, ownerId, mask, how);
3841 
3842  /* if we have a detoasted copy, free it */
3843  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3844  pfree(acl);
3845 
3846  ReleaseSysCache(tuple);
3847 
3848  return result;
3849 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define DatumGetAclP(X)
Definition: acl.h:113
#define Anum_pg_language_lanacl
Definition: pg_language.h:65
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
uint32 AclMode
Definition: parsenodes.h:63
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
uintptr_t Datum
Definition: postgres.h:374
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1245
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define DatumGetPointer(X)
Definition: postgres.h:557
FormData_pg_language * Form_pg_language
Definition: pg_language.h:51
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool pg_language_ownercheck ( Oid  lan_oid,
Oid  roleid 
)

Definition at line 4625 of file aclchk.c.

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

Referenced by check_object_ownership(), and create_proc_lang().

4626 {
4627  HeapTuple tuple;
4628  Oid ownerId;
4629 
4630  /* Superusers bypass all permission checking. */
4631  if (superuser_arg(roleid))
4632  return true;
4633 
4634  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid));
4635  if (!HeapTupleIsValid(tuple))
4636  ereport(ERROR,
4637  (errcode(ERRCODE_UNDEFINED_FUNCTION),
4638  errmsg("language with OID %u does not exist", lan_oid)));
4639 
4640  ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
4641 
4642  ReleaseSysCache(tuple);
4643 
4644  return has_privs_of_role(roleid, ownerId);
4645 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1083
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_language * Form_pg_language
Definition: pg_language.h:51
int errmsg(const char *fmt,...)
Definition: elog.c:797
AclResult pg_largeobject_aclcheck_snapshot ( Oid  lang_oid,
Oid  roleid,
AclMode  mode,
Snapshot  snapshot 
)

Definition at line 4445 of file aclchk.c.

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

Referenced by lo_get_fragment_internal(), lo_read(), lo_truncate_internal(), and lo_write().

4447 {
4448  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4449  ACLMASK_ANY, snapshot) != 0)
4450  return ACLCHECK_OK;
4451  else
4452  return ACLCHECK_NO_PRIV;
4453 }
AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3864
AclMode pg_largeobject_aclmask_snapshot ( Oid  lobj_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
Snapshot  snapshot 
)

Definition at line 3864 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().

3867 {
3868  AclMode result;
3869  Relation pg_lo_meta;
3870  ScanKeyData entry[1];
3871  SysScanDesc scan;
3872  HeapTuple tuple;
3873  Datum aclDatum;
3874  bool isNull;
3875  Acl *acl;
3876  Oid ownerId;
3877 
3878  /* Superusers bypass all permission checking. */
3879  if (superuser_arg(roleid))
3880  return mask;
3881 
3882  /*
3883  * Get the largeobject's ACL from pg_language_metadata
3884  */
3886  AccessShareLock);
3887 
3888  ScanKeyInit(&entry[0],
3890  BTEqualStrategyNumber, F_OIDEQ,
3891  ObjectIdGetDatum(lobj_oid));
3892 
3893  scan = systable_beginscan(pg_lo_meta,
3895  snapshot, 1, entry);
3896 
3897  tuple = systable_getnext(scan);
3898  if (!HeapTupleIsValid(tuple))
3899  ereport(ERROR,
3900  (errcode(ERRCODE_UNDEFINED_OBJECT),
3901  errmsg("large object %u does not exist", lobj_oid)));
3902 
3903  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
3904 
3906  RelationGetDescr(pg_lo_meta), &isNull);
3907 
3908  if (isNull)
3909  {
3910  /* No ACL, so build default ACL */
3911  acl = acldefault(ACL_OBJECT_LARGEOBJECT, ownerId);
3912  aclDatum = (Datum) 0;
3913  }
3914  else
3915  {
3916  /* detoast ACL if necessary */
3917  acl = DatumGetAclP(aclDatum);
3918  }
3919 
3920  result = aclmask(acl, roleid, ownerId, mask, how);
3921 
3922  /* if we have a detoasted copy, free it */
3923  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
3924  pfree(acl);
3925 
3926  systable_endscan(scan);
3927 
3928  heap_close(pg_lo_meta, AccessShareLock);
3929 
3930  return result;
3931 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:425
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
#define AccessShareLock
Definition: lockdefs.h:36
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: acl.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
uint32 AclMode
Definition: parsenodes.h:63
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define LargeObjectMetadataOidIndexId
Definition: indexing.h:183
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
uintptr_t Datum
Definition: postgres.h:374
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define LargeObjectMetadataRelationId
#define DatumGetPointer(X)
Definition: postgres.h:557
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define Anum_pg_largeobject_metadata_lomacl
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
bool pg_largeobject_ownercheck ( Oid  lobj_oid,
Oid  roleid 
)

Definition at line 4654 of file aclchk.c.

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

Referenced by be_lo_unlink(), and check_object_ownership().

4655 {
4656  Relation pg_lo_meta;
4657  ScanKeyData entry[1];
4658  SysScanDesc scan;
4659  HeapTuple tuple;
4660  Oid ownerId;
4661 
4662  /* Superusers bypass all permission checking. */
4663  if (superuser_arg(roleid))
4664  return true;
4665 
4666  /* There's no syscache for pg_largeobject_metadata */
4668  AccessShareLock);
4669 
4670  ScanKeyInit(&entry[0],
4672  BTEqualStrategyNumber, F_OIDEQ,
4673  ObjectIdGetDatum(lobj_oid));
4674 
4675  scan = systable_beginscan(pg_lo_meta,
4677  NULL, 1, entry);
4678 
4679  tuple = systable_getnext(scan);
4680  if (!HeapTupleIsValid(tuple))
4681  ereport(ERROR,
4682  (errcode(ERRCODE_UNDEFINED_OBJECT),
4683  errmsg("large object %u does not exist", lobj_oid)));
4684 
4685  ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
4686 
4687  systable_endscan(scan);
4688  heap_close(pg_lo_meta, AccessShareLock);
4689 
4690  return has_privs_of_role(roleid, ownerId);
4691 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:493
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4831
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:322
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:410
#define ObjectIdGetDatum(X)
Definition: postgres.h:515
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool superuser_arg(Oid roleid)
Definition: superuser.c:57
#define LargeObjectMetadataOidIndexId
Definition: indexing.h:183
FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:226
#define LargeObjectMetadataRelationId
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
AclMode pg_namespace_aclmask ( Oid  nsp_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3937 of file aclchk.c.

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

Referenced by pg_aclmask(), and pg_namespace_aclcheck().

3939 {
3940  AclMode result;
3941  HeapTuple tuple;
3942  Datum aclDatum;
3943  bool isNull;
3944  Acl *acl;
3945  Oid ownerId;
3946 
3947  /* Superusers bypass all permission checking. */
3948  if (superuser_arg(roleid))
3949  return mask;
3950 
3951  /*
3952  * If we have been assigned this namespace as a temp namespace, check to
3953  * make sure we have CREATE TEMP permission on the database, and if so act
3954  * as though we have all standard (but not GRANT OPTION) permissions on
3955  * the namespace. If we don't have CREATE TEMP, act as though we have
3956  * only USAGE (and not CREATE) rights.
3957  *
3958  * This may seem redundant given the check in InitTempTableNamespace, but
3959  * it really isn't since current user ID may have changed since then. The
3960  * upshot of this behavior is that a SECURITY DEFINER function can create
3961  * temp tables that can then be accessed (if permission is granted) by
3962  * code in the same session that doesn't have permissions to create temp
3963  * tables.
3964  *
3965  * XXX Would it be safe to ereport a special error message as
3966  * InitTempTableNamespace does? Returning zero here means we'll get a
3967  * generic "permission denied for schema pg_temp_N" message, which is not
3968  * remarkably user-friendly.
3969  */
3970  if (isTempNamespace(nsp_oid))
3971  {
3972  if (pg_database_aclcheck(MyDatabaseId, roleid,
3974  return mask & ACL_ALL_RIGHTS_NAMESPACE;
3975  else
3976  return mask & ACL_USAGE;
3977  }
3978 
3979  /*
3980  * Get the schema's ACL from pg_namespace
3981  */
3982  tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid));
3983  if (!HeapTupleIsValid(tuple))
3984  ereport(ERROR,
3985  (errcode(ERRCODE_UNDEFINED_SCHEMA),
3986  errmsg("schema with OID %u does not exist", nsp_oid)));
3987 
3988  ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
3989 
3991  &isNull);
3992  if (isNull)
3993  {
3994  /* No ACL, so build default ACL */
3995  acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId);
3996  aclDatum = (Datum) 0;
3997  }
3998  else
3999  {
4000  /* detoast ACL if necessary */
4001  acl = DatumGetAclP(aclDatum);
4002  }
4003 
4004  result = aclmask(acl, roleid, ownerId, mask, how);
4005 
4006  /* if we have a detoasted copy, free it */
4007  if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
4008  pfree(acl);
4009 
4010  ReleaseSysCache(tuple);
4011 
4012  return result;
4013 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:51
#define DatumGetAclP(X)
Definition: acl.h:113
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1305
Acl * acldefault(GrantObjectType objtype, Oid ownerId)
Definition: