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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

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

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

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

Functions

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

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 171 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

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

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

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

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

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

Definition at line 76 of file acl.h.

◆ ACLITEM_SET_PRIVS

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

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

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

Definition at line 82 of file acl.h.

◆ ACLITEM_SET_RIGHTS

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

Definition at line 79 of file acl.h.

◆ DatumGetAclItemP

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

Definition at line 116 of file acl.h.

◆ DatumGetAclP

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

Definition at line 120 of file acl.h.

◆ DatumGetAclPCopy

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

Definition at line 121 of file acl.h.

◆ PG_GETARG_ACL_P

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

Definition at line 122 of file acl.h.

◆ PG_GETARG_ACL_P_COPY

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

Definition at line 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 117 of file acl.h.

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 124 of file acl.h.

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 118 of file acl.h.

Typedef Documentation

◆ Acl

typedef struct ArrayType Acl

Definition at line 106 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 174 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 181 of file acl.h.

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

Function Documentation

◆ aclcheck_error()

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

Definition at line 2622 of file aclchk.c.

2624{
2625 switch (aclerr)
2626 {
2627 case ACLCHECK_OK:
2628 /* no error, so return to caller */
2629 break;
2630 case ACLCHECK_NO_PRIV:
2631 {
2632 const char *msg = "???";
2633
2634 switch (objtype)
2635 {
2636 case OBJECT_AGGREGATE:
2637 msg = gettext_noop("permission denied for aggregate %s");
2638 break;
2639 case OBJECT_COLLATION:
2640 msg = gettext_noop("permission denied for collation %s");
2641 break;
2642 case OBJECT_COLUMN:
2643 msg = gettext_noop("permission denied for column %s");
2644 break;
2645 case OBJECT_CONVERSION:
2646 msg = gettext_noop("permission denied for conversion %s");
2647 break;
2648 case OBJECT_DATABASE:
2649 msg = gettext_noop("permission denied for database %s");
2650 break;
2651 case OBJECT_DOMAIN:
2652 msg = gettext_noop("permission denied for domain %s");
2653 break;
2655 msg = gettext_noop("permission denied for event trigger %s");
2656 break;
2657 case OBJECT_EXTENSION:
2658 msg = gettext_noop("permission denied for extension %s");
2659 break;
2660 case OBJECT_FDW:
2661 msg = gettext_noop("permission denied for foreign-data wrapper %s");
2662 break;
2664 msg = gettext_noop("permission denied for foreign server %s");
2665 break;
2667 msg = gettext_noop("permission denied for foreign table %s");
2668 break;
2669 case OBJECT_FUNCTION:
2670 msg = gettext_noop("permission denied for function %s");
2671 break;
2672 case OBJECT_INDEX:
2673 msg = gettext_noop("permission denied for index %s");
2674 break;
2675 case OBJECT_LANGUAGE:
2676 msg = gettext_noop("permission denied for language %s");
2677 break;
2678 case OBJECT_LARGEOBJECT:
2679 msg = gettext_noop("permission denied for large object %s");
2680 break;
2681 case OBJECT_MATVIEW:
2682 msg = gettext_noop("permission denied for materialized view %s");
2683 break;
2684 case OBJECT_OPCLASS:
2685 msg = gettext_noop("permission denied for operator class %s");
2686 break;
2687 case OBJECT_OPERATOR:
2688 msg = gettext_noop("permission denied for operator %s");
2689 break;
2690 case OBJECT_OPFAMILY:
2691 msg = gettext_noop("permission denied for operator family %s");
2692 break;
2694 msg = gettext_noop("permission denied for parameter %s");
2695 break;
2696 case OBJECT_POLICY:
2697 msg = gettext_noop("permission denied for policy %s");
2698 break;
2699 case OBJECT_PROCEDURE:
2700 msg = gettext_noop("permission denied for procedure %s");
2701 break;
2702 case OBJECT_PUBLICATION:
2703 msg = gettext_noop("permission denied for publication %s");
2704 break;
2705 case OBJECT_ROUTINE:
2706 msg = gettext_noop("permission denied for routine %s");
2707 break;
2708 case OBJECT_SCHEMA:
2709 msg = gettext_noop("permission denied for schema %s");
2710 break;
2711 case OBJECT_SEQUENCE:
2712 msg = gettext_noop("permission denied for sequence %s");
2713 break;
2715 msg = gettext_noop("permission denied for statistics object %s");
2716 break;
2718 msg = gettext_noop("permission denied for subscription %s");
2719 break;
2720 case OBJECT_TABLE:
2721 msg = gettext_noop("permission denied for table %s");
2722 break;
2723 case OBJECT_TABLESPACE:
2724 msg = gettext_noop("permission denied for tablespace %s");
2725 break;
2727 msg = gettext_noop("permission denied for text search configuration %s");
2728 break;
2730 msg = gettext_noop("permission denied for text search dictionary %s");
2731 break;
2732 case OBJECT_TYPE:
2733 msg = gettext_noop("permission denied for type %s");
2734 break;
2735 case OBJECT_VIEW:
2736 msg = gettext_noop("permission denied for view %s");
2737 break;
2738 /* these currently aren't used */
2740 case OBJECT_AMOP:
2741 case OBJECT_AMPROC:
2742 case OBJECT_ATTRIBUTE:
2743 case OBJECT_CAST:
2744 case OBJECT_DEFAULT:
2745 case OBJECT_DEFACL:
2749 case OBJECT_ROLE:
2750 case OBJECT_RULE:
2752 case OBJECT_TRANSFORM:
2753 case OBJECT_TRIGGER:
2754 case OBJECT_TSPARSER:
2755 case OBJECT_TSTEMPLATE:
2757 elog(ERROR, "unsupported object type: %d", objtype);
2758 }
2759
2760 ereport(ERROR,
2761 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2762 errmsg(msg, objectname)));
2763 break;
2764 }
2765 case ACLCHECK_NOT_OWNER:
2766 {
2767 const char *msg = "???";
2768
2769 switch (objtype)
2770 {
2771 case OBJECT_AGGREGATE:
2772 msg = gettext_noop("must be owner of aggregate %s");
2773 break;
2774 case OBJECT_COLLATION:
2775 msg = gettext_noop("must be owner of collation %s");
2776 break;
2777 case OBJECT_CONVERSION:
2778 msg = gettext_noop("must be owner of conversion %s");
2779 break;
2780 case OBJECT_DATABASE:
2781 msg = gettext_noop("must be owner of database %s");
2782 break;
2783 case OBJECT_DOMAIN:
2784 msg = gettext_noop("must be owner of domain %s");
2785 break;
2787 msg = gettext_noop("must be owner of event trigger %s");
2788 break;
2789 case OBJECT_EXTENSION:
2790 msg = gettext_noop("must be owner of extension %s");
2791 break;
2792 case OBJECT_FDW:
2793 msg = gettext_noop("must be owner of foreign-data wrapper %s");
2794 break;
2796 msg = gettext_noop("must be owner of foreign server %s");
2797 break;
2799 msg = gettext_noop("must be owner of foreign table %s");
2800 break;
2801 case OBJECT_FUNCTION:
2802 msg = gettext_noop("must be owner of function %s");
2803 break;
2804 case OBJECT_INDEX:
2805 msg = gettext_noop("must be owner of index %s");
2806 break;
2807 case OBJECT_LANGUAGE:
2808 msg = gettext_noop("must be owner of language %s");
2809 break;
2810 case OBJECT_LARGEOBJECT:
2811 msg = gettext_noop("must be owner of large object %s");
2812 break;
2813 case OBJECT_MATVIEW:
2814 msg = gettext_noop("must be owner of materialized view %s");
2815 break;
2816 case OBJECT_OPCLASS:
2817 msg = gettext_noop("must be owner of operator class %s");
2818 break;
2819 case OBJECT_OPERATOR:
2820 msg = gettext_noop("must be owner of operator %s");
2821 break;
2822 case OBJECT_OPFAMILY:
2823 msg = gettext_noop("must be owner of operator family %s");
2824 break;
2825 case OBJECT_PROCEDURE:
2826 msg = gettext_noop("must be owner of procedure %s");
2827 break;
2828 case OBJECT_PUBLICATION:
2829 msg = gettext_noop("must be owner of publication %s");
2830 break;
2831 case OBJECT_ROUTINE:
2832 msg = gettext_noop("must be owner of routine %s");
2833 break;
2834 case OBJECT_SEQUENCE:
2835 msg = gettext_noop("must be owner of sequence %s");
2836 break;
2838 msg = gettext_noop("must be owner of subscription %s");
2839 break;
2840 case OBJECT_TABLE:
2841 msg = gettext_noop("must be owner of table %s");
2842 break;
2843 case OBJECT_TYPE:
2844 msg = gettext_noop("must be owner of type %s");
2845 break;
2846 case OBJECT_VIEW:
2847 msg = gettext_noop("must be owner of view %s");
2848 break;
2849 case OBJECT_SCHEMA:
2850 msg = gettext_noop("must be owner of schema %s");
2851 break;
2853 msg = gettext_noop("must be owner of statistics object %s");
2854 break;
2855 case OBJECT_TABLESPACE:
2856 msg = gettext_noop("must be owner of tablespace %s");
2857 break;
2859 msg = gettext_noop("must be owner of text search configuration %s");
2860 break;
2862 msg = gettext_noop("must be owner of text search dictionary %s");
2863 break;
2864
2865 /*
2866 * Special cases: For these, the error message talks
2867 * about "relation", because that's where the
2868 * ownership is attached. See also
2869 * check_object_ownership().
2870 */
2871 case OBJECT_COLUMN:
2872 case OBJECT_POLICY:
2873 case OBJECT_RULE:
2875 case OBJECT_TRIGGER:
2876 msg = gettext_noop("must be owner of relation %s");
2877 break;
2878 /* these currently aren't used */
2880 case OBJECT_AMOP:
2881 case OBJECT_AMPROC:
2882 case OBJECT_ATTRIBUTE:
2883 case OBJECT_CAST:
2884 case OBJECT_DEFAULT:
2885 case OBJECT_DEFACL:
2890 case OBJECT_ROLE:
2891 case OBJECT_TRANSFORM:
2892 case OBJECT_TSPARSER:
2893 case OBJECT_TSTEMPLATE:
2895 elog(ERROR, "unsupported object type: %d", objtype);
2896 }
2897
2898 ereport(ERROR,
2899 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2900 errmsg(msg, objectname)));
2901 break;
2902 }
2903 default:
2904 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2905 break;
2906 }
2907}
#define gettext_noop(x)
Definition: c.h:1153
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:2326
@ OBJECT_FDW
Definition: parsenodes.h:2328
@ OBJECT_TSPARSER
Definition: parsenodes.h:2359
@ OBJECT_COLLATION
Definition: parsenodes.h:2319
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:2362
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:2312
@ OBJECT_OPCLASS
Definition: parsenodes.h:2336
@ OBJECT_DEFACL
Definition: parsenodes.h:2323
@ OBJECT_AGGREGATE
Definition: parsenodes.h:2313
@ OBJECT_MATVIEW
Definition: parsenodes.h:2335
@ OBJECT_SCHEMA
Definition: parsenodes.h:2348
@ OBJECT_POLICY
Definition: parsenodes.h:2340
@ OBJECT_OPERATOR
Definition: parsenodes.h:2337
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:2330
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:2357
@ OBJECT_OPFAMILY
Definition: parsenodes.h:2338
@ OBJECT_DOMAIN
Definition: parsenodes.h:2324
@ OBJECT_COLUMN
Definition: parsenodes.h:2318
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2354
@ OBJECT_ROLE
Definition: parsenodes.h:2345
@ OBJECT_ROUTINE
Definition: parsenodes.h:2346
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:2334
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:2343
@ OBJECT_PROCEDURE
Definition: parsenodes.h:2341
@ OBJECT_EXTENSION
Definition: parsenodes.h:2327
@ OBJECT_INDEX
Definition: parsenodes.h:2332
@ OBJECT_DEFAULT
Definition: parsenodes.h:2322
@ OBJECT_DATABASE
Definition: parsenodes.h:2321
@ OBJECT_SEQUENCE
Definition: parsenodes.h:2349
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:2360
@ OBJECT_LANGUAGE
Definition: parsenodes.h:2333
@ OBJECT_AMOP
Definition: parsenodes.h:2314
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:2344
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:2329
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:2358
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:2316
@ OBJECT_PUBLICATION
Definition: parsenodes.h:2342
@ OBJECT_RULE
Definition: parsenodes.h:2347
@ OBJECT_CONVERSION
Definition: parsenodes.h:2320
@ OBJECT_AMPROC
Definition: parsenodes.h:2315
@ OBJECT_TABLE
Definition: parsenodes.h:2353
@ OBJECT_VIEW
Definition: parsenodes.h:2363
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:2339
@ OBJECT_TYPE
Definition: parsenodes.h:2361
@ OBJECT_FUNCTION
Definition: parsenodes.h:2331
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:2352
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:2325
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:2350
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:2351
@ OBJECT_CAST
Definition: parsenodes.h:2317
@ OBJECT_TRIGGER
Definition: parsenodes.h:2356
@ OBJECT_TRANSFORM
Definition: parsenodes.h:2355

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

2913{
2914 switch (aclerr)
2915 {
2916 case ACLCHECK_OK:
2917 /* no error, so return to caller */
2918 break;
2919 case ACLCHECK_NO_PRIV:
2920 ereport(ERROR,
2921 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2922 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2923 colname, objectname)));
2924 break;
2925 case ACLCHECK_NOT_OWNER:
2926 /* relation msg is OK since columns don't have separate owners */
2927 aclcheck_error(aclerr, objtype, objectname);
2928 break;
2929 default:
2930 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2931 break;
2932 }
2933}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2622

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

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:72
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:73
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:1521
@ DROP_RESTRICT
Definition: parsenodes.h:2385

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
#define Assert(condition)
Definition: c.h:815

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

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

5696{
5697 if (!role)
5698 return;
5699
5700 if (role->roletype != ROLESPEC_CSTRING)
5701 return;
5702
5703 if (IsReservedName(role->rolename))
5704 {
5705 if (detail_msg)
5706 ereport(ERROR,
5707 (errcode(ERRCODE_RESERVED_NAME),
5708 errmsg("role name \"%s\" is reserved",
5709 role->rolename),
5710 errdetail_internal("%s", detail_msg)));
5711 else
5712 ereport(ERROR,
5713 (errcode(ERRCODE_RESERVED_NAME),
5714 errmsg("role name \"%s\" is reserved",
5715 role->rolename)));
5716 }
5717}
bool IsReservedName(const char *name)
Definition: catalog.c:247
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
@ 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 default:
1009 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1010 (int) action->objtype);
1011 /* keep compiler quiet */
1012 all_privileges = ACL_NO_RIGHTS;
1013 errormsg = NULL;
1014 }
1015
1016 if (action->privileges == NIL)
1017 {
1018 iacls.all_privs = true;
1019
1020 /*
1021 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1022 * depending on the object type
1023 */
1024 iacls.privileges = ACL_NO_RIGHTS;
1025 }
1026 else
1027 {
1028 iacls.all_privs = false;
1029 iacls.privileges = ACL_NO_RIGHTS;
1030
1031 foreach(cell, action->privileges)
1032 {
1033 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1034 AclMode priv;
1035
1036 if (privnode->cols)
1037 ereport(ERROR,
1038 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1039 errmsg("default privileges cannot be set for columns")));
1040
1041 if (privnode->priv_name == NULL) /* parser mistake? */
1042 elog(ERROR, "AccessPriv node must specify privilege");
1043 priv = string_to_privilege(privnode->priv_name);
1044
1045 if (priv & ~((AclMode) all_privileges))
1046 ereport(ERROR,
1047 (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1048 errmsg(errormsg, privilege_to_string(priv))));
1049
1050 iacls.privileges |= priv;
1051 }
1052 }
1053
1054 if (rolespecs == NIL)
1055 {
1056 /* Set permissions for myself */
1057 iacls.roleid = GetUserId();
1058
1059 SetDefaultACLsInSchemas(&iacls, nspnames);
1060 }
1061 else
1062 {
1063 /* Look up the role OIDs and do permissions checks */
1064 ListCell *rolecell;
1065
1066 foreach(rolecell, rolespecs)
1067 {
1068 RoleSpec *rolespec = lfirst(rolecell);
1069
1070 iacls.roleid = get_rolespec_oid(rolespec, false);
1071
1072 if (!has_privs_of_role(GetUserId(), iacls.roleid))
1073 ereport(ERROR,
1074 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1075 errmsg("permission denied to change default privileges")));
1076
1077 SetDefaultACLsInSchemas(&iacls, nspnames);
1078 }
1079 }
1080}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5588
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:2534
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1088
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:2575
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:76
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
Oid GetUserId(void)
Definition: miscinit.c:517
@ 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:2596
List * cols
Definition: parsenodes.h:2597
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_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_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:2539
@ ACL_TARGET_ALL_IN_SCHEMA
Definition: parsenodes.h:2540
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 5554 of file acl.c.

5555{
5556 Oid oid;
5557
5558 oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5560 if (!OidIsValid(oid) && !missing_ok)
5561 ereport(ERROR,
5562 (errcode(ERRCODE_UNDEFINED_OBJECT),
5563 errmsg("role \"%s\" does not exist", rolname)));
5564 return oid;
5565}
#define OidIsValid(objectId)
Definition: c.h:732
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 5673 of file acl.c.

5674{
5675 HeapTuple tp;
5676 Form_pg_authid authForm;
5677 char *rolename;
5678
5679 tp = get_rolespec_tuple(role);
5680 authForm = (Form_pg_authid) GETSTRUCT(tp);
5681 rolename = pstrdup(NameStr(authForm->rolname));
5682 ReleaseSysCache(tp);
5683
5684 return rolename;
5685}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5627
#define NameStr(name)
Definition: c.h:703
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * pstrdup(const char *in)
Definition: mcxt.c:1696
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 5588 of file acl.c.

5589{
5590 Oid oid;
5591
5592 switch (role->roletype)
5593 {
5594 case ROLESPEC_CSTRING:
5595 Assert(role->rolename);
5596 oid = get_role_oid(role->rolename, missing_ok);
5597 break;
5598
5601 oid = GetUserId();
5602 break;
5603
5605 oid = GetSessionUserId();
5606 break;
5607
5608 case ROLESPEC_PUBLIC:
5609 ereport(ERROR,
5610 (errcode(ERRCODE_UNDEFINED_OBJECT),
5611 errmsg("role \"%s\" does not exist", "public")));
5612 oid = InvalidOid; /* make compiler happy */
5613 break;
5614
5615 default:
5616 elog(ERROR, "unexpected role type %d", role->roletype);
5617 }
5618
5619 return oid;
5620}
Oid GetSessionUserId(void)
Definition: miscinit.c:556
@ 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:37

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

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

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)

Definition at line 5627 of file acl.c.

5628{
5629 HeapTuple tuple;
5630
5631 switch (role->roletype)
5632 {
5633 case ROLESPEC_CSTRING:
5634 Assert(role->rolename);
5635 tuple = SearchSysCache1(AUTHNAME, CStringGetDatum(role->rolename));
5636 if (!HeapTupleIsValid(tuple))
5637 ereport(ERROR,
5638 (errcode(ERRCODE_UNDEFINED_OBJECT),
5639 errmsg("role \"%s\" does not exist", role->rolename)));
5640 break;
5641
5644 tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
5645 if (!HeapTupleIsValid(tuple))
5646 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5647 break;
5648
5651 if (!HeapTupleIsValid(tuple))
5652 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5653 break;
5654
5655 case ROLESPEC_PUBLIC:
5656 ereport(ERROR,
5657 (errcode(ERRCODE_UNDEFINED_OBJECT),
5658 errmsg("role \"%s\" does not exist", "public")));
5659 tuple = NULL; /* make compiler happy */
5660 break;
5661
5662 default:
5663 elog(ERROR, "unexpected role type %d", role->roletype);
5664 }
5665
5666 return tuple;
5667}
#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 4215 of file aclchk.c.

4216{
4217 Acl *result;
4218 Acl *glob_acl;
4219 Acl *schema_acl;
4220 Acl *def_acl;
4221 char defaclobjtype;
4222
4223 /*
4224 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4225 * yet.
4226 */
4228 return NULL;
4229
4230 /* Check if object type is supported in pg_default_acl */
4231 switch (objtype)
4232 {
4233 case OBJECT_TABLE:
4234 defaclobjtype = DEFACLOBJ_RELATION;
4235 break;
4236
4237 case OBJECT_SEQUENCE:
4238 defaclobjtype = DEFACLOBJ_SEQUENCE;
4239 break;
4240
4241 case OBJECT_FUNCTION:
4242 defaclobjtype = DEFACLOBJ_FUNCTION;
4243 break;
4244
4245 case OBJECT_TYPE:
4246 defaclobjtype = DEFACLOBJ_TYPE;
4247 break;
4248
4249 case OBJECT_SCHEMA:
4250 defaclobjtype = DEFACLOBJ_NAMESPACE;
4251 break;
4252
4253 default:
4254 return NULL;
4255 }
4256
4257 /* Look up the relevant pg_default_acl entries */
4258 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4259 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4260
4261 /* Quick out if neither entry exists */
4262 if (glob_acl == NULL && schema_acl == NULL)
4263 return NULL;
4264
4265 /* We need to know the hard-wired default value, too */
4266 def_acl = acldefault(objtype, ownerId);
4267
4268 /* If there's no global entry, substitute the hard-wired default */
4269 if (glob_acl == NULL)
4270 glob_acl = def_acl;
4271
4272 /* Merge in any per-schema privileges */
4273 result = aclmerge(glob_acl, schema_acl, ownerId);
4274
4275 /*
4276 * For efficiency, we want to return NULL if the result equals default.
4277 * This requires sorting both arrays to get an accurate comparison.
4278 */
4279 aclitemsort(result);
4280 aclitemsort(def_acl);
4281 if (aclequal(result, def_acl))
4282 result = NULL;
4283
4284 return result;
4285}
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:4180
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:466

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 4156 of file aclchk.c.

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

4138{
4139 bool result = false;
4140 HeapTuple utup;
4141
4142 /* Superusers bypass all permission checking. */
4143 if (superuser_arg(roleid))
4144 return true;
4145
4146 utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4147 if (HeapTupleIsValid(utup))
4148 {
4149 result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4150 ReleaseSysCache(utup);
4151 }
4152 return result;
4153}
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:93
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1704
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 3804 of file aclchk.c.

3805{
3806 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3807}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:3814
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 4058 of file aclchk.c.

4059{
4060 int cacheid;
4061 Oid ownerId;
4062
4063 /* Superusers bypass all permission checking. */
4064 if (superuser_arg(roleid))
4065 return true;
4066
4067 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4068 if (classid == LargeObjectRelationId)
4069 classid = LargeObjectMetadataRelationId;
4070
4071 cacheid = get_object_catcache_oid(classid);
4072 if (cacheid != -1)
4073 {
4074 /* we can get the object's tuple from the syscache */
4075 HeapTuple tuple;
4076
4077 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4078 if (!HeapTupleIsValid(tuple))
4079 elog(ERROR, "cache lookup failed for %s %u",
4080 get_object_class_descr(classid), objectid);
4081
4082 ownerId = DatumGetObjectId(SysCacheGetAttrNotNull(cacheid,
4083 tuple,
4084 get_object_attnum_owner(classid)));
4085 ReleaseSysCache(tuple);
4086 }
4087 else
4088 {
4089 /* for catalogs without an appropriate syscache */
4090 Relation rel;
4091 ScanKeyData entry[1];
4092 SysScanDesc scan;
4093 HeapTuple tuple;
4094 bool isnull;
4095
4096 rel = table_open(classid, AccessShareLock);
4097
4098 ScanKeyInit(&entry[0],
4099 get_object_attnum_oid(classid),
4100 BTEqualStrategyNumber, F_OIDEQ,
4101 ObjectIdGetDatum(objectid));
4102
4103 scan = systable_beginscan(rel,
4104 get_object_oid_index(classid), true,
4105 NULL, 1, entry);
4106
4107 tuple = systable_getnext(scan);
4108 if (!HeapTupleIsValid(tuple))
4109 elog(ERROR, "could not find tuple for %s %u",
4110 get_object_class_descr(classid), objectid);
4111
4112 ownerId = DatumGetObjectId(heap_getattr(tuple,
4113 get_object_attnum_owner(classid),
4114 RelationGetDescr(rel),
4115 &isnull));
4116 Assert(!isnull);
4117
4118 systable_endscan(scan);
4120 }
4121
4122 return has_privs_of_role(roleid, ownerId);
4123}
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:606
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:513
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#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:531
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 3836 of file aclchk.c.

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

3880{
3881 return pg_attribute_aclcheck_all_ext(table_oid, roleid, mode, how, NULL);
3882}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3889

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

3892{
3893 AclResult result;
3894 HeapTuple classTuple;
3895 Form_pg_class classForm;
3896 Oid ownerId;
3897 AttrNumber nattrs;
3898 AttrNumber curr_att;
3899
3900 /*
3901 * Must fetch pg_class row to get owner ID and number of attributes.
3902 */
3903 classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
3904 if (!HeapTupleIsValid(classTuple))
3905 {
3906 if (is_missing != NULL)
3907 {
3908 /* return "no privileges" instead of throwing an error */
3909 *is_missing = true;
3910 return ACLCHECK_NO_PRIV;
3911 }
3912 else
3913 ereport(ERROR,
3915 errmsg("relation with OID %u does not exist",
3916 table_oid)));
3917 }
3918 classForm = (Form_pg_class) GETSTRUCT(classTuple);
3919
3920 ownerId = classForm->relowner;
3921 nattrs = classForm->relnatts;
3922
3923 ReleaseSysCache(classTuple);
3924
3925 /*
3926 * Initialize result in case there are no non-dropped columns. We want to
3927 * report failure in such cases for either value of 'how'.
3928 */
3929 result = ACLCHECK_NO_PRIV;
3930
3931 for (curr_att = 1; curr_att <= nattrs; curr_att++)
3932 {
3933 HeapTuple attTuple;
3934 Datum aclDatum;
3935 bool isNull;
3936 Acl *acl;
3937 AclMode attmask;
3938
3939 attTuple = SearchSysCache2(ATTNUM,
3940 ObjectIdGetDatum(table_oid),
3941 Int16GetDatum(curr_att));
3942
3943 /*
3944 * Lookup failure probably indicates that the table was just dropped,
3945 * but we'll treat it the same as a dropped column rather than
3946 * throwing error.
3947 */
3948 if (!HeapTupleIsValid(attTuple))
3949 continue;
3950
3951 /* ignore dropped columns */
3952 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
3953 {
3954 ReleaseSysCache(attTuple);
3955 continue;
3956 }
3957
3958 aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl,
3959 &isNull);
3960
3961 /*
3962 * Here we hard-wire knowledge that the default ACL for a column
3963 * grants no privileges, so that we can fall out quickly in the very
3964 * common case where attacl is null.
3965 */
3966 if (isNull)
3967 attmask = 0;
3968 else
3969 {
3970 /* detoast column's ACL if necessary */
3971 acl = DatumGetAclP(aclDatum);
3972
3973 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
3974
3975 /* if we have a detoasted copy, free it */
3976 if ((Pointer) acl != DatumGetPointer(aclDatum))
3977 pfree(acl);
3978 }
3979
3980 ReleaseSysCache(attTuple);
3981
3982 if (attmask != 0)
3983 {
3984 result = ACLCHECK_OK;
3985 if (how == ACLMASK_ANY)
3986 break; /* succeed on any success */
3987 }
3988 else
3989 {
3990 result = ACLCHECK_NO_PRIV;
3991 if (how == ACLMASK_ALL)
3992 break; /* fail on any failure */
3993 }
3994 }
3995
3996 return result;
3997}
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:479
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
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 3848 of file aclchk.c.

3850{
3851 if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
3852 ACLMASK_ANY, is_missing) != 0)
3853 return ACLCHECK_OK;
3854 else
3855 return ACLCHECK_NO_PRIV;
3856}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3126

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

4019{
4020 if (pg_class_aclmask_ext(table_oid, roleid, mode,
4021 ACLMASK_ANY, is_missing) != 0)
4022 return ACLCHECK_OK;
4023 else
4024 return ACLCHECK_NO_PRIV;
4025}
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3250

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

3242{
3243 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3244}

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

4046{
4047 if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4048 ACLMASK_ANY, snapshot) != 0)
4049 return ACLCHECK_OK;
4050 else
4051 return ACLCHECK_NO_PRIV;
4052}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:3503

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

4033{
4034 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4035 return ACLCHECK_OK;
4036 else
4037 return ACLCHECK_NO_PRIV;
4038}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3380
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 4291 of file aclchk.c.

4293{
4294 int nmembers;
4295 Oid *members;
4296
4297 /* Nothing to do if ACL is defaulted */
4298 if (acl == NULL)
4299 return;
4300
4301 /* Extract roles mentioned in ACL */
4302 nmembers = aclmembers(acl, &members);
4303
4304 /* Update the shared dependency ACL info */
4305 updateAclDependencies(classId, objectId, objsubId,
4306 ownerId,
4307 0, NULL,
4308 nmembers, members);
4309}
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(), NamespaceCreate(), and ProcedureCreate().

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4318 of file aclchk.c.

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

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

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

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

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

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

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

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

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

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