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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

#define ACL_ID_PUBLIC   0 /* placeholder for id in a PUBLIC acl item */
 
#define ACLITEM_GET_PRIVS(item)   ((item).ai_privs & 0xFFFFFFFF)
 
#define ACLITEM_GET_GOPTIONS(item)   (((item).ai_privs >> 32) & 0xFFFFFFFF)
 
#define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
 
#define ACL_GRANT_OPTION_FOR(privs)   (((AclMode) (privs) & 0xFFFFFFFF) << 32)
 
#define ACL_OPTION_TO_PRIVS(privs)   (((AclMode) (privs) >> 32) & 0xFFFFFFFF)
 
#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) 0xFFFFFFFF)
 
#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFFFFFF << 32)
 
#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_SET_CHR   's'
 
#define ACL_ALTER_SYSTEM_CHR   'A'
 
#define ACL_MAINTAIN_CHR   'm'
 
#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"
 
#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|ACL_MAINTAIN)
 
#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_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)
 
#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)
 
#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)
 

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

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

Functions

Aclacldefault (ObjectType objtype, Oid ownerId)
 
Aclget_user_default_acl (ObjectType objtype, Oid ownerId, Oid nsp_oid)
 
void recordDependencyOnNewAcl (Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
 
Aclaclupdate (const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
 
Aclaclnewowner (const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
 
Aclmake_empty_acl (void)
 
Aclaclcopy (const Acl *orig_acl)
 
Aclaclconcat (const Acl *left_acl, const Acl *right_acl)
 
Aclaclmerge (const Acl *left_acl, const Acl *right_acl, Oid ownerId)
 
void aclitemsort (Acl *acl)
 
bool aclequal (const Acl *left_acl, const Acl *right_acl)
 
AclMode aclmask (const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
 
int aclmembers (const Acl *acl, Oid **roleids)
 
bool has_privs_of_role (Oid member, Oid role)
 
bool member_can_set_role (Oid member, Oid role)
 
void check_can_set_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)
 
Oid select_best_admin (Oid member, Oid role)
 
Oid get_role_oid (const char *rolname, bool missing_ok)
 
Oid get_role_oid_or_public (const char *rolname)
 
Oid get_rolespec_oid (const RoleSpec *role, bool missing_ok)
 
void check_rolespec_name (const RoleSpec *role, const char *detail_msg)
 
HeapTuple get_rolespec_tuple (const RoleSpec *role)
 
char * get_rolespec_name (const RoleSpec *role)
 
void select_best_grantor (Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult object_aclcheck (Oid classid, Oid objectid, Oid roleid, AclMode mode)
 
AclResult object_aclcheck_ext (Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_attribute_aclcheck_all_ext (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_parameter_aclcheck (const char *name, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
void ReplaceRoleInInitPriv (Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
 
void RemoveRoleFromInitPriv (Oid roleid, Oid classid, Oid objid, int32 objsubid)
 
bool object_ownercheck (Oid classid, Oid objectid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 171 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

#define ACL_DAT (   ACL)    ((AclItem *) ARR_DATA_PTR(ACL))

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

#define ACL_GRANT_OPTION_FOR (   privs)    (((AclMode) (privs) & 0xFFFFFFFF) << 32)

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

#define ACL_OPTION_TO_PRIVS (   privs)    (((AclMode) (privs) >> 32) & 0xFFFFFFFF)

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFFFFFF << 32)

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

#define ACLITEM_GET_GOPTIONS (   item)    (((item).ai_privs >> 32) & 0xFFFFFFFF)

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

#define ACLITEM_SET_GOPTIONS (   item,
  goptions 
)
Value:
((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFFFFFF) << 32)) | \
(((AclMode) (goptions) & 0xFFFFFFFF) << 32))
uint64 AclMode
Definition: parsenodes.h:74

Definition at line 76 of file acl.h.

◆ ACLITEM_SET_PRIVS

#define ACLITEM_SET_PRIVS (   item,
  privs 
)
Value:
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFFFFFF)) | \
((AclMode) (privs) & 0xFFFFFFFF))

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

#define ACLITEM_SET_PRIVS_GOPTIONS (   item,
  privs,
  goptions 
)
Value:
((item).ai_privs = ((AclMode) (privs) & 0xFFFFFFFF) | \
(((AclMode) (goptions) & 0xFFFFFFFF) << 32))

Definition at line 82 of file acl.h.

◆ ACLITEM_SET_RIGHTS

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

Definition at line 79 of file acl.h.

◆ DatumGetAclItemP

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

Definition at line 116 of file acl.h.

◆ DatumGetAclP

#define DatumGetAclP (   X)    ((Acl *) PG_DETOAST_DATUM(X))

Definition at line 120 of file acl.h.

◆ DatumGetAclPCopy

#define DatumGetAclPCopy (   X)    ((Acl *) PG_DETOAST_DATUM_COPY(X))

Definition at line 121 of file acl.h.

◆ PG_GETARG_ACL_P

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

Definition at line 122 of file acl.h.

◆ PG_GETARG_ACL_P_COPY

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

Definition at line 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 117 of file acl.h.

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 124 of file acl.h.

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 118 of file acl.h.

Typedef Documentation

◆ Acl

typedef struct ArrayType Acl

Definition at line 106 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 174 of file acl.h.

175{
176 ACLMASK_ALL, /* normal case: compute all bits */
177 ACLMASK_ANY, /* return when result is known nonzero */
178} AclMaskHow;
AclMaskHow
Definition: acl.h:175
@ ACLMASK_ANY
Definition: acl.h:177
@ ACLMASK_ALL
Definition: acl.h:176

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 181 of file acl.h.

182{
183 ACLCHECK_OK = 0,
186} AclResult;
AclResult
Definition: acl.h:182
@ ACLCHECK_NO_PRIV
Definition: acl.h:184
@ ACLCHECK_OK
Definition: acl.h:183
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185

Function Documentation

◆ aclcheck_error()

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

Definition at line 2654 of file aclchk.c.

2656{
2657 switch (aclerr)
2658 {
2659 case ACLCHECK_OK:
2660 /* no error, so return to caller */
2661 break;
2662 case ACLCHECK_NO_PRIV:
2663 {
2664 const char *msg = "???";
2665
2666 switch (objtype)
2667 {
2668 case OBJECT_AGGREGATE:
2669 msg = gettext_noop("permission denied for aggregate %s");
2670 break;
2671 case OBJECT_COLLATION:
2672 msg = gettext_noop("permission denied for collation %s");
2673 break;
2674 case OBJECT_COLUMN:
2675 msg = gettext_noop("permission denied for column %s");
2676 break;
2677 case OBJECT_CONVERSION:
2678 msg = gettext_noop("permission denied for conversion %s");
2679 break;
2680 case OBJECT_DATABASE:
2681 msg = gettext_noop("permission denied for database %s");
2682 break;
2683 case OBJECT_DOMAIN:
2684 msg = gettext_noop("permission denied for domain %s");
2685 break;
2687 msg = gettext_noop("permission denied for event trigger %s");
2688 break;
2689 case OBJECT_EXTENSION:
2690 msg = gettext_noop("permission denied for extension %s");
2691 break;
2692 case OBJECT_FDW:
2693 msg = gettext_noop("permission denied for foreign-data wrapper %s");
2694 break;
2696 msg = gettext_noop("permission denied for foreign server %s");
2697 break;
2699 msg = gettext_noop("permission denied for foreign table %s");
2700 break;
2701 case OBJECT_FUNCTION:
2702 msg = gettext_noop("permission denied for function %s");
2703 break;
2704 case OBJECT_INDEX:
2705 msg = gettext_noop("permission denied for index %s");
2706 break;
2707 case OBJECT_LANGUAGE:
2708 msg = gettext_noop("permission denied for language %s");
2709 break;
2710 case OBJECT_LARGEOBJECT:
2711 msg = gettext_noop("permission denied for large object %s");
2712 break;
2713 case OBJECT_MATVIEW:
2714 msg = gettext_noop("permission denied for materialized view %s");
2715 break;
2716 case OBJECT_OPCLASS:
2717 msg = gettext_noop("permission denied for operator class %s");
2718 break;
2719 case OBJECT_OPERATOR:
2720 msg = gettext_noop("permission denied for operator %s");
2721 break;
2722 case OBJECT_OPFAMILY:
2723 msg = gettext_noop("permission denied for operator family %s");
2724 break;
2726 msg = gettext_noop("permission denied for parameter %s");
2727 break;
2728 case OBJECT_POLICY:
2729 msg = gettext_noop("permission denied for policy %s");
2730 break;
2731 case OBJECT_PROCEDURE:
2732 msg = gettext_noop("permission denied for procedure %s");
2733 break;
2734 case OBJECT_PUBLICATION:
2735 msg = gettext_noop("permission denied for publication %s");
2736 break;
2737 case OBJECT_ROUTINE:
2738 msg = gettext_noop("permission denied for routine %s");
2739 break;
2740 case OBJECT_SCHEMA:
2741 msg = gettext_noop("permission denied for schema %s");
2742 break;
2743 case OBJECT_SEQUENCE:
2744 msg = gettext_noop("permission denied for sequence %s");
2745 break;
2747 msg = gettext_noop("permission denied for statistics object %s");
2748 break;
2750 msg = gettext_noop("permission denied for subscription %s");
2751 break;
2752 case OBJECT_TABLE:
2753 msg = gettext_noop("permission denied for table %s");
2754 break;
2755 case OBJECT_TABLESPACE:
2756 msg = gettext_noop("permission denied for tablespace %s");
2757 break;
2759 msg = gettext_noop("permission denied for text search configuration %s");
2760 break;
2762 msg = gettext_noop("permission denied for text search dictionary %s");
2763 break;
2764 case OBJECT_TYPE:
2765 msg = gettext_noop("permission denied for type %s");
2766 break;
2767 case OBJECT_VIEW:
2768 msg = gettext_noop("permission denied for view %s");
2769 break;
2770 /* these currently aren't used */
2772 case OBJECT_AMOP:
2773 case OBJECT_AMPROC:
2774 case OBJECT_ATTRIBUTE:
2775 case OBJECT_CAST:
2776 case OBJECT_DEFAULT:
2777 case OBJECT_DEFACL:
2781 case OBJECT_ROLE:
2782 case OBJECT_RULE:
2784 case OBJECT_TRANSFORM:
2785 case OBJECT_TRIGGER:
2786 case OBJECT_TSPARSER:
2787 case OBJECT_TSTEMPLATE:
2789 elog(ERROR, "unsupported object type: %d", objtype);
2790 }
2791
2792 ereport(ERROR,
2793 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2794 errmsg(msg, objectname)));
2795 break;
2796 }
2797 case ACLCHECK_NOT_OWNER:
2798 {
2799 const char *msg = "???";
2800
2801 switch (objtype)
2802 {
2803 case OBJECT_AGGREGATE:
2804 msg = gettext_noop("must be owner of aggregate %s");
2805 break;
2806 case OBJECT_COLLATION:
2807 msg = gettext_noop("must be owner of collation %s");
2808 break;
2809 case OBJECT_CONVERSION:
2810 msg = gettext_noop("must be owner of conversion %s");
2811 break;
2812 case OBJECT_DATABASE:
2813 msg = gettext_noop("must be owner of database %s");
2814 break;
2815 case OBJECT_DOMAIN:
2816 msg = gettext_noop("must be owner of domain %s");
2817 break;
2819 msg = gettext_noop("must be owner of event trigger %s");
2820 break;
2821 case OBJECT_EXTENSION:
2822 msg = gettext_noop("must be owner of extension %s");
2823 break;
2824 case OBJECT_FDW:
2825 msg = gettext_noop("must be owner of foreign-data wrapper %s");
2826 break;
2828 msg = gettext_noop("must be owner of foreign server %s");
2829 break;
2831 msg = gettext_noop("must be owner of foreign table %s");
2832 break;
2833 case OBJECT_FUNCTION:
2834 msg = gettext_noop("must be owner of function %s");
2835 break;
2836 case OBJECT_INDEX:
2837 msg = gettext_noop("must be owner of index %s");
2838 break;
2839 case OBJECT_LANGUAGE:
2840 msg = gettext_noop("must be owner of language %s");
2841 break;
2842 case OBJECT_LARGEOBJECT:
2843 msg = gettext_noop("must be owner of large object %s");
2844 break;
2845 case OBJECT_MATVIEW:
2846 msg = gettext_noop("must be owner of materialized view %s");
2847 break;
2848 case OBJECT_OPCLASS:
2849 msg = gettext_noop("must be owner of operator class %s");
2850 break;
2851 case OBJECT_OPERATOR:
2852 msg = gettext_noop("must be owner of operator %s");
2853 break;
2854 case OBJECT_OPFAMILY:
2855 msg = gettext_noop("must be owner of operator family %s");
2856 break;
2857 case OBJECT_PROCEDURE:
2858 msg = gettext_noop("must be owner of procedure %s");
2859 break;
2860 case OBJECT_PUBLICATION:
2861 msg = gettext_noop("must be owner of publication %s");
2862 break;
2863 case OBJECT_ROUTINE:
2864 msg = gettext_noop("must be owner of routine %s");
2865 break;
2866 case OBJECT_SEQUENCE:
2867 msg = gettext_noop("must be owner of sequence %s");
2868 break;
2870 msg = gettext_noop("must be owner of subscription %s");
2871 break;
2872 case OBJECT_TABLE:
2873 msg = gettext_noop("must be owner of table %s");
2874 break;
2875 case OBJECT_TYPE:
2876 msg = gettext_noop("must be owner of type %s");
2877 break;
2878 case OBJECT_VIEW:
2879 msg = gettext_noop("must be owner of view %s");
2880 break;
2881 case OBJECT_SCHEMA:
2882 msg = gettext_noop("must be owner of schema %s");
2883 break;
2885 msg = gettext_noop("must be owner of statistics object %s");
2886 break;
2887 case OBJECT_TABLESPACE:
2888 msg = gettext_noop("must be owner of tablespace %s");
2889 break;
2891 msg = gettext_noop("must be owner of text search configuration %s");
2892 break;
2894 msg = gettext_noop("must be owner of text search dictionary %s");
2895 break;
2896
2897 /*
2898 * Special cases: For these, the error message talks
2899 * about "relation", because that's where the
2900 * ownership is attached. See also
2901 * check_object_ownership().
2902 */
2903 case OBJECT_COLUMN:
2904 case OBJECT_POLICY:
2905 case OBJECT_RULE:
2907 case OBJECT_TRIGGER:
2908 msg = gettext_noop("must be owner of relation %s");
2909 break;
2910 /* these currently aren't used */
2912 case OBJECT_AMOP:
2913 case OBJECT_AMPROC:
2914 case OBJECT_ATTRIBUTE:
2915 case OBJECT_CAST:
2916 case OBJECT_DEFAULT:
2917 case OBJECT_DEFACL:
2922 case OBJECT_ROLE:
2923 case OBJECT_TRANSFORM:
2924 case OBJECT_TSPARSER:
2925 case OBJECT_TSTEMPLATE:
2927 elog(ERROR, "unsupported object type: %d", objtype);
2928 }
2929
2930 ereport(ERROR,
2931 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2932 errmsg(msg, objectname)));
2933 break;
2934 }
2935 default:
2936 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2937 break;
2938 }
2939}
#define gettext_noop(x)
Definition: c.h:1194
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2339
@ OBJECT_FDW
Definition: parsenodes.h:2341
@ OBJECT_TSPARSER
Definition: parsenodes.h:2372
@ OBJECT_COLLATION
Definition: parsenodes.h:2332
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2375
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2325
@ OBJECT_OPCLASS
Definition: parsenodes.h:2349
@ OBJECT_DEFACL
Definition: parsenodes.h:2336
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2326
@ OBJECT_MATVIEW
Definition: parsenodes.h:2348
@ OBJECT_SCHEMA
Definition: parsenodes.h:2361
@ OBJECT_POLICY
Definition: parsenodes.h:2353
@ OBJECT_OPERATOR
Definition: parsenodes.h:2350
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2343
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2370
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2351
@ OBJECT_DOMAIN
Definition: parsenodes.h:2337
@ OBJECT_COLUMN
Definition: parsenodes.h:2331
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2367
@ OBJECT_ROLE
Definition: parsenodes.h:2358
@ OBJECT_ROUTINE
Definition: parsenodes.h:2359
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2347
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2356
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2354
@ OBJECT_EXTENSION
Definition: parsenodes.h:2340
@ OBJECT_INDEX
Definition: parsenodes.h:2345
@ OBJECT_DEFAULT
Definition: parsenodes.h:2335
@ OBJECT_DATABASE
Definition: parsenodes.h:2334
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2362
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2373
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2346
@ OBJECT_AMOP
Definition: parsenodes.h:2327
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2357
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2342
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2371
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2329
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2355
@ OBJECT_RULE
Definition: parsenodes.h:2360
@ OBJECT_CONVERSION
Definition: parsenodes.h:2333
@ OBJECT_AMPROC
Definition: parsenodes.h:2328
@ OBJECT_TABLE
Definition: parsenodes.h:2366
@ OBJECT_VIEW
Definition: parsenodes.h:2376
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2352
@ OBJECT_TYPE
Definition: parsenodes.h:2374
@ OBJECT_FUNCTION
Definition: parsenodes.h:2344
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2365
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2338
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2363
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2364
@ OBJECT_CAST
Definition: parsenodes.h:2330
@ OBJECT_TRIGGER
Definition: parsenodes.h:2369
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2368

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

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), currtid_internal(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecCheckPermissions(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_prewarm(), pgrowlocks(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDblink(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackForStats(), RangeVarCallbackMaintainsTable(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), subquery_planner(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), ValidateOperatorReference(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

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

Definition at line 2943 of file aclchk.c.

2945{
2946 switch (aclerr)
2947 {
2948 case ACLCHECK_OK:
2949 /* no error, so return to caller */
2950 break;
2951 case ACLCHECK_NO_PRIV:
2952 ereport(ERROR,
2953 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2954 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2955 colname, objectname)));
2956 break;
2957 case ACLCHECK_NOT_OWNER:
2958 /* relation msg is OK since columns don't have separate owners */
2959 aclcheck_error(aclerr, objtype, objectname);
2960 break;
2961 default:
2962 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2963 break;
2964 }
2965}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2654

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

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

void aclcheck_error_type ( AclResult  aclerr,
Oid  typeOid 
)

◆ aclconcat()

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

Definition at line 477 of file acl.c.

478{
479 Acl *result_acl;
480
481 result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
482
483 memcpy(ACL_DAT(result_acl),
484 ACL_DAT(left_acl),
485 ACL_NUM(left_acl) * sizeof(AclItem));
486
487 memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
488 ACL_DAT(right_acl),
489 ACL_NUM(right_acl) * sizeof(AclItem));
490
491 return result_acl;
492}
static Acl * allocacl(int n)
Definition: acl.c:426
#define ACL_DAT(ACL)
Definition: acl.h:109
#define ACL_NUM(ACL)
Definition: acl.h:108
Definition: acl.h:55

References ACL_DAT, ACL_NUM, and allocacl().

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl * aclcopy ( const Acl orig_acl)

Definition at line 457 of file acl.c.

458{
459 Acl *result_acl;
460
461 result_acl = allocacl(ACL_NUM(orig_acl));
462
463 memcpy(ACL_DAT(result_acl),
464 ACL_DAT(orig_acl),
465 ACL_NUM(orig_acl) * sizeof(AclItem));
466
467 return result_acl;
468}

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 803 of file acl.c.

804{
805 AclMode world_default;
806 AclMode owner_default;
807 int nacl;
808 Acl *acl;
809 AclItem *aip;
810
811 switch (objtype)
812 {
813 case OBJECT_COLUMN:
814 /* by default, columns have no extra privileges */
815 world_default = ACL_NO_RIGHTS;
816 owner_default = ACL_NO_RIGHTS;
817 break;
818 case OBJECT_TABLE:
819 world_default = ACL_NO_RIGHTS;
820 owner_default = ACL_ALL_RIGHTS_RELATION;
821 break;
822 case OBJECT_SEQUENCE:
823 world_default = ACL_NO_RIGHTS;
824 owner_default = ACL_ALL_RIGHTS_SEQUENCE;
825 break;
826 case OBJECT_DATABASE:
827 /* for backwards compatibility, grant some rights by default */
828 world_default = ACL_CREATE_TEMP | ACL_CONNECT;
829 owner_default = ACL_ALL_RIGHTS_DATABASE;
830 break;
831 case OBJECT_FUNCTION:
832 /* Grant EXECUTE by default, for now */
833 world_default = ACL_EXECUTE;
834 owner_default = ACL_ALL_RIGHTS_FUNCTION;
835 break;
836 case OBJECT_LANGUAGE:
837 /* Grant USAGE by default, for now */
838 world_default = ACL_USAGE;
839 owner_default = ACL_ALL_RIGHTS_LANGUAGE;
840 break;
842 world_default = ACL_NO_RIGHTS;
843 owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
844 break;
845 case OBJECT_SCHEMA:
846 world_default = ACL_NO_RIGHTS;
847 owner_default = ACL_ALL_RIGHTS_SCHEMA;
848 break;
850 world_default = ACL_NO_RIGHTS;
851 owner_default = ACL_ALL_RIGHTS_TABLESPACE;
852 break;
853 case OBJECT_FDW:
854 world_default = ACL_NO_RIGHTS;
855 owner_default = ACL_ALL_RIGHTS_FDW;
856 break;
858 world_default = ACL_NO_RIGHTS;
859 owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
860 break;
861 case OBJECT_DOMAIN:
862 case OBJECT_TYPE:
863 world_default = ACL_USAGE;
864 owner_default = ACL_ALL_RIGHTS_TYPE;
865 break;
867 world_default = ACL_NO_RIGHTS;
868 owner_default = ACL_ALL_RIGHTS_PARAMETER_ACL;
869 break;
870 default:
871 elog(ERROR, "unrecognized object type: %d", (int) objtype);
872 world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
873 owner_default = ACL_NO_RIGHTS;
874 break;
875 }
876
877 nacl = 0;
878 if (world_default != ACL_NO_RIGHTS)
879 nacl++;
880 if (owner_default != ACL_NO_RIGHTS)
881 nacl++;
882
883 acl = allocacl(nacl);
884 aip = ACL_DAT(acl);
885
886 if (world_default != ACL_NO_RIGHTS)
887 {
889 aip->ai_grantor = ownerId;
890 ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
891 aip++;
892 }
893
894 /*
895 * Note that the owner's entry shows all ordinary privileges but no grant
896 * options. This is because his grant options come "from the system" and
897 * not from his own efforts. (The SQL spec says that the owner's rights
898 * come from a "_SYSTEM" authid.) However, we do consider that the
899 * owner's ordinary privileges are self-granted; this lets him revoke
900 * them. We implement the owner's grant options without any explicit
901 * "_SYSTEM"-like ACL entry, by internally special-casing the owner
902 * wherever we are testing grant options.
903 */
904 if (owner_default != ACL_NO_RIGHTS)
905 {
906 aip->ai_grantee = ownerId;
907 aip->ai_grantor = ownerId;
908 ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
909 }
910
911 return acl;
912}
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:164
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:170
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition: acl.h:168
#define ACL_ALL_RIGHTS_SCHEMA
Definition: acl.h:169
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:161
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:162
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:165
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:166
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:171
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:163
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:160
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:167
#define ACL_CREATE_TEMP
Definition: parsenodes.h:86
#define ACL_USAGE
Definition: parsenodes.h:84
#define ACL_NO_RIGHTS
Definition: parsenodes.h:92
#define ACL_CONNECT
Definition: parsenodes.h:87
#define ACL_EXECUTE
Definition: parsenodes.h:83
Oid ai_grantee
Definition: acl.h:56
Oid ai_grantor
Definition: acl.h:57

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog, ERROR, OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

Referenced by acldefault_sql(), buildDefaultACLCommands(), dumpACL(), dumpRoleGUCPrivs(), dumpTable(), dumpTablespaces(), ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), get_user_default_acl(), object_aclmask_ext(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask_ext(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask_ext(), and SetDefaultACL().

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 559 of file acl.c.

560{
561 /* Check for cases where one or both are empty/null */
562 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
563 {
564 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
565 return true;
566 else
567 return false;
568 }
569 else
570 {
571 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
572 return false;
573 }
574
575 if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
576 return false;
577
578 if (memcmp(ACL_DAT(left_acl),
579 ACL_DAT(right_acl),
580 ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
581 return true;
582
583 return false;
584}

References ACL_DAT, and ACL_NUM.

Referenced by ExecGrant_Parameter(), get_user_default_acl(), and SetDefaultACL().

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 545 of file acl.c.

546{
547 if (acl != NULL && ACL_NUM(acl) > 1)
548 qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
549}
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:724
#define qsort(a, b, c, d)
Definition: port.h:499

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

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclmask()

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

Definition at line 1388 of file acl.c.

1390{
1391 AclMode result;
1393 AclItem *aidat;
1394 int i,
1395 num;
1396
1397 /*
1398 * Null ACL should not happen, since caller should have inserted
1399 * appropriate default
1400 */
1401 if (acl == NULL)
1402 elog(ERROR, "null ACL");
1403
1404 check_acl(acl);
1405
1406 /* Quick exit for mask == 0 */
1407 if (mask == 0)
1408 return 0;
1409
1410 result = 0;
1411
1412 /* Owner always implicitly has all grant options */
1413 if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1414 has_privs_of_role(roleid, ownerId))
1415 {
1416 result = mask & ACLITEM_ALL_GOPTION_BITS;
1417 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1418 return result;
1419 }
1420
1421 num = ACL_NUM(acl);
1422 aidat = ACL_DAT(acl);
1423
1424 /*
1425 * Check privileges granted directly to roleid or to public
1426 */
1427 for (i = 0; i < num; i++)
1428 {
1429 AclItem *aidata = &aidat[i];
1430
1431 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1432 aidata->ai_grantee == roleid)
1433 {
1434 result |= aidata->ai_privs & mask;
1435 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1436 return result;
1437 }
1438 }
1439
1440 /*
1441 * Check privileges granted indirectly via role memberships. We do this in
1442 * a separate pass to minimize expensive indirect membership tests. In
1443 * particular, it's worth testing whether a given ACL entry grants any
1444 * privileges still of interest before we perform the has_privs_of_role
1445 * test.
1446 */
1447 remaining = mask & ~result;
1448 for (i = 0; i < num; i++)
1449 {
1450 AclItem *aidata = &aidat[i];
1451
1452 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1453 aidata->ai_grantee == roleid)
1454 continue; /* already checked it */
1455
1456 if ((aidata->ai_privs & remaining) &&
1457 has_privs_of_role(roleid, aidata->ai_grantee))
1458 {
1459 result |= aidata->ai_privs & mask;
1460 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1461 return result;
1462 remaining = mask & ~result;
1463 }
1464 }
1465
1466 return result;
1467}
static void check_acl(const Acl *acl)
Definition: acl.c:590
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:5284
#define ACLITEM_ALL_GOPTION_BITS
Definition: acl.h:88
int remaining
Definition: informix.c:692
int i
Definition: isn.c:77
AclMode ai_privs
Definition: acl.h:58

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

Referenced by check_circularity(), LockTableAclCheck(), object_aclmask_ext(), pg_attribute_aclcheck_all_ext(), pg_attribute_aclmask_ext(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask_ext(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask_ext(), and recursive_revoke().

◆ aclmembers()

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

Definition at line 1540 of file acl.c.

1541{
1542 Oid *list;
1543 const AclItem *acldat;
1544 int i,
1545 j;
1546
1547 if (acl == NULL || ACL_NUM(acl) == 0)
1548 {
1549 *roleids = NULL;
1550 return 0;
1551 }
1552
1553 check_acl(acl);
1554
1555 /* Allocate the worst-case space requirement */
1556 list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1557 acldat = ACL_DAT(acl);
1558
1559 /*
1560 * Walk the ACL collecting mentioned RoleIds.
1561 */
1562 j = 0;
1563 for (i = 0; i < ACL_NUM(acl); i++)
1564 {
1565 const AclItem *ai = &acldat[i];
1566
1567 if (ai->ai_grantee != ACL_ID_PUBLIC)
1568 list[j++] = ai->ai_grantee;
1569 /* grantor is currently never PUBLIC, but let's check anyway */
1570 if (ai->ai_grantor != ACL_ID_PUBLIC)
1571 list[j++] = ai->ai_grantor;
1572 }
1573
1574 /* Sort the array */
1575 qsort(list, j, sizeof(Oid), oid_cmp);
1576
1577 /*
1578 * We could repalloc the array down to minimum size, but it's hardly worth
1579 * it since it's only transient memory.
1580 */
1581 *roleids = list;
1582
1583 /* Remove duplicates from the array */
1584 return qunique(list, j, sizeof(Oid), oid_cmp);
1585}
int j
Definition: isn.c:78
void * palloc(Size size)
Definition: mcxt.c:1365
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:258
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21

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

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), recordDependencyOnNewAcl(), recordExtensionInitPrivWorker(), RemoveRoleFromInitPriv(), ReplaceRoleInInitPriv(), and SetDefaultACL().

◆ aclmerge()

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

Definition at line 501 of file acl.c.

502{
503 Acl *result_acl;
504 AclItem *aip;
505 int i,
506 num;
507
508 /* Check for cases where one or both are empty/null */
509 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
510 {
511 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
512 return NULL;
513 else
514 return aclcopy(right_acl);
515 }
516 else
517 {
518 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
519 return aclcopy(left_acl);
520 }
521
522 /* Merge them the hard way, one item at a time */
523 result_acl = aclcopy(left_acl);
524
525 aip = ACL_DAT(right_acl);
526 num = ACL_NUM(right_acl);
527
528 for (i = 0; i < num; i++, aip++)
529 {
530 Acl *tmp_acl;
531
532 tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
533 ownerId, DROP_RESTRICT);
534 pfree(result_acl);
535 result_acl = tmp_acl;
536 }
537
538 return result_acl;
539}
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:992
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:457
#define ACL_MODECHG_ADD
Definition: acl.h:129
void pfree(void *pointer)
Definition: mcxt.c:1594
@ DROP_RESTRICT
Definition: parsenodes.h:2398

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

Referenced by get_user_default_acl().

◆ aclnewowner()

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

Definition at line 1119 of file acl.c.

1120{
1121 Acl *new_acl;
1122 AclItem *new_aip;
1123 AclItem *old_aip;
1124 AclItem *dst_aip;
1125 AclItem *src_aip;
1126 AclItem *targ_aip;
1127 bool newpresent = false;
1128 int dst,
1129 src,
1130 targ,
1131 num;
1132
1133 check_acl(old_acl);
1134
1135 /*
1136 * Make a copy of the given ACL, substituting new owner ID for old
1137 * wherever it appears as either grantor or grantee. Also note if the new
1138 * owner ID is already present.
1139 */
1140 num = ACL_NUM(old_acl);
1141 old_aip = ACL_DAT(old_acl);
1142 new_acl = allocacl(num);
1143 new_aip = ACL_DAT(new_acl);
1144 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1145 for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1146 {
1147 if (dst_aip->ai_grantor == oldOwnerId)
1148 dst_aip->ai_grantor = newOwnerId;
1149 else if (dst_aip->ai_grantor == newOwnerId)
1150 newpresent = true;
1151 if (dst_aip->ai_grantee == oldOwnerId)
1152 dst_aip->ai_grantee = newOwnerId;
1153 else if (dst_aip->ai_grantee == newOwnerId)
1154 newpresent = true;
1155 }
1156
1157 /*
1158 * If the old ACL contained any references to the new owner, then we may
1159 * now have generated an ACL containing duplicate entries. Find them and
1160 * merge them so that there are not duplicates. (This is relatively
1161 * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1162 * be the normal case.)
1163 *
1164 * To simplify deletion of duplicate entries, we temporarily leave them in
1165 * the array but set their privilege masks to zero; when we reach such an
1166 * entry it's just skipped. (Thus, a side effect of this code will be to
1167 * remove privilege-free entries, should there be any in the input.) dst
1168 * is the next output slot, targ is the currently considered input slot
1169 * (always >= dst), and src scans entries to the right of targ looking for
1170 * duplicates. Once an entry has been emitted to dst it is known
1171 * duplicate-free and need not be considered anymore.
1172 */
1173 if (newpresent)
1174 {
1175 dst = 0;
1176 for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1177 {
1178 /* ignore if deleted in an earlier pass */
1179 if (ACLITEM_GET_RIGHTS(*targ_aip) == ACL_NO_RIGHTS)
1180 continue;
1181 /* find and merge any duplicates */
1182 for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1183 src++, src_aip++)
1184 {
1185 if (ACLITEM_GET_RIGHTS(*src_aip) == ACL_NO_RIGHTS)
1186 continue;
1187 if (aclitem_match(targ_aip, src_aip))
1188 {
1189 ACLITEM_SET_RIGHTS(*targ_aip,
1190 ACLITEM_GET_RIGHTS(*targ_aip) |
1191 ACLITEM_GET_RIGHTS(*src_aip));
1192 /* mark the duplicate deleted */
1194 }
1195 }
1196 /* and emit to output */
1197 new_aip[dst] = *targ_aip;
1198 dst++;
1199 }
1200 /* Adjust array size to be 'dst' items */
1201 ARR_DIMS(new_acl)[0] = dst;
1202 SET_VARSIZE(new_acl, ACL_N_SIZE(dst));
1203 }
1204
1205 return new_acl;
1206}
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition: acl.c:713
#define ACL_N_SIZE(N)
Definition: acl.h:110
#define ACLITEM_GET_RIGHTS(item)
Definition: acl.h:68
#define ACLITEM_SET_RIGHTS(item, rights)
Definition: acl.h:79
#define ARR_DIMS(a)
Definition: array.h:294
static void SET_VARSIZE(void *PTR, Size len)
Definition: varatt.h:432

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(), change_owner_fix_column_acls(), and ReplaceRoleInInitPriv().

◆ aclupdate()

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

Definition at line 992 of file acl.c.

994{
995 Acl *new_acl = NULL;
996 AclItem *old_aip,
997 *new_aip = NULL;
998 AclMode old_rights,
999 old_goptions,
1000 new_rights,
1001 new_goptions;
1002 int dst,
1003 num;
1004
1005 /* Caller probably already checked old_acl, but be safe */
1006 check_acl(old_acl);
1007
1008 /* If granting grant options, check for circularity */
1009 if (modechg != ACL_MODECHG_DEL &&
1011 check_circularity(old_acl, mod_aip, ownerId);
1012
1013 num = ACL_NUM(old_acl);
1014 old_aip = ACL_DAT(old_acl);
1015
1016 /*
1017 * Search the ACL for an existing entry for this grantee and grantor. If
1018 * one exists, just modify the entry in-place (well, in the same position,
1019 * since we actually return a copy); otherwise, insert the new entry at
1020 * the end.
1021 */
1022
1023 for (dst = 0; dst < num; ++dst)
1024 {
1025 if (aclitem_match(mod_aip, old_aip + dst))
1026 {
1027 /* found a match, so modify existing item */
1028 new_acl = allocacl(num);
1029 new_aip = ACL_DAT(new_acl);
1030 memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
1031 break;
1032 }
1033 }
1034
1035 if (dst == num)
1036 {
1037 /* need to append a new item */
1038 new_acl = allocacl(num + 1);
1039 new_aip = ACL_DAT(new_acl);
1040 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1041
1042 /* initialize the new entry with no permissions */
1043 new_aip[dst].ai_grantee = mod_aip->ai_grantee;
1044 new_aip[dst].ai_grantor = mod_aip->ai_grantor;
1045 ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
1047 num++; /* set num to the size of new_acl */
1048 }
1049
1050 old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1051 old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1052
1053 /* apply the specified permissions change */
1054 switch (modechg)
1055 {
1056 case ACL_MODECHG_ADD:
1057 ACLITEM_SET_RIGHTS(new_aip[dst],
1058 old_rights | ACLITEM_GET_RIGHTS(*mod_aip));
1059 break;
1060 case ACL_MODECHG_DEL:
1061 ACLITEM_SET_RIGHTS(new_aip[dst],
1062 old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
1063 break;
1064 case ACL_MODECHG_EQL:
1065 ACLITEM_SET_RIGHTS(new_aip[dst],
1066 ACLITEM_GET_RIGHTS(*mod_aip));
1067 break;
1068 }
1069
1070 new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1071 new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1072
1073 /*
1074 * If the adjusted entry has no permissions, delete it from the list.
1075 */
1076 if (new_rights == ACL_NO_RIGHTS)
1077 {
1078 memmove(new_aip + dst,
1079 new_aip + dst + 1,
1080 (num - dst - 1) * sizeof(AclItem));
1081 /* Adjust array size to be 'num - 1' items */
1082 ARR_DIMS(new_acl)[0] = num - 1;
1083 SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1084 }
1085
1086 /*
1087 * Remove abandoned privileges (cascading revoke). Currently we can only
1088 * handle this when the grantee is not PUBLIC.
1089 */
1090 if ((old_goptions & ~new_goptions) != 0)
1091 {
1092 Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1093 new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1094 (old_goptions & ~new_goptions),
1095 ownerId, behavior);
1096 }
1097
1098 return new_acl;
1099}
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition: acl.c:1302
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1222
#define ACL_SIZE(ACL)
Definition: acl.h:111
#define ACL_MODECHG_DEL
Definition: acl.h:130
#define ACLITEM_GET_GOPTIONS(item)
Definition: acl.h:67
#define ACL_MODECHG_EQL
Definition: acl.h:131
Assert(PointerIsAligned(start, uint64))

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

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

◆ check_can_set_role()

void check_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5341 of file acl.c.

5342{
5343 if (!member_can_set_role(member, role))
5344 ereport(ERROR,
5345 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5346 errmsg("must be able to SET ROLE \"%s\"",
5347 GetUserNameFromId(role, false))));
5348}
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5318
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:988

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

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

◆ check_rolespec_name()

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

Definition at line 5693 of file acl.c.

5694{
5695 if (!role)
5696 return;
5697
5698 if (role->roletype != ROLESPEC_CSTRING)
5699 return;
5700
5701 if (IsReservedName(role->rolename))
5702 {
5703 if (detail_msg)
5704 ereport(ERROR,
5705 (errcode(ERRCODE_RESERVED_NAME),
5706 errmsg("role name \"%s\" is reserved",
5707 role->rolename),
5708 errdetail_internal("%s", detail_msg)));
5709 else
5710 ereport(ERROR,
5711 (errcode(ERRCODE_RESERVED_NAME),
5712 errmsg("role name \"%s\" is reserved",
5713 role->rolename)));
5714 }
5715}
bool IsReservedName(const char *name)
Definition: catalog.c:278
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1243
@ ROLESPEC_CSTRING
Definition: parsenodes.h:419
RoleSpecType roletype
Definition: parsenodes.h:429
char * rolename
Definition: parsenodes.h:430

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

Referenced by AlterRole(), and AlterRoleSet().

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

Definition at line 916 of file aclchk.c.

917{
918 GrantStmt *action = stmt->action;
919 InternalDefaultACL iacls;
920 ListCell *cell;
921 List *rolespecs = NIL;
922 List *nspnames = NIL;
923 DefElem *drolespecs = NULL;
924 DefElem *dnspnames = NULL;
925 AclMode all_privileges;
926 const char *errormsg;
927
928 /* Deconstruct the "options" part of the statement */
929 foreach(cell, stmt->options)
930 {
931 DefElem *defel = (DefElem *) lfirst(cell);
932
933 if (strcmp(defel->defname, "schemas") == 0)
934 {
935 if (dnspnames)
936 errorConflictingDefElem(defel, pstate);
937 dnspnames = defel;
938 }
939 else if (strcmp(defel->defname, "roles") == 0)
940 {
941 if (drolespecs)
942 errorConflictingDefElem(defel, pstate);
943 drolespecs = defel;
944 }
945 else
946 elog(ERROR, "option \"%s\" not recognized", defel->defname);
947 }
948
949 if (dnspnames)
950 nspnames = (List *) dnspnames->arg;
951 if (drolespecs)
952 rolespecs = (List *) drolespecs->arg;
953
954 /* Prepare the InternalDefaultACL representation of the statement */
955 /* roleid to be filled below */
956 /* nspid to be filled in SetDefaultACLsInSchemas */
957 iacls.is_grant = action->is_grant;
958 iacls.objtype = action->objtype;
959 /* all_privs to be filled below */
960 /* privileges to be filled below */
961 iacls.grantees = NIL; /* filled below */
962 iacls.grant_option = action->grant_option;
963 iacls.behavior = action->behavior;
964
965 /*
966 * Convert the RoleSpec list into an Oid list. Note that at this point we
967 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
968 * there shouldn't be any additional work needed to support this case.
969 */
970 foreach(cell, action->grantees)
971 {
972 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
973 Oid grantee_uid;
974
975 switch (grantee->roletype)
976 {
977 case ROLESPEC_PUBLIC:
978 grantee_uid = ACL_ID_PUBLIC;
979 break;
980 default:
981 grantee_uid = get_rolespec_oid(grantee, false);
982 break;
983 }
984 iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
985 }
986
987 /*
988 * Convert action->privileges, a list of privilege strings, into an
989 * AclMode bitmask.
990 */
991 switch (action->objtype)
992 {
993 case OBJECT_TABLE:
994 all_privileges = ACL_ALL_RIGHTS_RELATION;
995 errormsg = gettext_noop("invalid privilege type %s for relation");
996 break;
997 case OBJECT_SEQUENCE:
998 all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
999 errormsg = gettext_noop("invalid privilege type %s for sequence");
1000 break;
1001 case OBJECT_FUNCTION:
1002 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1003 errormsg = gettext_noop("invalid privilege type %s for function");
1004 break;
1005 case OBJECT_PROCEDURE:
1006 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1007 errormsg = gettext_noop("invalid privilege type %s for procedure");
1008 break;
1009 case OBJECT_ROUTINE:
1010 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1011 errormsg = gettext_noop("invalid privilege type %s for routine");
1012 break;
1013 case OBJECT_TYPE:
1014 all_privileges = ACL_ALL_RIGHTS_TYPE;
1015 errormsg = gettext_noop("invalid privilege type %s for type");
1016 break;
1017 case OBJECT_SCHEMA:
1018 all_privileges = ACL_ALL_RIGHTS_SCHEMA;
1019 errormsg = gettext_noop("invalid privilege type %s for schema");
1020 break;
1021 case OBJECT_LARGEOBJECT:
1022 all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
1023 errormsg = gettext_noop("invalid privilege type %s for large object");
1024 break;
1025 default:
1026 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1027 (int) action->objtype);
1028 /* keep compiler quiet */
1029 all_privileges = ACL_NO_RIGHTS;
1030 errormsg = NULL;
1031 }
1032
1033 if (action->privileges == NIL)
1034 {
1035 iacls.all_privs = true;
1036
1037 /*
1038 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1039 * depending on the object type
1040 */
1041 iacls.privileges = ACL_NO_RIGHTS;
1042 }
1043 else
1044 {
1045 iacls.all_privs = false;
1046 iacls.privileges = ACL_NO_RIGHTS;
1047
1048 foreach(cell, action->privileges)
1049 {
1050 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1051 AclMode priv;
1052
1053 if (privnode->cols)
1054 ereport(ERROR,
1055 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1056 errmsg("default privileges cannot be set for columns")));
1057
1058 if (privnode->priv_name == NULL) /* parser mistake? */
1059 elog(ERROR, "AccessPriv node must specify privilege");
1060 priv = string_to_privilege(privnode->priv_name);
1061
1062 if (priv & ~all_privileges)
1063 ereport(ERROR,
1064 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1065 errmsg(errormsg, privilege_to_string(priv))));
1066
1067 iacls.privileges |= priv;
1068 }
1069 }
1070
1071 if (rolespecs == NIL)
1072 {
1073 /* Set permissions for myself */
1074 iacls.roleid = GetUserId();
1075
1076 SetDefaultACLsInSchemas(&iacls, nspnames);
1077 }
1078 else
1079 {
1080 /* Look up the role OIDs and do permissions checks */
1081 ListCell *rolecell;
1082
1083 foreach(rolecell, rolespecs)
1084 {
1085 RoleSpec *rolespec = lfirst(rolecell);
1086
1087 iacls.roleid = get_rolespec_oid(rolespec, false);
1088
1089 if (!has_privs_of_role(GetUserId(), iacls.roleid))
1090 ereport(ERROR,
1091 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1092 errmsg("permission denied to change default privileges")));
1093
1094 SetDefaultACLsInSchemas(&iacls, nspnames);
1095 }
1096 }
1097}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5586
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:2566
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1105
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2607
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:371
#define stmt
Definition: indent_codes.h:59
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
Oid GetUserId(void)
Definition: miscinit.c:469
@ ROLESPEC_PUBLIC
Definition: parsenodes.h:423
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
char * priv_name
Definition: parsenodes.h:2627
List * cols
Definition: parsenodes.h:2628
char * defname
Definition: parsenodes.h:843
Node * arg
Definition: parsenodes.h:844
AclMode privileges
Definition: aclchk.c:98
List * grantees
Definition: aclchk.c:99
DropBehavior behavior
Definition: aclchk.c:101
ObjectType objtype
Definition: aclchk.c:96
Definition: pg_list.h:54

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, generate_unaccent_rules::action, InternalDefaultACL::all_privs, DefElem::arg, InternalDefaultACL::behavior, AccessPriv::cols, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, errorConflictingDefElem(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalDefaultACL::grant_option, InternalDefaultACL::grantees, has_privs_of_role(), if(), InternalDefaultACL::is_grant, lappend_oid(), lfirst, NIL, OBJECT_FUNCTION, OBJECT_LARGEOBJECT, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, InternalDefaultACL::objtype, AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, InternalDefaultACL::roleid, ROLESPEC_PUBLIC, RoleSpec::roletype, SetDefaultACLsInSchemas(), stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 391 of file aclchk.c.

392{
393 InternalGrant istmt;
394 ListCell *cell;
395 const char *errormsg;
396 AclMode all_privileges;
397
398 if (stmt->grantor)
399 {
400 Oid grantor;
401
402 grantor = get_rolespec_oid(stmt->grantor, false);
403
404 /*
405 * Currently, this clause is only for SQL compatibility, not very
406 * interesting otherwise.
407 */
408 if (grantor != GetUserId())
410 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
411 errmsg("grantor must be current user")));
412 }
413
414 /*
415 * Turn the regular GrantStmt into the InternalGrant form.
416 */
417 istmt.is_grant = stmt->is_grant;
418 istmt.objtype = stmt->objtype;
419
420 /* Collect the OIDs of the target objects */
421 switch (stmt->targtype)
422 {
424 istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects,
425 stmt->is_grant);
426 break;
428 istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
429 break;
430 /* ACL_TARGET_DEFAULTS should not be seen here */
431 default:
432 elog(ERROR, "unrecognized GrantStmt.targtype: %d",
433 (int) stmt->targtype);
434 }
435
436 /* all_privs to be filled below */
437 /* privileges to be filled below */
438 istmt.col_privs = NIL; /* may get filled below */
439 istmt.grantees = NIL; /* filled below */
440 istmt.grant_option = stmt->grant_option;
441 istmt.behavior = stmt->behavior;
442
443 /*
444 * Convert the RoleSpec list into an Oid list. Note that at this point we
445 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
446 * there shouldn't be any additional work needed to support this case.
447 */
448 foreach(cell, stmt->grantees)
449 {
450 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
451 Oid grantee_uid;
452
453 switch (grantee->roletype)
454 {
455 case ROLESPEC_PUBLIC:
456 grantee_uid = ACL_ID_PUBLIC;
457 break;
458 default:
459 grantee_uid = get_rolespec_oid(grantee, false);
460 break;
461 }
462 istmt.grantees = lappend_oid(istmt.grantees, grantee_uid);
463 }
464
465 /*
466 * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
467 * bitmask. Note: objtype can't be OBJECT_COLUMN.
468 */
469 switch (stmt->objtype)
470 {
471 case OBJECT_TABLE:
472
473 /*
474 * Because this might be a sequence, we test both relation and
475 * sequence bits, and later do a more limited test when we know
476 * the object type.
477 */
479 errormsg = gettext_noop("invalid privilege type %s for relation");
480 break;
481 case OBJECT_SEQUENCE:
482 all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
483 errormsg = gettext_noop("invalid privilege type %s for sequence");
484 break;
485 case OBJECT_DATABASE:
486 all_privileges = ACL_ALL_RIGHTS_DATABASE;
487 errormsg = gettext_noop("invalid privilege type %s for database");
488 break;
489 case OBJECT_DOMAIN:
490 all_privileges = ACL_ALL_RIGHTS_TYPE;
491 errormsg = gettext_noop("invalid privilege type %s for domain");
492 break;
493 case OBJECT_FUNCTION:
494 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
495 errormsg = gettext_noop("invalid privilege type %s for function");
496 break;
497 case OBJECT_LANGUAGE:
498 all_privileges = ACL_ALL_RIGHTS_LANGUAGE;
499 errormsg = gettext_noop("invalid privilege type %s for language");
500 break;
502 all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT;
503 errormsg = gettext_noop("invalid privilege type %s for large object");
504 break;
505 case OBJECT_SCHEMA:
506 all_privileges = ACL_ALL_RIGHTS_SCHEMA;
507 errormsg = gettext_noop("invalid privilege type %s for schema");
508 break;
509 case OBJECT_PROCEDURE:
510 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
511 errormsg = gettext_noop("invalid privilege type %s for procedure");
512 break;
513 case OBJECT_ROUTINE:
514 all_privileges = ACL_ALL_RIGHTS_FUNCTION;
515 errormsg = gettext_noop("invalid privilege type %s for routine");
516 break;
518 all_privileges = ACL_ALL_RIGHTS_TABLESPACE;
519 errormsg = gettext_noop("invalid privilege type %s for tablespace");
520 break;
521 case OBJECT_TYPE:
522 all_privileges = ACL_ALL_RIGHTS_TYPE;
523 errormsg = gettext_noop("invalid privilege type %s for type");
524 break;
525 case OBJECT_FDW:
526 all_privileges = ACL_ALL_RIGHTS_FDW;
527 errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
528 break;
530 all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER;
531 errormsg = gettext_noop("invalid privilege type %s for foreign server");
532 break;
534 all_privileges = ACL_ALL_RIGHTS_PARAMETER_ACL;
535 errormsg = gettext_noop("invalid privilege type %s for parameter");
536 break;
537 default:
538 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
539 (int) stmt->objtype);
540 /* keep compiler quiet */
541 all_privileges = ACL_NO_RIGHTS;
542 errormsg = NULL;
543 }
544
545 if (stmt->privileges == NIL)
546 {
547 istmt.all_privs = true;
548
549 /*
550 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
551 * depending on the object type
552 */
554 }
555 else
556 {
557 istmt.all_privs = false;
559
560 foreach(cell, stmt->privileges)
561 {
562 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
563 AclMode priv;
564
565 /*
566 * If it's a column-level specification, we just set it aside in
567 * col_privs for the moment; but insist it's for a relation.
568 */
569 if (privnode->cols)
570 {
571 if (stmt->objtype != OBJECT_TABLE)
573 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
574 errmsg("column privileges are only valid for relations")));
575 istmt.col_privs = lappend(istmt.col_privs, privnode);
576 continue;
577 }
578
579 if (privnode->priv_name == NULL) /* parser mistake? */
580 elog(ERROR, "AccessPriv node must specify privilege or columns");
581 priv = string_to_privilege(privnode->priv_name);
582
583 if (priv & ~all_privileges)
585 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
586 errmsg(errormsg, privilege_to_string(priv))));
587
588 istmt.privileges |= priv;
589 }
590 }
591
592 ExecGrantStmt_oids(&istmt);
593}
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition: aclchk.c:601
static List * objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
Definition: aclchk.c:677
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition: aclchk.c:789
List * lappend(List *list, void *datum)
Definition: list.c:339
@ ACL_TARGET_OBJECT
Definition: parsenodes.h:2570
@ ACL_TARGET_ALL_IN_SCHEMA
Definition: parsenodes.h:2571
DropBehavior behavior
AclMode privileges
ObjectType objtype

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, AccessPriv::cols, elog, ereport, errcode(), errmsg(), ERROR, ExecGrantStmt_oids(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, AccessPriv::priv_name, privilege_to_string(), InternalGrant::privileges, ROLESPEC_PUBLIC, RoleSpec::roletype, stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char *  rolname,
bool  missing_ok 
)

Definition at line 5552 of file acl.c.

5553{
5554 Oid oid;
5555
5556 oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5558 if (!OidIsValid(oid) && !missing_ok)
5559 ereport(ERROR,
5560 (errcode(ERRCODE_UNDEFINED_OBJECT),
5561 errmsg("role \"%s\" does not exist", rolname)));
5562 return oid;
5563}
#define OidIsValid(objectId)
Definition: c.h:788
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:109

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

Referenced by aclparse(), check_hba(), check_ident_usermap(), 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(), shell_check_detail(), and worker_spi_launch().

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char * get_rolespec_name ( const RoleSpec role)

Definition at line 5671 of file acl.c.

5672{
5673 HeapTuple tp;
5674 Form_pg_authid authForm;
5675 char *rolename;
5676
5677 tp = get_rolespec_tuple(role);
5678 authForm = (Form_pg_authid) GETSTRUCT(tp);
5679 rolename = pstrdup(NameStr(authForm->rolname));
5680 ReleaseSysCache(tp);
5681
5682 return rolename;
5683}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5625
#define NameStr(name)
Definition: c.h:765
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
char * pstrdup(const char *in)
Definition: mcxt.c:1759
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:264

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

Referenced by AddRoleMems(), and DelRoleMems().

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)

Definition at line 5586 of file acl.c.

5587{
5588 Oid oid;
5589
5590 switch (role->roletype)
5591 {
5592 case ROLESPEC_CSTRING:
5593 Assert(role->rolename);
5594 oid = get_role_oid(role->rolename, missing_ok);
5595 break;
5596
5599 oid = GetUserId();
5600 break;
5601
5603 oid = GetSessionUserId();
5604 break;
5605
5606 case ROLESPEC_PUBLIC:
5607 ereport(ERROR,
5608 (errcode(ERRCODE_UNDEFINED_OBJECT),
5609 errmsg("role \"%s\" does not exist", "public")));
5610 oid = InvalidOid; /* make compiler happy */
5611 break;
5612
5613 default:
5614 elog(ERROR, "unexpected role type %d", role->roletype);
5615 }
5616
5617 return oid;
5618}
Oid GetSessionUserId(void)
Definition: miscinit.c:508
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:421
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:422
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:420
#define InvalidOid
Definition: postgres_ext.h:37

References Assert(), elog, ereport, errcode(), errmsg(), ERROR, get_role_oid(), GetSessionUserId(), GetUserId(), InvalidOid, RoleSpec::rolename, ROLESPEC_CSTRING, ROLESPEC_CURRENT_ROLE, ROLESPEC_CURRENT_USER, ROLESPEC_PUBLIC, ROLESPEC_SESSION_USER, and RoleSpec::roletype.

Referenced by AlterUserMapping(), ATExecCmd(), CreateSchemaCommand(), CreateTableSpace(), CreateUserMapping(), ExecAlterDefaultPrivilegesStmt(), ExecAlterOwnerStmt(), ExecuteGrantStmt(), GrantRole(), policy_role_list_to_array(), ReassignOwnedObjects(), RemoveUserMapping(), and roleSpecsToIds().

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

Definition at line 5625 of file acl.c.

5626{
5627 HeapTuple tuple;
5628
5629 switch (role->roletype)
5630 {
5631 case ROLESPEC_CSTRING:
5632 Assert(role->rolename);
5633 tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5634 if (!HeapTupleIsValid(tuple))
5635 ereport(ERROR,
5636 (errcode(ERRCODE_UNDEFINED_OBJECT),
5637 errmsg("role \"%s\" does not exist", role->rolename)));
5638 break;
5639
5642 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5643 if (!HeapTupleIsValid(tuple))
5644 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5645 break;
5646
5649 if (!HeapTupleIsValid(tuple))
5650 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5651 break;
5652
5653 case ROLESPEC_PUBLIC:
5654 ereport(ERROR,
5655 (errcode(ERRCODE_UNDEFINED_OBJECT),
5656 errmsg("role \"%s\" does not exist", "public")));
5657 tuple = NULL; /* make compiler happy */
5658 break;
5659
5660 default:
5661 elog(ERROR, "unexpected role type %d", role->roletype);
5662 }
5663
5664 return tuple;
5665}
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:220

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

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

◆ get_user_default_acl()

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

Definition at line 4247 of file aclchk.c.

4248{
4249 Acl *result;
4250 Acl *glob_acl;
4251 Acl *schema_acl;
4252 Acl *def_acl;
4253 char defaclobjtype;
4254
4255 /*
4256 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4257 * yet.
4258 */
4260 return NULL;
4261
4262 /* Check if object type is supported in pg_default_acl */
4263 switch (objtype)
4264 {
4265 case OBJECT_TABLE:
4266 defaclobjtype = DEFACLOBJ_RELATION;
4267 break;
4268
4269 case OBJECT_SEQUENCE:
4270 defaclobjtype = DEFACLOBJ_SEQUENCE;
4271 break;
4272
4273 case OBJECT_FUNCTION:
4274 defaclobjtype = DEFACLOBJ_FUNCTION;
4275 break;
4276
4277 case OBJECT_TYPE:
4278 defaclobjtype = DEFACLOBJ_TYPE;
4279 break;
4280
4281 case OBJECT_SCHEMA:
4282 defaclobjtype = DEFACLOBJ_NAMESPACE;
4283 break;
4284
4285 case OBJECT_LARGEOBJECT:
4286 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4287 break;
4288
4289 default:
4290 return NULL;
4291 }
4292
4293 /* Look up the relevant pg_default_acl entries */
4294 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4295 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4296
4297 /* Quick out if neither entry exists */
4298 if (glob_acl == NULL && schema_acl == NULL)
4299 return NULL;
4300
4301 /* We need to know the hard-wired default value, too */
4302 def_acl = acldefault(objtype, ownerId);
4303
4304 /* If there's no global entry, substitute the hard-wired default */
4305 if (glob_acl == NULL)
4306 glob_acl = def_acl;
4307
4308 /* Merge in any per-schema privileges */
4309 result = aclmerge(glob_acl, schema_acl, ownerId);
4310
4311 /*
4312 * For efficiency, we want to return NULL if the result equals default.
4313 * This requires sorting both arrays to get an accurate comparison.
4314 */
4315 aclitemsort(result);
4316 aclitemsort(def_acl);
4317 if (aclequal(result, def_acl))
4318 result = NULL;
4319
4320 return result;
4321}
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:501
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:803
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:559
void aclitemsort(Acl *acl)
Definition: acl.c:545
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4212
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:477

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 4188 of file aclchk.c.

4189{
4190 bool result = false;
4191 HeapTuple utup;
4192
4193 /* Superusers bypass all permission checking. */
4194 if (superuser_arg(roleid))
4195 return true;
4196
4197 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4198 if (HeapTupleIsValid(utup))
4199 {
4200 result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4201 ReleaseSysCache(utup);
4202 }
4203 return result;
4204}
bool rolbypassrls
Definition: pg_authid.h:41
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

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

Referenced by AlterRole(), check_enable_rls(), CreateRole(), and RI_Initial_Check().

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4169 of file aclchk.c.

4170{
4171 bool result = false;
4172 HeapTuple utup;
4173
4174 /* Superusers bypass all permission checking. */
4175 if (superuser_arg(roleid))
4176 return true;
4177
4178 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4179 if (HeapTupleIsValid(utup))
4180 {
4181 result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4182 ReleaseSysCache(utup);
4183 }
4184 return result;
4185}
bool rolcreaterole
Definition: pg_authid.h:37

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

Referenced by check_object_ownership(), CreateRole(), and have_createrole_privilege().

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 5284 of file acl.c.

5285{
5286 /* Fast path for simple case */
5287 if (member == role)
5288 return true;
5289
5290 /* Superusers have every privilege, so are part of every role */
5291 if (superuser_arg(member))
5292 return true;
5293
5294 /*
5295 * Find all the roles that member has the privileges of, including
5296 * multi-level recursion, then see if target role is any one of them.
5297 */
5299 InvalidOid, NULL),
5300 role);
5301}
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:5152
@ ROLERECURSE_PRIVS
Definition: acl.c:77
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:722

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

Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), bbsink_server_new(), calculate_database_size(), calculate_tablespace_size(), check_role_for_policy(), check_role_grantor(), ConfigOptionIsVisible(), convert_and_check_filename(), CreateSubscription(), DoCopy(), DropOwnedObjects(), ExecAlterDefaultPrivilegesStmt(), ExecCheckpoint(), file_fdw_validator(), GetConfigOptionValues(), InitPostgres(), object_ownercheck(), pg_class_aclmask_ext(), pg_namespace_aclmask_ext(), pg_role_aclcheck(), pg_signal_backend(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), ReassignOwnedObjects(), ReindexMultipleTables(), shell_check_detail(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 5040 of file acl.c.

5041{
5043 {
5045 GetSysCacheHashValue1(DATABASEOID,
5047
5048 /*
5049 * In normal mode, set a callback on any syscache invalidation of rows
5050 * of pg_auth_members (for roles_is_member_of()) pg_database (for
5051 * roles_is_member_of())
5052 */
5053 CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
5055 (Datum) 0);
5058 (Datum) 0);
5061 (Datum) 0);
5062 }
5063}
static uint32 cached_db_hash
Definition: acl.c:82
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:5070
Oid MyDatabaseId
Definition: globals.c:94
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1812
uint64_t Datum
Definition: postgres.h:70
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:118

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)

Definition at line 5414 of file acl.c.

5415{
5416 Oid admin_role;
5417
5418 if (superuser_arg(member))
5419 return true;
5420
5421 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5422 if (member == role)
5423 return false;
5424
5425 (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5426 return OidIsValid(admin_role);
5427}
@ ROLERECURSE_MEMBERS
Definition: acl.c:76

References OidIsValid, ROLERECURSE_MEMBERS, roles_is_member_of(), and superuser_arg().

Referenced by AlterRole(), AlterRoleSet(), check_object_ownership(), check_role_membership_authorization(), DropRole(), pg_role_aclcheck(), and RenameRole().

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 5364 of file acl.c.

5365{
5366 /* Fast path for simple case */
5367 if (member == role)
5368 return true;
5369
5370 /* Superusers have every privilege, so are part of every role */
5371 if (superuser_arg(member))
5372 return true;
5373
5374 /*
5375 * Find all the roles that member is a member of, including multi-level
5376 * recursion, then see if target role is any one of them.
5377 */
5379 InvalidOid, NULL),
5380 role);
5381}

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

Referenced by pg_role_aclcheck().

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)

Definition at line 5392 of file acl.c.

5393{
5394 /* Fast path for simple case */
5395 if (member == role)
5396 return true;
5397
5398 /*
5399 * Find all the roles that member is a member of, including multi-level
5400 * recursion, then see if target role is any one of them.
5401 */
5403 InvalidOid, NULL),
5404 role);
5405}

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

Referenced by AddRoleMems(), and is_member().

◆ make_empty_acl()

Acl * make_empty_acl ( void  )

Definition at line 448 of file acl.c.

449{
450 return allocacl(0);
451}

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5318 of file acl.c.

5319{
5320 /* Fast path for simple case */
5321 if (member == role)
5322 return true;
5323
5324 /* Superusers have every privilege, so can always SET ROLE */
5325 if (superuser_arg(member))
5326 return true;
5327
5328 /*
5329 * Find all the roles that member can access via SET ROLE, including
5330 * multi-level recursion, then see if target role is any one of them.
5331 */
5333 InvalidOid, NULL),
5334 role);
5335}
@ ROLERECURSE_SETROLE
Definition: acl.c:78

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

Referenced by check_can_set_role(), check_role(), pg_role_aclcheck(), and SwitchToUntrustedUser().

◆ object_aclcheck()

AclResult object_aclcheck ( Oid  classid,
Oid  objectid,
Oid  roleid,
AclMode  mode 
)

Definition at line 3836 of file aclchk.c.

3837{
3838 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3839}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3846
static PgChecksumMode mode
Definition: pg_checksums.c:56

References mode, and object_aclcheck_ext().

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterForeignServerOwner_internal(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepAlterColumnType(), ATPrepSetTableSpace(), BuildDescForRelation(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_temp_tablespaces(), CheckFunctionValidatorAccess(), CheckMyDatabase(), compute_return_type(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), extension_is_trusted(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), HandleFunctionRequest(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_name(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_name(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_name(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_name(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_name(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_name(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), InitTempTableNamespace(), inline_function(), inline_function_in_from(), interpret_function_parameter_list(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), movedb(), PrepareTempTablespaces(), preprocessNamespacePath(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), RenameSchema(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_aclcheck_ext()

◆ object_ownercheck()

bool object_ownercheck ( Oid  classid,
Oid  objectid,
Oid  roleid 
)

Definition at line 4090 of file aclchk.c.

4091{
4092 int cacheid;
4093 Oid ownerId;
4094
4095 /* Superusers bypass all permission checking. */
4096 if (superuser_arg(roleid))
4097 return true;
4098
4099 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4100 if (classid == LargeObjectRelationId)
4101 classid = LargeObjectMetadataRelationId;
4102
4103 cacheid = get_object_catcache_oid(classid);
4104 if (cacheid != -1)
4105 {
4106 /* we can get the object's tuple from the syscache */
4107 HeapTuple tuple;
4108
4109 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4110 if (!HeapTupleIsValid(tuple))
4111 elog(ERROR, "cache lookup failed for %s %u",
4112 get_object_class_descr(classid), objectid);
4113
4114 ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4115 tuple,
4116 get_object_attnum_owner(classid)));
4117 ReleaseSysCache(tuple);
4118 }
4119 else
4120 {
4121 /* for catalogs without an appropriate syscache */
4122 Relation rel;
4123 ScanKeyData entry[1];
4124 SysScanDesc scan;
4125 HeapTuple tuple;
4126 bool isnull;
4127
4128 rel = table_open(classid, AccessShareLock);
4129
4130 ScanKeyInit(&entry[0],
4131 get_object_attnum_oid(classid),
4132 BTEqualStrategyNumber, F_OIDEQ,
4133 ObjectIdGetDatum(objectid));
4134
4135 scan = systable_beginscan(rel,
4136 get_object_oid_index(classid), true,
4137 NULL, 1, entry);
4138
4139 tuple = systable_getnext(scan);
4140 if (!HeapTupleIsValid(tuple))
4141 elog(ERROR, "could not find tuple for %s %u",
4142 get_object_class_descr(classid), objectid);
4143
4144 ownerId = DatumGetObjectId(heap_getattr(tuple,
4145 get_object_attnum_owner(classid),
4146 RelationGetDescr(rel),
4147 &isnull));
4148 Assert(!isnull);
4149
4150 systable_endscan(scan);
4152 }
4153
4154 return has_privs_of_role(roleid, ownerId);
4155}
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:388
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:904
#define AccessShareLock
Definition: lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
const char * get_object_class_descr(Oid class_id)
int get_object_catcache_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:252
#define RelationGetDescr(relation)
Definition: rel.h:541
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:625
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, Assert(), BTEqualStrategyNumber, DatumGetObjectId(), elog, ERROR, get_object_attnum_oid(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), get_object_oid_index(), has_privs_of_role(), heap_getattr(), HeapTupleIsValid, ObjectIdGetDatum(), RelationGetDescr, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), superuser_arg(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterType(), AlterTypeNamespace_oid(), AlterTypeOwner(), ATExecChangeOwner(), ATSimplePermissions(), be_lo_unlink(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), CreateCast(), createdb(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), DefineOpClass(), DefineQueryRewrite(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecuteTruncateGuts(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), movedb(), OperatorCreate(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackForStats(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), user_mapping_ddl_aclcheck(), vacuum_is_permitted_for_relation(), and ValidateOperatorReference().

◆ pg_attribute_aclcheck()

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

Definition at line 3868 of file aclchk.c.

3870{
3871 return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3872}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3880
int16 attnum
Definition: pg_attribute.h:74

References attnum, mode, and pg_attribute_aclcheck_ext().

Referenced by all_rows_selectable(), BuildIndexValueDescription(), checkFkeyPermissions(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), and ri_ReportViolation().

◆ pg_attribute_aclcheck_all()

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

Definition at line 3910 of file aclchk.c.

3912{
3913 return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3914}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3921

References mode, and pg_attribute_aclcheck_all_ext().

Referenced by all_rows_selectable(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), and has_any_column_privilege_name_name().

◆ pg_attribute_aclcheck_all_ext()

AclResult pg_attribute_aclcheck_all_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how,
bool *  is_missing 
)

Definition at line 3921 of file aclchk.c.

3924{
3925 AclResult result;
3926 HeapTuple classTuple;
3927 Form_pg_class classForm;
3928 Oid ownerId;
3929 AttrNumber nattrs;
3930 AttrNumber curr_att;
3931
3932 /*
3933 * Must fetch pg_class row to get owner ID and number of attributes.
3934 */
3935 classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3936 if (!HeapTupleIsValid(classTuple))
3937 {
3938 if (is_missing != NULL)
3939 {
3940 /* return "no privileges" instead of throwing an error */
3941 *is_missing = true;
3942 return ACLCHECK_NO_PRIV;
3943 }
3944 else
3945 ereport(ERROR,
3947 errmsg("relation with OID %u does not exist",
3948 table_oid)));
3949 }
3950 classForm = (Form_pg_class) GETSTRUCT(classTuple);
3951
3952 ownerId = classForm->relowner;
3953 nattrs = classForm->relnatts;
3954
3955 ReleaseSysCache(classTuple);
3956
3957 /*
3958 * Initialize result in case there are no non-dropped columns. We want to
3959 * report failure in such cases for either value of 'how'.
3960 */
3961 result = ACLCHECK_NO_PRIV;
3962
3963 for (curr_att = 1; curr_att <= nattrs; curr_att++)
3964 {
3965 HeapTuple attTuple;
3966 Datum aclDatum;
3967 bool isNull;
3968 Acl *acl;
3969 AclMode attmask;
3970
3971 attTuple = SearchSysCache2(ATTNUM,
3972 ObjectIdGetDatum(table_oid),
3973 Int16GetDatum(curr_att));
3974
3975 /*
3976 * Lookup failure probably indicates that the table was just dropped,
3977 * but we'll treat it the same as a dropped column rather than
3978 * throwing error.
3979 */
3980 if (!HeapTupleIsValid(attTuple))
3981 continue;
3982
3983 /* ignore dropped columns */
3984 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
3985 {
3986 ReleaseSysCache(attTuple);
3987 continue;
3988 }
3989
3990 aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3991 &isNull);
3992
3993 /*
3994 * Here we hard-wire knowledge that the default ACL for a column
3995 * grants no privileges, so that we can fall out quickly in the very
3996 * common case where attacl is null.
3997 */
3998 if (isNull)
3999 attmask = 0;
4000 else
4001 {
4002 /* detoast column's ACL if necessary */
4003 acl = DatumGetAclP(aclDatum);
4004
4005 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4006
4007 /* if we have a detoasted copy, free it */
4008 if (acl != DatumGetPointer(aclDatum))
4009 pfree(acl);
4010 }
4011
4012 ReleaseSysCache(attTuple);
4013
4014 if (attmask != 0)
4015 {
4016 result = ACLCHECK_OK;
4017 if (how == ACLMASK_ANY)
4018 break; /* succeed on any success */
4019 }
4020 else
4021 {
4022 result = ACLCHECK_NO_PRIV;
4023 if (how == ACLMASK_ALL)
4024 break; /* fail on any failure */
4025 }
4026 }
4027
4028 return result;
4029}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1388
#define DatumGetAclP(X)
Definition: acl.h:120
int16 AttrNumber
Definition: attnum.h:21
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
FormData_pg_class * Form_pg_class
Definition: pg_class.h:156
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:79
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:182
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:595
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:230

References ACLCHECK_NO_PRIV, ACLCHECK_OK, aclmask(), ACLMASK_ALL, ACLMASK_ANY, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg(), ERROR, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttr().

Referenced by has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_name_id(), and pg_attribute_aclcheck_all().

◆ pg_attribute_aclcheck_ext()

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

Definition at line 3880 of file aclchk.c.

3882{
3883 if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3884 ACLMASK_ANY, is_missing) != 0)
3885 return ACLCHECK_OK;
3886 else
3887 return ACLCHECK_NO_PRIV;
3888}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3158

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, attnum, mode, and pg_attribute_aclmask_ext().

Referenced by column_privilege_check(), and pg_attribute_aclcheck().

◆ pg_class_aclcheck()

◆ pg_class_aclcheck_ext()

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

Definition at line 4049 of file aclchk.c.

4051{
4052 if (pg_class_aclmask_ext(table_oid, roleid, mode,
4053 ACLMASK_ANY, is_missing) != 0)
4054 return ACLCHECK_OK;
4055 else
4056 return ACLCHECK_NO_PRIV;
4057}
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3282

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

Referenced by column_privilege_check(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_name_id(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_name_id(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_name_id(), and pg_class_aclcheck().

◆ pg_class_aclmask()

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

Definition at line 3272 of file aclchk.c.

3274{
3275 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3276}

References pg_class_aclmask_ext().

Referenced by ExecCheckOneRelPerms(), and pg_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4076 of file aclchk.c.

4078{
4079 if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4080 ACLMASK_ANY, snapshot) != 0)
4081 return ACLCHECK_OK;
4082 else
4083 return ACLCHECK_NO_PRIV;
4084}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3535

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

Referenced by has_lo_priv_byid(), and inv_open().

◆ pg_parameter_aclcheck()

AclResult pg_parameter_aclcheck ( const char *  name,
Oid  roleid,
AclMode  mode 
)

Definition at line 4064 of file aclchk.c.

4065{
4066 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4067 return ACLCHECK_OK;
4068 else
4069 return ACLCHECK_NO_PRIV;
4070}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3412
const char * name

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, name, and pg_parameter_aclmask().

Referenced by AlterSystemSetConfigFile(), has_param_priv_byname(), set_config_with_handle(), and validate_option_array_item().

◆ recordDependencyOnNewAcl()

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

Definition at line 4327 of file aclchk.c.

4329{
4330 int nmembers;
4331 Oid *members;
4332
4333 /* Nothing to do if ACL is defaulted */
4334 if (acl == NULL)
4335 return;
4336
4337 /* Extract roles mentioned in ACL */
4338 nmembers = aclmembers(acl, &members);
4339
4340 /* Update the shared dependency ACL info */
4341 updateAclDependencies(classId, objectId, objsubId,
4342 ownerId,
4343 0, NULL,
4344 nmembers, members);
4345}
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1540
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:491

References aclmembers(), and updateAclDependencies().

Referenced by GenerateTypeDependencies(), heap_create_with_catalog(), LargeObjectCreate(), NamespaceCreate(), and ProcedureCreate().

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4354 of file aclchk.c.

4355{
4356 /*
4357 * pg_class / pg_attribute
4358 *
4359 * If this is a relation then we need to see if there are any sub-objects
4360 * (eg: columns) for it and, if so, be sure to call
4361 * recordExtensionInitPrivWorker() for each one.
4362 */
4363 if (classoid == RelationRelationId)
4364 {
4365 Form_pg_class pg_class_tuple;
4366 Datum aclDatum;
4367 bool isNull;
4368 HeapTuple tuple;
4369
4370 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4371 if (!HeapTupleIsValid(tuple))
4372 elog(ERROR, "cache lookup failed for relation %u", objoid);
4373 pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4374
4375 /*
4376 * Indexes don't have permissions, neither do the pg_class rows for
4377 * composite types. (These cases are unreachable given the
4378 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4379 */
4380 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4381 pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4382 pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4383 {
4384 ReleaseSysCache(tuple);
4385 return;
4386 }
4387
4388 /*
4389 * If this isn't a sequence then it's possibly going to have
4390 * column-level ACLs associated with it.
4391 */
4392 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4393 {
4394 AttrNumber curr_att;
4395 AttrNumber nattrs = pg_class_tuple->relnatts;
4396
4397 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4398 {
4399 HeapTuple attTuple;
4400 Datum attaclDatum;
4401
4402 attTuple = SearchSysCache2(ATTNUM,
4403 ObjectIdGetDatum(objoid),
4404 Int16GetDatum(curr_att));
4405
4406 if (!HeapTupleIsValid(attTuple))
4407 continue;
4408
4409 /* ignore dropped columns */
4410 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4411 {
4412 ReleaseSysCache(attTuple);
4413 continue;
4414 }
4415
4416 attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
4417 Anum_pg_attribute_attacl,
4418 &isNull);
4419
4420 /* no need to do anything for a NULL ACL */
4421 if (isNull)
4422 {
4423 ReleaseSysCache(attTuple);
4424 continue;
4425 }
4426
4427 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4428 DatumGetAclP(attaclDatum));
4429
4430 ReleaseSysCache(attTuple);
4431 }
4432 }
4433
4434 aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
4435 &isNull);
4436
4437 /* Add the record, if any, for the top-level object */
4438 if (!isNull)
4439 recordExtensionInitPrivWorker(objoid, classoid, 0,
4440 DatumGetAclP(aclDatum));
4441
4442 ReleaseSysCache(tuple);
4443 }
4444 else if (classoid == LargeObjectRelationId)
4445 {
4446 /* For large objects, we must consult pg_largeobject_metadata */
4447 Datum aclDatum;
4448 bool isNull;
4449 HeapTuple tuple;
4450 ScanKeyData entry[1];
4451 SysScanDesc scan;
4452 Relation relation;
4453
4454 /*
4455 * Note: this is dead code, given that we don't allow large objects to
4456 * be made extension members. But it seems worth carrying in case
4457 * some future caller of this function has need for it.
4458 */
4459 relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock);
4460
4461 /* There's no syscache for pg_largeobject_metadata */
4462 ScanKeyInit(&entry[0],
4463 Anum_pg_largeobject_metadata_oid,
4464 BTEqualStrategyNumber, F_OIDEQ,
4465 ObjectIdGetDatum(objoid));
4466
4467 scan = systable_beginscan(relation,
4468 LargeObjectMetadataOidIndexId, true,
4469 NULL, 1, entry);
4470
4471 tuple = systable_getnext(scan);
4472 if (!HeapTupleIsValid(tuple))
4473 elog(ERROR, "could not find tuple for large object %u", objoid);
4474
4475 aclDatum = heap_getattr(tuple,
4476 Anum_pg_largeobject_metadata_lomacl,
4477 RelationGetDescr(relation), &isNull);
4478
4479 /* Add the record, if any, for the top-level object */
4480 if (!isNull)
4481 recordExtensionInitPrivWorker(objoid, classoid, 0,
4482 DatumGetAclP(aclDatum));
4483
4484 systable_endscan(scan);
4485 }
4486 /* This will error on unsupported classoid. */
4487 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4488 {
4489 int cacheid;
4490 Datum aclDatum;
4491 bool isNull;
4492 HeapTuple tuple;
4493
4494 cacheid = get_object_catcache_oid(classoid);
4495 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4496 if (!HeapTupleIsValid(tuple))
4497 elog(ERROR, "cache lookup failed for %s %u",
4498 get_object_class_descr(classoid), objoid);
4499
4500 aclDatum = SysCacheGetAttr(cacheid, tuple,
4501 get_object_attnum_acl(classoid),
4502 &isNull);
4503
4504 /* Add the record, if any, for the top-level object */
4505 if (!isNull)
4506 recordExtensionInitPrivWorker(objoid, classoid, 0,
4507 DatumGetAclP(aclDatum));
4508
4509 ReleaseSysCache(tuple);
4510 }
4511}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition: aclchk.c:4630
#define InvalidAttrNumber
Definition: attnum.h:23
#define RowExclusiveLock
Definition: lockdefs.h:38
AttrNumber get_object_attnum_acl(Oid class_id)

References BTEqualStrategyNumber, DatumGetAclP, elog, ERROR, get_object_attnum_acl(), get_object_catcache_oid(), get_object_class_descr(), GETSTRUCT(), heap_getattr(), HeapTupleIsValid, Int16GetDatum(), InvalidAttrNumber, ObjectIdGetDatum(), recordExtensionInitPrivWorker(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SearchSysCache2(), SysCacheGetAttr(), systable_beginscan(), systable_endscan(), systable_getnext(), and table_open().

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4518 of file aclchk.c.

4519{
4520 /*
4521 * If this is a relation then we need to see if there are any sub-objects
4522 * (eg: columns) for it and, if so, be sure to call
4523 * recordExtensionInitPrivWorker() for each one.
4524 */
4525 if (classoid == RelationRelationId)
4526 {
4527 Form_pg_class pg_class_tuple;
4528 HeapTuple tuple;
4529
4530 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4531 if (!HeapTupleIsValid(tuple))
4532 elog(ERROR, "cache lookup failed for relation %u", objoid);
4533 pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
4534
4535 /*
4536 * Indexes don't have permissions, neither do the pg_class rows for
4537 * composite types. (These cases are unreachable given the
4538 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4539 */
4540 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4541 pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
4542 pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
4543 {
4544 ReleaseSysCache(tuple);
4545 return;
4546 }
4547
4548 /*
4549 * If this isn't a sequence then it's possibly going to have
4550 * column-level ACLs associated with it.
4551 */
4552 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4553 {
4554 AttrNumber curr_att;
4555 AttrNumber nattrs = pg_class_tuple->relnatts;
4556
4557 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4558 {
4559 HeapTuple attTuple;
4560
4561 attTuple = SearchSysCache2(ATTNUM,
4562 ObjectIdGetDatum(objoid),
4563 Int16GetDatum(curr_att));
4564
4565 if (!HeapTupleIsValid(attTuple))
4566 continue;
4567
4568 /* when removing, remove all entries, even dropped columns */
4569
4570 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4571
4572 ReleaseSysCache(attTuple);
4573 }
4574 }
4575
4576 ReleaseSysCache(tuple);
4577 }
4578
4579 /* Remove the record, if any, for the top-level object */
4580 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4581}

References elog, ERROR, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), ObjectIdGetDatum(), recordExtensionInitPrivWorker(), ReleaseSysCache(), SearchSysCache1(), and SearchSysCache2().

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

void RemoveRoleFromInitPriv ( Oid  roleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4867 of file aclchk.c.

4868{
4869 Relation rel;
4870 ScanKeyData key[3];
4871 SysScanDesc scan;
4872 HeapTuple oldtuple;
4873 int cacheid;
4874 HeapTuple objtuple;
4875 Oid ownerId;
4876 Datum oldAclDatum;
4877 bool isNull;
4878 Acl *old_acl;
4879 Acl *new_acl;
4880 HeapTuple newtuple;
4881 int noldmembers;
4882 int nnewmembers;
4883 Oid *oldmembers;
4884 Oid *newmembers;
4885
4886 /* Search for existing pg_init_privs entry for the target object. */
4887 rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4888
4889 ScanKeyInit(&key[0],
4890 Anum_pg_init_privs_objoid,
4891 BTEqualStrategyNumber, F_OIDEQ,
4892 ObjectIdGetDatum(objid));
4893 ScanKeyInit(&key[1],
4894 Anum_pg_init_privs_classoid,
4895 BTEqualStrategyNumber, F_OIDEQ,
4896 ObjectIdGetDatum(classid));
4897 ScanKeyInit(&key[2],
4898 Anum_pg_init_privs_objsubid,
4899 BTEqualStrategyNumber, F_INT4EQ,
4900 Int32GetDatum(objsubid));
4901
4902 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4903 NULL, 3, key);
4904
4905 /* There should exist only one entry or none. */
4906 oldtuple = systable_getnext(scan);
4907
4908 if (!HeapTupleIsValid(oldtuple))
4909 {
4910 /*
4911 * Hmm, why are we here if there's no entry? But pack up and go away
4912 * quietly.
4913 */
4914 systable_endscan(scan);
4916 return;
4917 }
4918
4919 /* Get a writable copy of the existing ACL. */
4920 oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4921 RelationGetDescr(rel), &isNull);
4922 Assert(!isNull);
4923 old_acl = DatumGetAclPCopy(oldAclDatum);
4924
4925 /*
4926 * We need the members of both old and new ACLs so we can correct the
4927 * shared dependency information. Collect data before
4928 * merge_acl_with_grant throws away old_acl.
4929 */
4930 noldmembers = aclmembers(old_acl, &oldmembers);
4931
4932 /* Must find out the owner's OID the hard way. */
4933 cacheid = get_object_catcache_oid(classid);
4934 objtuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objid));
4935 if (!HeapTupleIsValid(objtuple))
4936 elog(ERROR, "cache lookup failed for %s %u",
4937 get_object_class_descr(classid), objid);
4938
4939 ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4940 objtuple,
4941 get_object_attnum_owner(classid)));
4942 ReleaseSysCache(objtuple);
4943
4944 /*
4945 * Generate new ACL. Grantor of rights is always the same as the owner.
4946 */
4947 if (old_acl != NULL)
4948 new_acl = merge_acl_with_grant(old_acl,
4949 false, /* is_grant */
4950 false, /* grant_option */
4952 list_make1_oid(roleid),
4954 ownerId,
4955 ownerId);
4956 else
4957 new_acl = NULL; /* this case shouldn't happen, probably */
4958
4959 /* If we end with an empty ACL, delete the pg_init_privs entry. */
4960 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4961 {
4962 CatalogTupleDelete(rel, &oldtuple->t_self);
4963 }
4964 else
4965 {
4966 Datum values[Natts_pg_init_privs] = {0};
4967 bool nulls[Natts_pg_init_privs] = {0};
4968 bool replaces[Natts_pg_init_privs] = {0};
4969
4970 /* Update existing entry. */
4971 values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4972 replaces[Anum_pg_init_privs_initprivs - 1] = true;
4973
4974 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4975 values, nulls, replaces);
4976 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4977 }
4978
4979 /*
4980 * Update the shared dependency ACL info.
4981 */
4982 nnewmembers = aclmembers(new_acl, &newmembers);
4983
4984 updateInitAclDependencies(classid, objid, objsubid,
4985 noldmembers, oldmembers,
4986 nnewmembers, newmembers);
4987
4988 systable_endscan(scan);
4989
4990 /* prevent error when processing objects multiple times */
4992
4994}
#define ACLITEM_ALL_PRIV_BITS
Definition: acl.h:87
#define DatumGetAclPCopy(X)
Definition: acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition: aclchk.c:181
static Datum values[MAXATTR]
Definition: bootstrap.c:153
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1210
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition: indexing.c:365
#define list_make1_oid(x1)
Definition: pg_list.h:242
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:512
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
ItemPointerData t_self
Definition: htup.h:65
void CommandCounterIncrement(void)
Definition: xact.c:1101

References ACL_NUM, ACLITEM_ALL_PRIV_BITS, aclmembers(), Assert(), BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, DatumGetObjectId(), DROP_RESTRICT, elog, ERROR, get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), sort-test::key, list_make1_oid, merge_acl_with_grant(), ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

void RemoveRoleFromObjectACL ( Oid  roleid,
Oid  classid,
Oid  objid 
)

Definition at line 1422 of file aclchk.c.

1423{
1424 if (classid == DefaultAclRelationId)
1425 {
1426 InternalDefaultACL iacls;
1427 Form_pg_default_acl pg_default_acl_tuple;
1428 Relation rel;
1429 ScanKeyData skey[1];
1430 SysScanDesc scan;
1431 HeapTuple tuple;
1432
1433 /* first fetch info needed by SetDefaultACL */
1434 rel = table_open(DefaultAclRelationId, AccessShareLock);
1435
1436 ScanKeyInit(&skey[0],
1437 Anum_pg_default_acl_oid,
1438 BTEqualStrategyNumber, F_OIDEQ,
1439 ObjectIdGetDatum(objid));
1440
1441 scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1442 NULL, 1, skey);
1443
1444 tuple = systable_getnext(scan);
1445
1446 if (!HeapTupleIsValid(tuple))
1447 elog(ERROR, "could not find tuple for default ACL %u", objid);
1448
1449 pg_default_acl_tuple = (Form_pg_default_acl) GETSTRUCT(tuple);
1450
1451 iacls.roleid = pg_default_acl_tuple->defaclrole;
1452 iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1453
1454 switch (pg_default_acl_tuple->defaclobjtype)
1455 {
1456 case DEFACLOBJ_RELATION:
1457 iacls.objtype = OBJECT_TABLE;
1458 break;
1459 case DEFACLOBJ_SEQUENCE:
1460 iacls.objtype = OBJECT_SEQUENCE;
1461 break;
1462 case DEFACLOBJ_FUNCTION:
1463 iacls.objtype = OBJECT_FUNCTION;
1464 break;
1465 case DEFACLOBJ_TYPE:
1466 iacls.objtype = OBJECT_TYPE;
1467 break;
1468 case DEFACLOBJ_NAMESPACE:
1469 iacls.objtype = OBJECT_SCHEMA;
1470 break;
1471 case DEFACLOBJ_LARGEOBJECT:
1473 break;
1474 default:
1475 /* Shouldn't get here */
1476 elog(ERROR, "unexpected default ACL type: %d",
1477 (int) pg_default_acl_tuple->defaclobjtype);
1478 break;
1479 }
1480
1481 systable_endscan(scan);
1483
1484 iacls.is_grant = false;
1485 iacls.all_privs = true;
1486 iacls.privileges = ACL_NO_RIGHTS;
1487 iacls.grantees = list_make1_oid(roleid);
1488 iacls.grant_option = false;
1489 iacls.behavior = DROP_CASCADE;
1490
1491 /* Do it */
1492 SetDefaultACL(&iacls);
1493 }
1494 else
1495 {
1496 InternalGrant istmt;
1497
1498 switch (classid)
1499 {
1500 case RelationRelationId:
1501 /* it's OK to use TABLE for a sequence */
1502 istmt.objtype = OBJECT_TABLE;
1503 break;
1504 case DatabaseRelationId:
1505 istmt.objtype = OBJECT_DATABASE;
1506 break;
1507 case TypeRelationId:
1508 istmt.objtype = OBJECT_TYPE;
1509 break;
1510 case ProcedureRelationId:
1511 istmt.objtype = OBJECT_ROUTINE;
1512 break;
1513 case LanguageRelationId:
1514 istmt.objtype = OBJECT_LANGUAGE;
1515 break;
1516 case LargeObjectRelationId:
1518 break;
1519 case NamespaceRelationId:
1520 istmt.objtype = OBJECT_SCHEMA;
1521 break;
1522 case TableSpaceRelationId:
1523 istmt.objtype = OBJECT_TABLESPACE;
1524 break;
1525 case ForeignServerRelationId:
1527 break;
1528 case ForeignDataWrapperRelationId:
1529 istmt.objtype = OBJECT_FDW;
1530 break;
1531 case ParameterAclRelationId:
1533 break;
1534 default:
1535 elog(ERROR, "unexpected object class %u", classid);
1536 break;
1537 }
1538 istmt.is_grant = false;
1539 istmt.objects = list_make1_oid(objid);
1540 istmt.all_privs = true;
1541 istmt.privileges = ACL_NO_RIGHTS;
1542 istmt.col_privs = NIL;
1543 istmt.grantees = list_make1_oid(roleid);
1544 istmt.grant_option = false;
1545 istmt.behavior = DROP_CASCADE;
1546
1547 ExecGrantStmt_oids(&istmt);
1548 }
1549}
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition: aclchk.c:1147
@ DROP_CASCADE
Definition: parsenodes.h:2399
FormData_pg_default_acl * Form_pg_default_acl

References AccessShareLock, ACL_NO_RIGHTS, InternalDefaultACL::all_privs, InternalGrant::all_privs, InternalDefaultACL::behavior, InternalGrant::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DROP_CASCADE, elog, ERROR, ExecGrantStmt_oids(), GETSTRUCT(), InternalDefaultACL::grant_option, InternalGrant::grant_option, InternalDefaultACL::grantees, InternalGrant::grantees, HeapTupleIsValid, InternalDefaultACL::is_grant, InternalGrant::is_grant, list_make1_oid, NIL, InternalDefaultACL::nspid, OBJECT_DATABASE, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, ObjectIdGetDatum(), InternalGrant::objects, InternalDefaultACL::objtype, InternalGrant::objtype, InternalDefaultACL::privileges, InternalGrant::privileges, InternalDefaultACL::roleid, ScanKeyInit(), SetDefaultACL(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

void ReplaceRoleInInitPriv ( Oid  oldroleid,
Oid  newroleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4758 of file aclchk.c.

4760{
4761 Relation rel;
4762 ScanKeyData key[3];
4763 SysScanDesc scan;
4764 HeapTuple oldtuple;
4765 Datum oldAclDatum;
4766 bool isNull;
4767 Acl *old_acl;
4768 Acl *new_acl;
4769 HeapTuple newtuple;
4770 int noldmembers;
4771 int nnewmembers;
4772 Oid *oldmembers;
4773 Oid *newmembers;
4774
4775 /* Search for existing pg_init_privs entry for the target object. */
4776 rel = table_open(InitPrivsRelationId, RowExclusiveLock);
4777
4778 ScanKeyInit(&key[0],
4779 Anum_pg_init_privs_objoid,
4780 BTEqualStrategyNumber, F_OIDEQ,
4781 ObjectIdGetDatum(objid));
4782 ScanKeyInit(&key[1],
4783 Anum_pg_init_privs_classoid,
4784 BTEqualStrategyNumber, F_OIDEQ,
4785 ObjectIdGetDatum(classid));
4786 ScanKeyInit(&key[2],
4787 Anum_pg_init_privs_objsubid,
4788 BTEqualStrategyNumber, F_INT4EQ,
4789 Int32GetDatum(objsubid));
4790
4791 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4792 NULL, 3, key);
4793
4794 /* There should exist only one entry or none. */
4795 oldtuple = systable_getnext(scan);
4796
4797 if (!HeapTupleIsValid(oldtuple))
4798 {
4799 /*
4800 * Hmm, why are we here if there's no entry? But pack up and go away
4801 * quietly.
4802 */
4803 systable_endscan(scan);
4805 return;
4806 }
4807
4808 /* Get a writable copy of the existing ACL. */
4809 oldAclDatum = heap_getattr(oldtuple, Anum_pg_init_privs_initprivs,
4810 RelationGetDescr(rel), &isNull);
4811 Assert(!isNull);
4812 old_acl = DatumGetAclPCopy(oldAclDatum);
4813
4814 /*
4815 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4816 * oldroleid isn't the owner; but it does the job fine.
4817 */
4818 new_acl = aclnewowner(old_acl, oldroleid, newroleid);
4819
4820 /*
4821 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4822 * probably can't happen here, but we may as well cover the case.)
4823 */
4824 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4825 {
4826 CatalogTupleDelete(rel, &oldtuple->t_self);
4827 }
4828 else
4829 {
4830 Datum values[Natts_pg_init_privs] = {0};
4831 bool nulls[Natts_pg_init_privs] = {0};
4832 bool replaces[Natts_pg_init_privs] = {0};
4833
4834 /* Update existing entry. */
4835 values[Anum_pg_init_privs_initprivs - 1] = PointerGetDatum(new_acl);
4836 replaces[Anum_pg_init_privs_initprivs - 1] = true;
4837
4838 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4839 values, nulls, replaces);
4840 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4841 }
4842
4843 /*
4844 * Update the shared dependency ACL info.
4845 */
4846 noldmembers = aclmembers(old_acl, &oldmembers);
4847 nnewmembers = aclmembers(new_acl, &newmembers);
4848
4849 updateInitAclDependencies(classid, objid, objsubid,
4850 noldmembers, oldmembers,
4851 nnewmembers, newmembers);
4852
4853 systable_endscan(scan);
4854
4855 /* prevent error when processing objects multiple times */
4857
4859}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1119

References ACL_NUM, aclmembers(), aclnewowner(), Assert(), BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), sort-test::key, ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepReassignOwned_InitAcl().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5439 of file acl.c.

5440{
5441 Oid admin_role;
5442
5443 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5444 if (member == role)
5445 return InvalidOid;
5446
5447 (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5448 return admin_role;
5449}

References InvalidOid, ROLERECURSE_PRIVS, and roles_is_member_of().

Referenced by check_role_grantor().

◆ select_best_grantor()

void select_best_grantor ( Oid  roleId,
AclMode  privileges,
const Acl acl,
Oid  ownerId,
Oid grantorId,
AclMode grantOptions 
)

Definition at line 5476 of file acl.c.

5479{
5480 AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5481 List *roles_list;
5482 int nrights;
5483 ListCell *l;
5484
5485 /*
5486 * The object owner is always treated as having all grant options, so if
5487 * roleId is the owner it's easy. Also, if roleId is a superuser it's
5488 * easy: superusers are implicitly members of every role, so they act as
5489 * the object owner.
5490 */
5491 if (roleId == ownerId || superuser_arg(roleId))
5492 {
5493 *grantorId = ownerId;
5494 *grantOptions = needed_goptions;
5495 return;
5496 }
5497
5498 /*
5499 * Otherwise we have to do a careful search to see if roleId has the
5500 * privileges of any suitable role. Note: we can hang onto the result of
5501 * roles_is_member_of() throughout this loop, because aclmask_direct()
5502 * doesn't query any role memberships.
5503 */
5504 roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5505 InvalidOid, NULL);
5506
5507 /* initialize candidate result as default */
5508 *grantorId = roleId;
5509 *grantOptions = ACL_NO_RIGHTS;
5510 nrights = 0;
5511
5512 foreach(l, roles_list)
5513 {
5514 Oid otherrole = lfirst_oid(l);
5515 AclMode otherprivs;
5516
5517 otherprivs = aclmask_direct(acl, otherrole, ownerId,
5518 needed_goptions, ACLMASK_ALL);
5519 if (otherprivs == needed_goptions)
5520 {
5521 /* Found a suitable grantor */
5522 *grantorId = otherrole;
5523 *grantOptions = otherprivs;
5524 return;
5525 }
5526
5527 /*
5528 * If it has just some of the needed privileges, remember best
5529 * candidate.
5530 */
5531 if (otherprivs != ACL_NO_RIGHTS)
5532 {
5533 int nnewrights = pg_popcount64(otherprivs);
5534
5535 if (nnewrights > nrights)
5536 {
5537 *grantorId = otherrole;
5538 *grantOptions = otherprivs;
5539 nrights = nnewrights;
5540 }
5541 }
5542 }
5543}
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1477
#define ACL_GRANT_OPTION_FOR(privs)
Definition: acl.h:70
int pg_popcount64(uint64 word)
Definition: pg_bitutils.c:515
#define lfirst_oid(lc)
Definition: pg_list.h:174

References ACL_GRANT_OPTION_FOR, ACL_NO_RIGHTS, ACLMASK_ALL, aclmask_direct(), InvalidOid, lfirst_oid, pg_popcount64(), ROLERECURSE_PRIVS, roles_is_member_of(), and superuser_arg().

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), and ExecGrant_Relation().