PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 2639 of file aclchk.c.

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

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

2930{
2931 switch (aclerr)
2932 {
2933 case ACLCHECK_OK:
2934 /* no error, so return to caller */
2935 break;
2936 case ACLCHECK_NO_PRIV:
2937 ereport(ERROR,
2938 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2939 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2940 colname, objectname)));
2941 break;
2942 case ACLCHECK_NOT_OWNER:
2943 /* relation msg is OK since columns don't have separate owners */
2944 aclcheck_error(aclerr, objtype, objectname);
2945 break;
2946 default:
2947 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2948 break;
2949 }
2950}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2639

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 461 of file acl.c.

462{
463 Acl *result_acl;
464
465 result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
466
467 memcpy(ACL_DAT(result_acl),
468 ACL_DAT(left_acl),
469 ACL_NUM(left_acl) * sizeof(AclItem));
470
471 memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
472 ACL_DAT(right_acl),
473 ACL_NUM(right_acl) * sizeof(AclItem));
474
475 return result_acl;
476}
static Acl * allocacl(int n)
Definition: acl.c:410
#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 441 of file acl.c.

442{
443 Acl *result_acl;
444
445 result_acl = allocacl(ACL_NUM(orig_acl));
446
447 memcpy(ACL_DAT(result_acl),
448 ACL_DAT(orig_acl),
449 ACL_NUM(orig_acl) * sizeof(AclItem));
450
451 return result_acl;
452}

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 787 of file acl.c.

788{
789 AclMode world_default;
790 AclMode owner_default;
791 int nacl;
792 Acl *acl;
793 AclItem *aip;
794
795 switch (objtype)
796 {
797 case OBJECT_COLUMN:
798 /* by default, columns have no extra privileges */
799 world_default = ACL_NO_RIGHTS;
800 owner_default = ACL_NO_RIGHTS;
801 break;
802 case OBJECT_TABLE:
803 world_default = ACL_NO_RIGHTS;
804 owner_default = ACL_ALL_RIGHTS_RELATION;
805 break;
806 case OBJECT_SEQUENCE:
807 world_default = ACL_NO_RIGHTS;
808 owner_default = ACL_ALL_RIGHTS_SEQUENCE;
809 break;
810 case OBJECT_DATABASE:
811 /* for backwards compatibility, grant some rights by default */
812 world_default = ACL_CREATE_TEMP | ACL_CONNECT;
813 owner_default = ACL_ALL_RIGHTS_DATABASE;
814 break;
815 case OBJECT_FUNCTION:
816 /* Grant EXECUTE by default, for now */
817 world_default = ACL_EXECUTE;
818 owner_default = ACL_ALL_RIGHTS_FUNCTION;
819 break;
820 case OBJECT_LANGUAGE:
821 /* Grant USAGE by default, for now */
822 world_default = ACL_USAGE;
823 owner_default = ACL_ALL_RIGHTS_LANGUAGE;
824 break;
826 world_default = ACL_NO_RIGHTS;
827 owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
828 break;
829 case OBJECT_SCHEMA:
830 world_default = ACL_NO_RIGHTS;
831 owner_default = ACL_ALL_RIGHTS_SCHEMA;
832 break;
834 world_default = ACL_NO_RIGHTS;
835 owner_default = ACL_ALL_RIGHTS_TABLESPACE;
836 break;
837 case OBJECT_FDW:
838 world_default = ACL_NO_RIGHTS;
839 owner_default = ACL_ALL_RIGHTS_FDW;
840 break;
842 world_default = ACL_NO_RIGHTS;
843 owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
844 break;
845 case OBJECT_DOMAIN:
846 case OBJECT_TYPE:
847 world_default = ACL_USAGE;
848 owner_default = ACL_ALL_RIGHTS_TYPE;
849 break;
851 world_default = ACL_NO_RIGHTS;
852 owner_default = ACL_ALL_RIGHTS_PARAMETER_ACL;
853 break;
854 default:
855 elog(ERROR, "unrecognized object type: %d", (int) objtype);
856 world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
857 owner_default = ACL_NO_RIGHTS;
858 break;
859 }
860
861 nacl = 0;
862 if (world_default != ACL_NO_RIGHTS)
863 nacl++;
864 if (owner_default != ACL_NO_RIGHTS)
865 nacl++;
866
867 acl = allocacl(nacl);
868 aip = ACL_DAT(acl);
869
870 if (world_default != ACL_NO_RIGHTS)
871 {
873 aip->ai_grantor = ownerId;
874 ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
875 aip++;
876 }
877
878 /*
879 * Note that the owner's entry shows all ordinary privileges but no grant
880 * options. This is because his grant options come "from the system" and
881 * not from his own efforts. (The SQL spec says that the owner's rights
882 * come from a "_SYSTEM" authid.) However, we do consider that the
883 * owner's ordinary privileges are self-granted; this lets him revoke
884 * them. We implement the owner's grant options without any explicit
885 * "_SYSTEM"-like ACL entry, by internally special-casing the owner
886 * wherever we are testing grant options.
887 */
888 if (owner_default != ACL_NO_RIGHTS)
889 {
890 aip->ai_grantee = ownerId;
891 aip->ai_grantor = ownerId;
892 ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
893 }
894
895 return acl;
896}
#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 543 of file acl.c.

544{
545 /* Check for cases where one or both are empty/null */
546 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
547 {
548 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
549 return true;
550 else
551 return false;
552 }
553 else
554 {
555 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
556 return false;
557 }
558
559 if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
560 return false;
561
562 if (memcmp(ACL_DAT(left_acl),
563 ACL_DAT(right_acl),
564 ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
565 return true;
566
567 return false;
568}

References ACL_DAT, and ACL_NUM.

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

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 529 of file acl.c.

530{
531 if (acl != NULL && ACL_NUM(acl) > 1)
532 qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
533}
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:708
#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 1372 of file acl.c.

1374{
1375 AclMode result;
1377 AclItem *aidat;
1378 int i,
1379 num;
1380
1381 /*
1382 * Null ACL should not happen, since caller should have inserted
1383 * appropriate default
1384 */
1385 if (acl == NULL)
1386 elog(ERROR, "null ACL");
1387
1388 check_acl(acl);
1389
1390 /* Quick exit for mask == 0 */
1391 if (mask == 0)
1392 return 0;
1393
1394 result = 0;
1395
1396 /* Owner always implicitly has all grant options */
1397 if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1398 has_privs_of_role(roleid, ownerId))
1399 {
1400 result = mask & ACLITEM_ALL_GOPTION_BITS;
1401 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1402 return result;
1403 }
1404
1405 num = ACL_NUM(acl);
1406 aidat = ACL_DAT(acl);
1407
1408 /*
1409 * Check privileges granted directly to roleid or to public
1410 */
1411 for (i = 0; i < num; i++)
1412 {
1413 AclItem *aidata = &aidat[i];
1414
1415 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1416 aidata->ai_grantee == roleid)
1417 {
1418 result |= aidata->ai_privs & mask;
1419 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1420 return result;
1421 }
1422 }
1423
1424 /*
1425 * Check privileges granted indirectly via role memberships. We do this in
1426 * a separate pass to minimize expensive indirect membership tests. In
1427 * particular, it's worth testing whether a given ACL entry grants any
1428 * privileges still of interest before we perform the has_privs_of_role
1429 * test.
1430 */
1431 remaining = mask & ~result;
1432 for (i = 0; i < num; i++)
1433 {
1434 AclItem *aidata = &aidat[i];
1435
1436 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1437 aidata->ai_grantee == roleid)
1438 continue; /* already checked it */
1439
1440 if ((aidata->ai_privs & remaining) &&
1441 has_privs_of_role(roleid, aidata->ai_grantee))
1442 {
1443 result |= aidata->ai_privs & mask;
1444 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1445 return result;
1446 remaining = mask & ~result;
1447 }
1448 }
1449
1450 return result;
1451}
static void check_acl(const Acl *acl)
Definition: acl.c:574
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:5268
#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 1524 of file acl.c.

1525{
1526 Oid *list;
1527 const AclItem *acldat;
1528 int i,
1529 j;
1530
1531 if (acl == NULL || ACL_NUM(acl) == 0)
1532 {
1533 *roleids = NULL;
1534 return 0;
1535 }
1536
1537 check_acl(acl);
1538
1539 /* Allocate the worst-case space requirement */
1540 list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1541 acldat = ACL_DAT(acl);
1542
1543 /*
1544 * Walk the ACL collecting mentioned RoleIds.
1545 */
1546 j = 0;
1547 for (i = 0; i < ACL_NUM(acl); i++)
1548 {
1549 const AclItem *ai = &acldat[i];
1550
1551 if (ai->ai_grantee != ACL_ID_PUBLIC)
1552 list[j++] = ai->ai_grantee;
1553 /* grantor is currently never PUBLIC, but let's check anyway */
1554 if (ai->ai_grantor != ACL_ID_PUBLIC)
1555 list[j++] = ai->ai_grantor;
1556 }
1557
1558 /* Sort the array */
1559 qsort(list, j, sizeof(Oid), oid_cmp);
1560
1561 /*
1562 * We could repalloc the array down to minimum size, but it's hardly worth
1563 * it since it's only transient memory.
1564 */
1565 *roleids = list;
1566
1567 /* Remove duplicates from the array */
1568 return qunique(list, j, sizeof(Oid), oid_cmp);
1569}
int j
Definition: isn.c:78
void * palloc(Size size)
Definition: mcxt.c:1317
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 485 of file acl.c.

486{
487 Acl *result_acl;
488 AclItem *aip;
489 int i,
490 num;
491
492 /* Check for cases where one or both are empty/null */
493 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
494 {
495 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
496 return NULL;
497 else
498 return aclcopy(right_acl);
499 }
500 else
501 {
502 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
503 return aclcopy(left_acl);
504 }
505
506 /* Merge them the hard way, one item at a time */
507 result_acl = aclcopy(left_acl);
508
509 aip = ACL_DAT(right_acl);
510 num = ACL_NUM(right_acl);
511
512 for (i = 0; i < num; i++, aip++)
513 {
514 Acl *tmp_acl;
515
516 tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
517 ownerId, DROP_RESTRICT);
518 pfree(result_acl);
519 result_acl = tmp_acl;
520 }
521
522 return result_acl;
523}
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:976
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:441
#define ACL_MODECHG_ADD
Definition: acl.h:129
void pfree(void *pointer)
Definition: mcxt.c:1524
@ DROP_RESTRICT
Definition: parsenodes.h:2390

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 1103 of file acl.c.

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

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 976 of file acl.c.

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

5326{
5327 if (!member_can_set_role(member, role))
5328 ereport(ERROR,
5329 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5330 errmsg("must be able to SET ROLE \"%s\"",
5331 GetUserNameFromId(role, false))));
5332}
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:5302
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:1039

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 5677 of file acl.c.

5678{
5679 if (!role)
5680 return;
5681
5682 if (role->roletype != ROLESPEC_CSTRING)
5683 return;
5684
5685 if (IsReservedName(role->rolename))
5686 {
5687 if (detail_msg)
5688 ereport(ERROR,
5689 (errcode(ERRCODE_RESERVED_NAME),
5690 errmsg("role name \"%s\" is reserved",
5691 role->rolename),
5692 errdetail_internal("%s", detail_msg)));
5693 else
5694 ereport(ERROR,
5695 (errcode(ERRCODE_RESERVED_NAME),
5696 errmsg("role name \"%s\" is reserved",
5697 role->rolename)));
5698 }
5699}
bool IsReservedName(const char *name)
Definition: catalog.c:247
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1231
@ ROLESPEC_CSTRING
Definition: parsenodes.h:405
RoleSpecType roletype
Definition: parsenodes.h:415
char * rolename
Definition: parsenodes.h:416

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

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

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

5537{
5538 Oid oid;
5539
5540 oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5542 if (!OidIsValid(oid) && !missing_ok)
5543 ereport(ERROR,
5544 (errcode(ERRCODE_UNDEFINED_OBJECT),
5545 errmsg("role \"%s\" does not exist", rolname)));
5546 return oid;
5547}
#define OidIsValid(objectId)
Definition: c.h:746
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
#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 5655 of file acl.c.

5656{
5657 HeapTuple tp;
5658 Form_pg_authid authForm;
5659 char *rolename;
5660
5661 tp = get_rolespec_tuple(role);
5662 authForm = (Form_pg_authid) GETSTRUCT(tp);
5663 rolename = pstrdup(NameStr(authForm->rolname));
5664 ReleaseSysCache(tp);
5665
5666 return rolename;
5667}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5609
#define NameStr(name)
Definition: c.h:717
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
char * pstrdup(const char *in)
Definition: mcxt.c:1699
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269

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 5570 of file acl.c.

5571{
5572 Oid oid;
5573
5574 switch (role->roletype)
5575 {
5576 case ROLESPEC_CSTRING:
5577 Assert(role->rolename);
5578 oid = get_role_oid(role->rolename, missing_ok);
5579 break;
5580
5583 oid = GetUserId();
5584 break;
5585
5587 oid = GetSessionUserId();
5588 break;
5589
5590 case ROLESPEC_PUBLIC:
5591 ereport(ERROR,
5592 (errcode(ERRCODE_UNDEFINED_OBJECT),
5593 errmsg("role \"%s\" does not exist", "public")));
5594 oid = InvalidOid; /* make compiler happy */
5595 break;
5596
5597 default:
5598 elog(ERROR, "unexpected role type %d", role->roletype);
5599 }
5600
5601 return oid;
5602}
Oid GetSessionUserId(void)
Definition: miscinit.c:559
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:407
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:408
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:406
#define InvalidOid
Definition: postgres_ext.h:35

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 5609 of file acl.c.

5610{
5611 HeapTuple tuple;
5612
5613 switch (role->roletype)
5614 {
5615 case ROLESPEC_CSTRING:
5616 Assert(role->rolename);
5617 tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5618 if (!HeapTupleIsValid(tuple))
5619 ereport(ERROR,
5620 (errcode(ERRCODE_UNDEFINED_OBJECT),
5621 errmsg("role \"%s\" does not exist", role->rolename)));
5622 break;
5623
5626 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5627 if (!HeapTupleIsValid(tuple))
5628 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5629 break;
5630
5633 if (!HeapTupleIsValid(tuple))
5634 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5635 break;
5636
5637 case ROLESPEC_PUBLIC:
5638 ereport(ERROR,
5639 (errcode(ERRCODE_UNDEFINED_OBJECT),
5640 errmsg("role \"%s\" does not exist", "public")));
5641 tuple = NULL; /* make compiler happy */
5642 break;
5643
5644 default:
5645 elog(ERROR, "unexpected role type %d", role->roletype);
5646 }
5647
5648 return tuple;
5649}
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

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

4233{
4234 Acl *result;
4235 Acl *glob_acl;
4236 Acl *schema_acl;
4237 Acl *def_acl;
4238 char defaclobjtype;
4239
4240 /*
4241 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4242 * yet.
4243 */
4245 return NULL;
4246
4247 /* Check if object type is supported in pg_default_acl */
4248 switch (objtype)
4249 {
4250 case OBJECT_TABLE:
4251 defaclobjtype = DEFACLOBJ_RELATION;
4252 break;
4253
4254 case OBJECT_SEQUENCE:
4255 defaclobjtype = DEFACLOBJ_SEQUENCE;
4256 break;
4257
4258 case OBJECT_FUNCTION:
4259 defaclobjtype = DEFACLOBJ_FUNCTION;
4260 break;
4261
4262 case OBJECT_TYPE:
4263 defaclobjtype = DEFACLOBJ_TYPE;
4264 break;
4265
4266 case OBJECT_SCHEMA:
4267 defaclobjtype = DEFACLOBJ_NAMESPACE;
4268 break;
4269
4270 case OBJECT_LARGEOBJECT:
4271 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4272 break;
4273
4274 default:
4275 return NULL;
4276 }
4277
4278 /* Look up the relevant pg_default_acl entries */
4279 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4280 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4281
4282 /* Quick out if neither entry exists */
4283 if (glob_acl == NULL && schema_acl == NULL)
4284 return NULL;
4285
4286 /* We need to know the hard-wired default value, too */
4287 def_acl = acldefault(objtype, ownerId);
4288
4289 /* If there's no global entry, substitute the hard-wired default */
4290 if (glob_acl == NULL)
4291 glob_acl = def_acl;
4292
4293 /* Merge in any per-schema privileges */
4294 result = aclmerge(glob_acl, schema_acl, ownerId);
4295
4296 /*
4297 * For efficiency, we want to return NULL if the result equals default.
4298 * This requires sorting both arrays to get an accurate comparison.
4299 */
4300 aclitemsort(result);
4301 aclitemsort(def_acl);
4302 if (aclequal(result, def_acl))
4303 result = NULL;
4304
4305 return result;
4306}
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:485
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:787
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:543
void aclitemsort(Acl *acl)
Definition: acl.c:529
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4197
#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 4173 of file aclchk.c.

4174{
4175 bool result = false;
4176 HeapTuple utup;
4177
4178 /* Superusers bypass all permission checking. */
4179 if (superuser_arg(roleid))
4180 return true;
4181
4182 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4183 if (HeapTupleIsValid(utup))
4184 {
4185 result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4186 ReleaseSysCache(utup);
4187 }
4188 return result;
4189}
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 4154 of file aclchk.c.

4155{
4156 bool result = false;
4157 HeapTuple utup;
4158
4159 /* Superusers bypass all permission checking. */
4160 if (superuser_arg(roleid))
4161 return true;
4162
4163 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4164 if (HeapTupleIsValid(utup))
4165 {
4166 result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4167 ReleaseSysCache(utup);
4168 }
4169 return result;
4170}
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 5268 of file acl.c.

5269{
5270 /* Fast path for simple case */
5271 if (member == role)
5272 return true;
5273
5274 /* Superusers have every privilege, so are part of every role */
5275 if (superuser_arg(member))
5276 return true;
5277
5278 /*
5279 * Find all the roles that member has the privileges of, including
5280 * multi-level recursion, then see if target role is any one of them.
5281 */
5283 InvalidOid, NULL),
5284 role);
5285}
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:5136
@ ROLERECURSE_PRIVS
Definition: acl.c:78
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(), 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(), standard_ProcessUtility(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 5024 of file acl.c.

5025{
5027 {
5029 GetSysCacheHashValue1(DATABASEOID,
5031
5032 /*
5033 * In normal mode, set a callback on any syscache invalidation of rows
5034 * of pg_auth_members (for roles_is_member_of()) pg_database (for
5035 * roles_is_member_of())
5036 */
5037 CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
5039 (Datum) 0);
5042 (Datum) 0);
5045 (Datum) 0);
5046 }
5047}
static uint32 cached_db_hash
Definition: acl.c:83
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:5054
Oid MyDatabaseId
Definition: globals.c:94
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1802
uintptr_t Datum
Definition: postgres.h:69
#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 5398 of file acl.c.

5399{
5400 Oid admin_role;
5401
5402 if (superuser_arg(member))
5403 return true;
5404
5405 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5406 if (member == role)
5407 return false;
5408
5409 (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5410 return OidIsValid(admin_role);
5411}
@ ROLERECURSE_MEMBERS
Definition: acl.c:77

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 5348 of file acl.c.

5349{
5350 /* Fast path for simple case */
5351 if (member == role)
5352 return true;
5353
5354 /* Superusers have every privilege, so are part of every role */
5355 if (superuser_arg(member))
5356 return true;
5357
5358 /*
5359 * Find all the roles that member is a member of, including multi-level
5360 * recursion, then see if target role is any one of them.
5361 */
5363 InvalidOid, NULL),
5364 role);
5365}

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 5376 of file acl.c.

5377{
5378 /* Fast path for simple case */
5379 if (member == role)
5380 return true;
5381
5382 /*
5383 * Find all the roles that member is a member of, including multi-level
5384 * recursion, then see if target role is any one of them.
5385 */
5387 InvalidOid, NULL),
5388 role);
5389}

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 432 of file acl.c.

433{
434 return allocacl(0);
435}

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 5302 of file acl.c.

5303{
5304 /* Fast path for simple case */
5305 if (member == role)
5306 return true;
5307
5308 /* Superusers have every privilege, so can always SET ROLE */
5309 if (superuser_arg(member))
5310 return true;
5311
5312 /*
5313 * Find all the roles that member can access via SET ROLE, including
5314 * multi-level recursion, then see if target role is any one of them.
5315 */
5317 InvalidOid, NULL),
5318 role);
5319}
@ ROLERECURSE_SETROLE
Definition: acl.c:79

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

3822{
3823 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3824}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3831
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 4075 of file aclchk.c.

4076{
4077 int cacheid;
4078 Oid ownerId;
4079
4080 /* Superusers bypass all permission checking. */
4081 if (superuser_arg(roleid))
4082 return true;
4083
4084 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4085 if (classid == LargeObjectRelationId)
4086 classid = LargeObjectMetadataRelationId;
4087
4088 cacheid = get_object_catcache_oid(classid);
4089 if (cacheid != -1)
4090 {
4091 /* we can get the object's tuple from the syscache */
4092 HeapTuple tuple;
4093
4094 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4095 if (!HeapTupleIsValid(tuple))
4096 elog(ERROR, "cache lookup failed for %s %u",
4097 get_object_class_descr(classid), objectid);
4098
4099 ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4100 tuple,
4101 get_object_attnum_owner(classid)));
4102 ReleaseSysCache(tuple);
4103 }
4104 else
4105 {
4106 /* for catalogs without an appropriate syscache */
4107 Relation rel;
4108 ScanKeyData entry[1];
4109 SysScanDesc scan;
4110 HeapTuple tuple;
4111 bool isnull;
4112
4113 rel = table_open(classid, AccessShareLock);
4114
4115 ScanKeyInit(&entry[0],
4116 get_object_attnum_oid(classid),
4117 BTEqualStrategyNumber, F_OIDEQ,
4118 ObjectIdGetDatum(objectid));
4119
4120 scan = systable_beginscan(rel,
4121 get_object_oid_index(classid), true,
4122 NULL, 1, entry);
4123
4124 tuple = systable_getnext(scan);
4125 if (!HeapTupleIsValid(tuple))
4126 elog(ERROR, "could not find tuple for %s %u",
4127 get_object_class_descr(classid), objectid);
4128
4129 ownerId = DatumGetObjectId(heap_getattr(tuple,
4130 get_object_attnum_owner(classid),
4131 RelationGetDescr(rel),
4132 &isnull));
4133 Assert(!isnull);
4134
4135 systable_endscan(scan);
4137 }
4138
4139 return has_privs_of_role(roleid, ownerId);
4140}
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:247
#define RelationGetDescr(relation)
Definition: rel.h:542
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:631
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 3853 of file aclchk.c.

3855{
3856 return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
3857}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3865
int16 attnum
Definition: pg_attribute.h:74

References attnum, mode, and pg_attribute_aclcheck_ext().

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

◆ pg_attribute_aclcheck_all()

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

Definition at line 3895 of file aclchk.c.

3897{
3898 return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3899}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3906

References mode, and pg_attribute_aclcheck_all_ext().

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

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

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

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

3867{
3868 if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3869 ACLMASK_ANY, is_missing) != 0)
3870 return ACLCHECK_OK;
3871 else
3872 return ACLCHECK_NO_PRIV;
3873}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3143

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

4036{
4037 if (pg_class_aclmask_ext(table_oid, roleid, mode,
4038 ACLMASK_ANY, is_missing) != 0)
4039 return ACLCHECK_OK;
4040 else
4041 return ACLCHECK_NO_PRIV;
4042}
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3267

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

3259{
3260 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3261}

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

4063{
4064 if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4065 ACLMASK_ANY, snapshot) != 0)
4066 return ACLCHECK_OK;
4067 else
4068 return ACLCHECK_NO_PRIV;
4069}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3520

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

4050{
4051 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4052 return ACLCHECK_OK;
4053 else
4054 return ACLCHECK_NO_PRIV;
4055}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3397
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 4312 of file aclchk.c.

4314{
4315 int nmembers;
4316 Oid *members;
4317
4318 /* Nothing to do if ACL is defaulted */
4319 if (acl == NULL)
4320 return;
4321
4322 /* Extract roles mentioned in ACL */
4323 nmembers = aclmembers(acl, &members);
4324
4325 /* Update the shared dependency ACL info */
4326 updateAclDependencies(classId, objectId, objsubId,
4327 ownerId,
4328 0, NULL,
4329 nmembers, members);
4330}
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1524
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 4339 of file aclchk.c.

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

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

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

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

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

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

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 5423 of file acl.c.

5424{
5425 Oid admin_role;
5426
5427 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5428 if (member == role)
5429 return InvalidOid;
5430
5431 (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5432 return admin_role;
5433}

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 5460 of file acl.c.

5463{
5464 AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5465 List *roles_list;
5466 int nrights;
5467 ListCell *l;
5468
5469 /*
5470 * The object owner is always treated as having all grant options, so if
5471 * roleId is the owner it's easy. Also, if roleId is a superuser it's
5472 * easy: superusers are implicitly members of every role, so they act as
5473 * the object owner.
5474 */
5475 if (roleId == ownerId || superuser_arg(roleId))
5476 {
5477 *grantorId = ownerId;
5478 *grantOptions = needed_goptions;
5479 return;
5480 }
5481
5482 /*
5483 * Otherwise we have to do a careful search to see if roleId has the
5484 * privileges of any suitable role. Note: we can hang onto the result of
5485 * roles_is_member_of() throughout this loop, because aclmask_direct()
5486 * doesn't query any role memberships.
5487 */
5488 roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5489 InvalidOid, NULL);
5490
5491 /* initialize candidate result as default */
5492 *grantorId = roleId;
5493 *grantOptions = ACL_NO_RIGHTS;
5494 nrights = 0;
5495
5496 foreach(l, roles_list)
5497 {
5498 Oid otherrole = lfirst_oid(l);
5499 AclMode otherprivs;
5500
5501 otherprivs = aclmask_direct(acl, otherrole, ownerId,
5502 needed_goptions, ACLMASK_ALL);
5503 if (otherprivs == needed_goptions)
5504 {
5505 /* Found a suitable grantor */
5506 *grantorId = otherrole;
5507 *grantOptions = otherprivs;
5508 return;
5509 }
5510
5511 /*
5512 * If it has just some of the needed privileges, remember best
5513 * candidate.
5514 */
5515 if (otherprivs != ACL_NO_RIGHTS)
5516 {
5517 int nnewrights = pg_popcount64(otherprivs);
5518
5519 if (nnewrights > nrights)
5520 {
5521 *grantorId = otherrole;
5522 *grantOptions = otherprivs;
5523 nrights = nnewrights;
5524 }
5525 }
5526 }
5527}
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1461
#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().