Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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

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

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(), get_rel_from_relname(), 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(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackMaintainsTable(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), stats_lock_check_privileges(), 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 2941 of file aclchk.c.

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

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:479

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:2397

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:1234
@ 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 & ~((AclMode) all_privileges))
1063 ereport(ERROR,
1064 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1065 errmsg(errormsg, privilege_to_string(priv))));
1066
1067 iacls.privileges |= priv;
1068 }
1069 }
1070
1071 if (rolespecs == NIL)
1072 {
1073 /* Set permissions for myself */
1074 iacls.roleid = GetUserId();
1075
1076 SetDefaultACLsInSchemas(&iacls, nspnames);
1077 }
1078 else
1079 {
1080 /* Look up the role OIDs and do permissions checks */
1081 ListCell *rolecell;
1082
1083 foreach(rolecell, rolespecs)
1084 {
1085 RoleSpec *rolespec = lfirst(rolecell);
1086
1087 iacls.roleid = get_rolespec_oid(rolespec, false);
1088
1089 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:2564
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1105
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2605
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:2626
List * cols
Definition: parsenodes.h:2627
char * defname
Definition: parsenodes.h:842
Node * arg
Definition: parsenodes.h:843
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 & ~((AclMode) 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:2569
@ ACL_TARGET_ALL_IN_SCHEMA
Definition: parsenodes.h:2570
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:775
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:752
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 4245 of file aclchk.c.

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

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

4187{
4188 bool result = false;
4189 HeapTuple utup;
4190
4191 /* Superusers bypass all permission checking. */
4192 if (superuser_arg(roleid))
4193 return true;
4194
4195 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4196 if (HeapTupleIsValid(utup))
4197 {
4198 result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4199 ReleaseSysCache(utup);
4200 }
4201 return result;
4202}
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 4167 of file aclchk.c.

4168{
4169 bool result = false;
4170 HeapTuple utup;
4171
4172 /* Superusers bypass all permission checking. */
4173 if (superuser_arg(roleid))
4174 return true;
4175
4176 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4177 if (HeapTupleIsValid(utup))
4178 {
4179 result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4180 ReleaseSysCache(utup);
4181 }
4182 return result;
4183}
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 3834 of file aclchk.c.

3835{
3836 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3837}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3844
static PgChecksumMode mode
Definition: pg_checksums.c:55

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(), 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_set_returning_function(), 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 4088 of file aclchk.c.

4089{
4090 int cacheid;
4091 Oid ownerId;
4092
4093 /* Superusers bypass all permission checking. */
4094 if (superuser_arg(roleid))
4095 return true;
4096
4097 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4098 if (classid == LargeObjectRelationId)
4099 classid = LargeObjectMetadataRelationId;
4100
4101 cacheid = get_object_catcache_oid(classid);
4102 if (cacheid != -1)
4103 {
4104 /* we can get the object's tuple from the syscache */
4105 HeapTuple tuple;
4106
4107 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4108 if (!HeapTupleIsValid(tuple))
4109 elog(ERROR, "cache lookup failed for %s %u",
4110 get_object_class_descr(classid), objectid);
4111
4112 ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4113 tuple,
4114 get_object_attnum_owner(classid)));
4115 ReleaseSysCache(tuple);
4116 }
4117 else
4118 {
4119 /* for catalogs without an appropriate syscache */
4120 Relation rel;
4121 ScanKeyData entry[1];
4122 SysScanDesc scan;
4123 HeapTuple tuple;
4124 bool isnull;
4125
4126 rel = table_open(classid, AccessShareLock);
4127
4128 ScanKeyInit(&entry[0],
4129 get_object_attnum_oid(classid),
4130 BTEqualStrategyNumber, F_OIDEQ,
4131 ObjectIdGetDatum(objectid));
4132
4133 scan = systable_beginscan(rel,
4134 get_object_oid_index(classid), true,
4135 NULL, 1, entry);
4136
4137 tuple = systable_getnext(scan);
4138 if (!HeapTupleIsValid(tuple))
4139 elog(ERROR, "could not find tuple for %s %u",
4140 get_object_class_descr(classid), objectid);
4141
4142 ownerId = DatumGetObjectId(heap_getattr(tuple,
4143 get_object_attnum_owner(classid),
4144 RelationGetDescr(rel),
4145 &isnull));
4146 Assert(!isnull);
4147
4148 systable_endscan(scan);
4150 }
4151
4152 return has_privs_of_role(roleid, ownerId);
4153}
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:540
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(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), stats_lock_check_privileges(), 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 3866 of file aclchk.c.

3868{
3869 return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3870}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3878
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 3908 of file aclchk.c.

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

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

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

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

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

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

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

3272{
3273 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3274}

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

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

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

4063{
4064 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4065 return ACLCHECK_OK;
4066 else
4067 return ACLCHECK_NO_PRIV;
4068}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3410
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 4325 of file aclchk.c.

4327{
4328 int nmembers;
4329 Oid *members;
4330
4331 /* Nothing to do if ACL is defaulted */
4332 if (acl == NULL)
4333 return;
4334
4335 /* Extract roles mentioned in ACL */
4336 nmembers = aclmembers(acl, &members);
4337
4338 /* Update the shared dependency ACL info */
4339 updateAclDependencies(classId, objectId, objsubId,
4340 ownerId,
4341 0, NULL,
4342 nmembers, members);
4343}
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 4352 of file aclchk.c.

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

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

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

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

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

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

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