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_VACUUM_CHR   'v'
 
#define ACL_ANALYZE_CHR   'z'
 
#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAvz"
 
#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_VACUUM|ACL_ANALYZE)
 
#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 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_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)
 
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 160 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAvz"

Definition at line 155 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 171 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 172 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_ANALYZE_CHR

#define ACL_ANALYZE_CHR   'z'

Definition at line 152 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_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.

◆ ACL_VACUUM_CHR

#define ACL_VACUUM_CHR   'v'

Definition at line 151 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:81

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 1 of file acl.h.

◆ AclItem

typedef struct AclItem AclItem

Enumeration Type Documentation

◆ AclMaskHow

enum AclMaskHow
Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 175 of file acl.h.

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

◆ AclResult

enum AclResult
Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 182 of file acl.h.

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

Function Documentation

◆ aclcheck_error()

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

Definition at line 3485 of file aclchk.c.

3487 {
3488  switch (aclerr)
3489  {
3490  case ACLCHECK_OK:
3491  /* no error, so return to caller */
3492  break;
3493  case ACLCHECK_NO_PRIV:
3494  {
3495  const char *msg = "???";
3496 
3497  switch (objtype)
3498  {
3499  case OBJECT_AGGREGATE:
3500  msg = gettext_noop("permission denied for aggregate %s");
3501  break;
3502  case OBJECT_COLLATION:
3503  msg = gettext_noop("permission denied for collation %s");
3504  break;
3505  case OBJECT_COLUMN:
3506  msg = gettext_noop("permission denied for column %s");
3507  break;
3508  case OBJECT_CONVERSION:
3509  msg = gettext_noop("permission denied for conversion %s");
3510  break;
3511  case OBJECT_DATABASE:
3512  msg = gettext_noop("permission denied for database %s");
3513  break;
3514  case OBJECT_DOMAIN:
3515  msg = gettext_noop("permission denied for domain %s");
3516  break;
3517  case OBJECT_EVENT_TRIGGER:
3518  msg = gettext_noop("permission denied for event trigger %s");
3519  break;
3520  case OBJECT_EXTENSION:
3521  msg = gettext_noop("permission denied for extension %s");
3522  break;
3523  case OBJECT_FDW:
3524  msg = gettext_noop("permission denied for foreign-data wrapper %s");
3525  break;
3526  case OBJECT_FOREIGN_SERVER:
3527  msg = gettext_noop("permission denied for foreign server %s");
3528  break;
3529  case OBJECT_FOREIGN_TABLE:
3530  msg = gettext_noop("permission denied for foreign table %s");
3531  break;
3532  case OBJECT_FUNCTION:
3533  msg = gettext_noop("permission denied for function %s");
3534  break;
3535  case OBJECT_INDEX:
3536  msg = gettext_noop("permission denied for index %s");
3537  break;
3538  case OBJECT_LANGUAGE:
3539  msg = gettext_noop("permission denied for language %s");
3540  break;
3541  case OBJECT_LARGEOBJECT:
3542  msg = gettext_noop("permission denied for large object %s");
3543  break;
3544  case OBJECT_MATVIEW:
3545  msg = gettext_noop("permission denied for materialized view %s");
3546  break;
3547  case OBJECT_OPCLASS:
3548  msg = gettext_noop("permission denied for operator class %s");
3549  break;
3550  case OBJECT_OPERATOR:
3551  msg = gettext_noop("permission denied for operator %s");
3552  break;
3553  case OBJECT_OPFAMILY:
3554  msg = gettext_noop("permission denied for operator family %s");
3555  break;
3556  case OBJECT_PARAMETER_ACL:
3557  msg = gettext_noop("permission denied for parameter %s");
3558  break;
3559  case OBJECT_POLICY:
3560  msg = gettext_noop("permission denied for policy %s");
3561  break;
3562  case OBJECT_PROCEDURE:
3563  msg = gettext_noop("permission denied for procedure %s");
3564  break;
3565  case OBJECT_PUBLICATION:
3566  msg = gettext_noop("permission denied for publication %s");
3567  break;
3568  case OBJECT_ROUTINE:
3569  msg = gettext_noop("permission denied for routine %s");
3570  break;
3571  case OBJECT_SCHEMA:
3572  msg = gettext_noop("permission denied for schema %s");
3573  break;
3574  case OBJECT_SEQUENCE:
3575  msg = gettext_noop("permission denied for sequence %s");
3576  break;
3577  case OBJECT_STATISTIC_EXT:
3578  msg = gettext_noop("permission denied for statistics object %s");
3579  break;
3580  case OBJECT_SUBSCRIPTION:
3581  msg = gettext_noop("permission denied for subscription %s");
3582  break;
3583  case OBJECT_TABLE:
3584  msg = gettext_noop("permission denied for table %s");
3585  break;
3586  case OBJECT_TABLESPACE:
3587  msg = gettext_noop("permission denied for tablespace %s");
3588  break;
3590  msg = gettext_noop("permission denied for text search configuration %s");
3591  break;
3592  case OBJECT_TSDICTIONARY:
3593  msg = gettext_noop("permission denied for text search dictionary %s");
3594  break;
3595  case OBJECT_TYPE:
3596  msg = gettext_noop("permission denied for type %s");
3597  break;
3598  case OBJECT_VIEW:
3599  msg = gettext_noop("permission denied for view %s");
3600  break;
3601  /* these currently aren't used */
3602  case OBJECT_ACCESS_METHOD:
3603  case OBJECT_AMOP:
3604  case OBJECT_AMPROC:
3605  case OBJECT_ATTRIBUTE:
3606  case OBJECT_CAST:
3607  case OBJECT_DEFAULT:
3608  case OBJECT_DEFACL:
3609  case OBJECT_DOMCONSTRAINT:
3612  case OBJECT_ROLE:
3613  case OBJECT_RULE:
3614  case OBJECT_TABCONSTRAINT:
3615  case OBJECT_TRANSFORM:
3616  case OBJECT_TRIGGER:
3617  case OBJECT_TSPARSER:
3618  case OBJECT_TSTEMPLATE:
3619  case OBJECT_USER_MAPPING:
3620  elog(ERROR, "unsupported object type: %d", objtype);
3621  }
3622 
3623  ereport(ERROR,
3624  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3625  errmsg(msg, objectname)));
3626  break;
3627  }
3628  case ACLCHECK_NOT_OWNER:
3629  {
3630  const char *msg = "???";
3631 
3632  switch (objtype)
3633  {
3634  case OBJECT_AGGREGATE:
3635  msg = gettext_noop("must be owner of aggregate %s");
3636  break;
3637  case OBJECT_COLLATION:
3638  msg = gettext_noop("must be owner of collation %s");
3639  break;
3640  case OBJECT_CONVERSION:
3641  msg = gettext_noop("must be owner of conversion %s");
3642  break;
3643  case OBJECT_DATABASE:
3644  msg = gettext_noop("must be owner of database %s");
3645  break;
3646  case OBJECT_DOMAIN:
3647  msg = gettext_noop("must be owner of domain %s");
3648  break;
3649  case OBJECT_EVENT_TRIGGER:
3650  msg = gettext_noop("must be owner of event trigger %s");
3651  break;
3652  case OBJECT_EXTENSION:
3653  msg = gettext_noop("must be owner of extension %s");
3654  break;
3655  case OBJECT_FDW:
3656  msg = gettext_noop("must be owner of foreign-data wrapper %s");
3657  break;
3658  case OBJECT_FOREIGN_SERVER:
3659  msg = gettext_noop("must be owner of foreign server %s");
3660  break;
3661  case OBJECT_FOREIGN_TABLE:
3662  msg = gettext_noop("must be owner of foreign table %s");
3663  break;
3664  case OBJECT_FUNCTION:
3665  msg = gettext_noop("must be owner of function %s");
3666  break;
3667  case OBJECT_INDEX:
3668  msg = gettext_noop("must be owner of index %s");
3669  break;
3670  case OBJECT_LANGUAGE:
3671  msg = gettext_noop("must be owner of language %s");
3672  break;
3673  case OBJECT_LARGEOBJECT:
3674  msg = gettext_noop("must be owner of large object %s");
3675  break;
3676  case OBJECT_MATVIEW:
3677  msg = gettext_noop("must be owner of materialized view %s");
3678  break;
3679  case OBJECT_OPCLASS:
3680  msg = gettext_noop("must be owner of operator class %s");
3681  break;
3682  case OBJECT_OPERATOR:
3683  msg = gettext_noop("must be owner of operator %s");
3684  break;
3685  case OBJECT_OPFAMILY:
3686  msg = gettext_noop("must be owner of operator family %s");
3687  break;
3688  case OBJECT_PROCEDURE:
3689  msg = gettext_noop("must be owner of procedure %s");
3690  break;
3691  case OBJECT_PUBLICATION:
3692  msg = gettext_noop("must be owner of publication %s");
3693  break;
3694  case OBJECT_ROUTINE:
3695  msg = gettext_noop("must be owner of routine %s");
3696  break;
3697  case OBJECT_SEQUENCE:
3698  msg = gettext_noop("must be owner of sequence %s");
3699  break;
3700  case OBJECT_SUBSCRIPTION:
3701  msg = gettext_noop("must be owner of subscription %s");
3702  break;
3703  case OBJECT_TABLE:
3704  msg = gettext_noop("must be owner of table %s");
3705  break;
3706  case OBJECT_TYPE:
3707  msg = gettext_noop("must be owner of type %s");
3708  break;
3709  case OBJECT_VIEW:
3710  msg = gettext_noop("must be owner of view %s");
3711  break;
3712  case OBJECT_SCHEMA:
3713  msg = gettext_noop("must be owner of schema %s");
3714  break;
3715  case OBJECT_STATISTIC_EXT:
3716  msg = gettext_noop("must be owner of statistics object %s");
3717  break;
3718  case OBJECT_TABLESPACE:
3719  msg = gettext_noop("must be owner of tablespace %s");
3720  break;
3722  msg = gettext_noop("must be owner of text search configuration %s");
3723  break;
3724  case OBJECT_TSDICTIONARY:
3725  msg = gettext_noop("must be owner of text search dictionary %s");
3726  break;
3727 
3728  /*
3729  * Special cases: For these, the error message talks
3730  * about "relation", because that's where the
3731  * ownership is attached. See also
3732  * check_object_ownership().
3733  */
3734  case OBJECT_COLUMN:
3735  case OBJECT_POLICY:
3736  case OBJECT_RULE:
3737  case OBJECT_TABCONSTRAINT:
3738  case OBJECT_TRIGGER:
3739  msg = gettext_noop("must be owner of relation %s");
3740  break;
3741  /* these currently aren't used */
3742  case OBJECT_ACCESS_METHOD:
3743  case OBJECT_AMOP:
3744  case OBJECT_AMPROC:
3745  case OBJECT_ATTRIBUTE:
3746  case OBJECT_CAST:
3747  case OBJECT_DEFAULT:
3748  case OBJECT_DEFACL:
3749  case OBJECT_DOMCONSTRAINT:
3750  case OBJECT_PARAMETER_ACL:
3753  case OBJECT_ROLE:
3754  case OBJECT_TRANSFORM:
3755  case OBJECT_TSPARSER:
3756  case OBJECT_TSTEMPLATE:
3757  case OBJECT_USER_MAPPING:
3758  elog(ERROR, "unsupported object type: %d", objtype);
3759  }
3760 
3761  ereport(ERROR,
3762  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3763  errmsg(msg, objectname)));
3764  break;
3765  }
3766  default:
3767  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3768  break;
3769  }
3770 }
#define gettext_noop(x)
Definition: c.h:1135
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
@ OBJECT_EVENT_TRIGGER
Definition: parsenodes.h:1876
@ OBJECT_FDW
Definition: parsenodes.h:1878
@ OBJECT_TSPARSER
Definition: parsenodes.h:1909
@ OBJECT_COLLATION
Definition: parsenodes.h:1869
@ OBJECT_USER_MAPPING
Definition: parsenodes.h:1912
@ OBJECT_ACCESS_METHOD
Definition: parsenodes.h:1862
@ OBJECT_OPCLASS
Definition: parsenodes.h:1886
@ OBJECT_DEFACL
Definition: parsenodes.h:1873
@ OBJECT_AGGREGATE
Definition: parsenodes.h:1863
@ OBJECT_MATVIEW
Definition: parsenodes.h:1885
@ OBJECT_SCHEMA
Definition: parsenodes.h:1898
@ OBJECT_POLICY
Definition: parsenodes.h:1890
@ OBJECT_OPERATOR
Definition: parsenodes.h:1887
@ OBJECT_FOREIGN_TABLE
Definition: parsenodes.h:1880
@ OBJECT_TSCONFIGURATION
Definition: parsenodes.h:1907
@ OBJECT_OPFAMILY
Definition: parsenodes.h:1888
@ OBJECT_DOMAIN
Definition: parsenodes.h:1874
@ OBJECT_COLUMN
Definition: parsenodes.h:1868
@ OBJECT_TABLESPACE
Definition: parsenodes.h:1904
@ OBJECT_ROLE
Definition: parsenodes.h:1895
@ OBJECT_ROUTINE
Definition: parsenodes.h:1896
@ OBJECT_LARGEOBJECT
Definition: parsenodes.h:1884
@ OBJECT_PUBLICATION_NAMESPACE
Definition: parsenodes.h:1893
@ OBJECT_PROCEDURE
Definition: parsenodes.h:1891
@ OBJECT_EXTENSION
Definition: parsenodes.h:1877
@ OBJECT_INDEX
Definition: parsenodes.h:1882
@ OBJECT_DEFAULT
Definition: parsenodes.h:1872
@ OBJECT_DATABASE
Definition: parsenodes.h:1871
@ OBJECT_SEQUENCE
Definition: parsenodes.h:1899
@ OBJECT_TSTEMPLATE
Definition: parsenodes.h:1910
@ OBJECT_LANGUAGE
Definition: parsenodes.h:1883
@ OBJECT_AMOP
Definition: parsenodes.h:1864
@ OBJECT_PUBLICATION_REL
Definition: parsenodes.h:1894
@ OBJECT_FOREIGN_SERVER
Definition: parsenodes.h:1879
@ OBJECT_TSDICTIONARY
Definition: parsenodes.h:1908
@ OBJECT_ATTRIBUTE
Definition: parsenodes.h:1866
@ OBJECT_PUBLICATION
Definition: parsenodes.h:1892
@ OBJECT_RULE
Definition: parsenodes.h:1897
@ OBJECT_CONVERSION
Definition: parsenodes.h:1870
@ OBJECT_AMPROC
Definition: parsenodes.h:1865
@ OBJECT_TABLE
Definition: parsenodes.h:1903
@ OBJECT_VIEW
Definition: parsenodes.h:1913
@ OBJECT_PARAMETER_ACL
Definition: parsenodes.h:1889
@ OBJECT_TYPE
Definition: parsenodes.h:1911
@ OBJECT_FUNCTION
Definition: parsenodes.h:1881
@ OBJECT_TABCONSTRAINT
Definition: parsenodes.h:1902
@ OBJECT_DOMCONSTRAINT
Definition: parsenodes.h:1875
@ OBJECT_SUBSCRIPTION
Definition: parsenodes.h:1900
@ OBJECT_STATISTIC_EXT
Definition: parsenodes.h:1901
@ OBJECT_CAST
Definition: parsenodes.h:1867
@ OBJECT_TRIGGER
Definition: parsenodes.h:1906
@ OBJECT_TRANSFORM
Definition: parsenodes.h:1905

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(), 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(), ExecCheckRTPerms(), 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(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

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

Definition at line 3774 of file aclchk.c.

3776 {
3777  switch (aclerr)
3778  {
3779  case ACLCHECK_OK:
3780  /* no error, so return to caller */
3781  break;
3782  case ACLCHECK_NO_PRIV:
3783  ereport(ERROR,
3784  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3785  errmsg("permission denied for column \"%s\" of relation \"%s\"",
3786  colname, objectname)));
3787  break;
3788  case ACLCHECK_NOT_OWNER:
3789  /* relation msg is OK since columns don't have separate owners */
3790  aclcheck_error(aclerr, objtype, objectname);
3791  break;
3792  default:
3793  elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
3794  break;
3795  }
3796 }
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3485

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

435 {
436  Acl *result_acl;
437 
438  result_acl = allocacl(ACL_NUM(left_acl) + ACL_NUM(right_acl));
439 
440  memcpy(ACL_DAT(result_acl),
441  ACL_DAT(left_acl),
442  ACL_NUM(left_acl) * sizeof(AclItem));
443 
444  memcpy(ACL_DAT(result_acl) + ACL_NUM(left_acl),
445  ACL_DAT(right_acl),
446  ACL_NUM(right_acl) * sizeof(AclItem));
447 
448  return result_acl;
449 }
static Acl * allocacl(int n)
Definition: acl.c:383
#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 414 of file acl.c.

415 {
416  Acl *result_acl;
417 
418  result_acl = allocacl(ACL_NUM(orig_acl));
419 
420  memcpy(ACL_DAT(result_acl),
421  ACL_DAT(orig_acl),
422  ACL_NUM(orig_acl) * sizeof(AclItem));
423 
424  return result_acl;
425 }

References ACL_DAT, ACL_NUM, and allocacl().

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

◆ acldefault()

Acl* acldefault ( ObjectType  objtype,
Oid  ownerId 
)

Definition at line 755 of file acl.c.

756 {
757  AclMode world_default;
758  AclMode owner_default;
759  int nacl;
760  Acl *acl;
761  AclItem *aip;
762 
763  switch (objtype)
764  {
765  case OBJECT_COLUMN:
766  /* by default, columns have no extra privileges */
767  world_default = ACL_NO_RIGHTS;
768  owner_default = ACL_NO_RIGHTS;
769  break;
770  case OBJECT_TABLE:
771  world_default = ACL_NO_RIGHTS;
772  owner_default = ACL_ALL_RIGHTS_RELATION;
773  break;
774  case OBJECT_SEQUENCE:
775  world_default = ACL_NO_RIGHTS;
776  owner_default = ACL_ALL_RIGHTS_SEQUENCE;
777  break;
778  case OBJECT_DATABASE:
779  /* for backwards compatibility, grant some rights by default */
780  world_default = ACL_CREATE_TEMP | ACL_CONNECT;
781  owner_default = ACL_ALL_RIGHTS_DATABASE;
782  break;
783  case OBJECT_FUNCTION:
784  /* Grant EXECUTE by default, for now */
785  world_default = ACL_EXECUTE;
786  owner_default = ACL_ALL_RIGHTS_FUNCTION;
787  break;
788  case OBJECT_LANGUAGE:
789  /* Grant USAGE by default, for now */
790  world_default = ACL_USAGE;
791  owner_default = ACL_ALL_RIGHTS_LANGUAGE;
792  break;
793  case OBJECT_LARGEOBJECT:
794  world_default = ACL_NO_RIGHTS;
795  owner_default = ACL_ALL_RIGHTS_LARGEOBJECT;
796  break;
797  case OBJECT_SCHEMA:
798  world_default = ACL_NO_RIGHTS;
799  owner_default = ACL_ALL_RIGHTS_SCHEMA;
800  break;
801  case OBJECT_TABLESPACE:
802  world_default = ACL_NO_RIGHTS;
803  owner_default = ACL_ALL_RIGHTS_TABLESPACE;
804  break;
805  case OBJECT_FDW:
806  world_default = ACL_NO_RIGHTS;
807  owner_default = ACL_ALL_RIGHTS_FDW;
808  break;
810  world_default = ACL_NO_RIGHTS;
811  owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER;
812  break;
813  case OBJECT_DOMAIN:
814  case OBJECT_TYPE:
815  world_default = ACL_USAGE;
816  owner_default = ACL_ALL_RIGHTS_TYPE;
817  break;
819  world_default = ACL_NO_RIGHTS;
820  owner_default = ACL_ALL_RIGHTS_PARAMETER_ACL;
821  break;
822  default:
823  elog(ERROR, "unrecognized object type: %d", (int) objtype);
824  world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
825  owner_default = ACL_NO_RIGHTS;
826  break;
827  }
828 
829  nacl = 0;
830  if (world_default != ACL_NO_RIGHTS)
831  nacl++;
832  if (owner_default != ACL_NO_RIGHTS)
833  nacl++;
834 
835  acl = allocacl(nacl);
836  aip = ACL_DAT(acl);
837 
838  if (world_default != ACL_NO_RIGHTS)
839  {
840  aip->ai_grantee = ACL_ID_PUBLIC;
841  aip->ai_grantor = ownerId;
842  ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
843  aip++;
844  }
845 
846  /*
847  * Note that the owner's entry shows all ordinary privileges but no grant
848  * options. This is because his grant options come "from the system" and
849  * not from his own efforts. (The SQL spec says that the owner's rights
850  * come from a "_SYSTEM" authid.) However, we do consider that the
851  * owner's ordinary privileges are self-granted; this lets him revoke
852  * them. We implement the owner's grant options without any explicit
853  * "_SYSTEM"-like ACL entry, by internally special-casing the owner
854  * wherever we are testing grant options.
855  */
856  if (owner_default != ACL_NO_RIGHTS)
857  {
858  aip->ai_grantee = ownerId;
859  aip->ai_grantor = ownerId;
860  ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
861  }
862 
863  return acl;
864 }
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition: acl.h:165
#define ACL_ALL_RIGHTS_TABLESPACE
Definition: acl.h:171
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition: acl.h:169
#define ACL_ALL_RIGHTS_SCHEMA
Definition: acl.h:170
#define ACL_ALL_RIGHTS_SEQUENCE
Definition: acl.h:162
#define ACL_ALL_RIGHTS_DATABASE
Definition: acl.h:163
#define ACL_ALL_RIGHTS_FUNCTION
Definition: acl.h:166
#define ACL_ALL_RIGHTS_LANGUAGE
Definition: acl.h:167
#define ACL_ALL_RIGHTS_TYPE
Definition: acl.h:172
#define ACL_ALL_RIGHTS_FDW
Definition: acl.h:164
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition: acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition: acl.h:161
#define ACL_ID_PUBLIC
Definition: acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition: acl.h:168
#define ACL_CREATE_TEMP
Definition: parsenodes.h:93
#define ACL_USAGE
Definition: parsenodes.h:91
#define ACL_NO_RIGHTS
Definition: parsenodes.h:100
#define ACL_CONNECT
Definition: parsenodes.h:94
#define ACL_EXECUTE
Definition: parsenodes.h:90
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_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Parameter(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), get_user_default_acl(), object_aclmask(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask(), and SetDefaultACL().

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)

Definition at line 516 of file acl.c.

517 {
518  /* Check for cases where one or both are empty/null */
519  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
520  {
521  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
522  return true;
523  else
524  return false;
525  }
526  else
527  {
528  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
529  return false;
530  }
531 
532  if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
533  return false;
534 
535  if (memcmp(ACL_DAT(left_acl),
536  ACL_DAT(right_acl),
537  ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
538  return true;
539 
540  return false;
541 }

References ACL_DAT, and ACL_NUM.

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

◆ aclitemsort()

void aclitemsort ( Acl acl)

Definition at line 502 of file acl.c.

503 {
504  if (acl != NULL && ACL_NUM(acl) > 1)
505  qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
506 }
static int aclitemComparator(const void *arg1, const void *arg2)
Definition: acl.c:676
#define qsort(a, b, c, d)
Definition: port.h:445

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

1336 {
1337  AclMode result;
1339  AclItem *aidat;
1340  int i,
1341  num;
1342 
1343  /*
1344  * Null ACL should not happen, since caller should have inserted
1345  * appropriate default
1346  */
1347  if (acl == NULL)
1348  elog(ERROR, "null ACL");
1349 
1350  check_acl(acl);
1351 
1352  /* Quick exit for mask == 0 */
1353  if (mask == 0)
1354  return 0;
1355 
1356  result = 0;
1357 
1358  /* Owner always implicitly has all grant options */
1359  if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1360  has_privs_of_role(roleid, ownerId))
1361  {
1362  result = mask & ACLITEM_ALL_GOPTION_BITS;
1363  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1364  return result;
1365  }
1366 
1367  num = ACL_NUM(acl);
1368  aidat = ACL_DAT(acl);
1369 
1370  /*
1371  * Check privileges granted directly to roleid or to public
1372  */
1373  for (i = 0; i < num; i++)
1374  {
1375  AclItem *aidata = &aidat[i];
1376 
1377  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1378  aidata->ai_grantee == roleid)
1379  {
1380  result |= aidata->ai_privs & mask;
1381  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1382  return result;
1383  }
1384  }
1385 
1386  /*
1387  * Check privileges granted indirectly via role memberships. We do this in
1388  * a separate pass to minimize expensive indirect membership tests. In
1389  * particular, it's worth testing whether a given ACL entry grants any
1390  * privileges still of interest before we perform the has_privs_of_role
1391  * test.
1392  */
1393  remaining = mask & ~result;
1394  for (i = 0; i < num; i++)
1395  {
1396  AclItem *aidata = &aidat[i];
1397 
1398  if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1399  aidata->ai_grantee == roleid)
1400  continue; /* already checked it */
1401 
1402  if ((aidata->ai_privs & remaining) &&
1403  has_privs_of_role(roleid, aidata->ai_grantee))
1404  {
1405  result |= aidata->ai_privs & mask;
1406  if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1407  return result;
1408  remaining = mask & ~result;
1409  }
1410  }
1411 
1412  return result;
1413 }
static void check_acl(const Acl *acl)
Definition: acl.c:547
bool has_privs_of_role(Oid member, Oid role)
Definition: acl.c:4949
#define ACLITEM_ALL_GOPTION_BITS
Definition: acl.h:88
int remaining
Definition: informix.c:667
int i
Definition: isn.c:73
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(), pg_attribute_aclmask_ext(), pg_class_aclmask_ext(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_parameter_acl_aclmask(), pg_parameter_aclmask(), pg_type_aclmask(), and recursive_revoke().

◆ aclmembers()

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

Definition at line 1486 of file acl.c.

1487 {
1488  Oid *list;
1489  const AclItem *acldat;
1490  int i,
1491  j;
1492 
1493  if (acl == NULL || ACL_NUM(acl) == 0)
1494  {
1495  *roleids = NULL;
1496  return 0;
1497  }
1498 
1499  check_acl(acl);
1500 
1501  /* Allocate the worst-case space requirement */
1502  list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1503  acldat = ACL_DAT(acl);
1504 
1505  /*
1506  * Walk the ACL collecting mentioned RoleIds.
1507  */
1508  j = 0;
1509  for (i = 0; i < ACL_NUM(acl); i++)
1510  {
1511  const AclItem *ai = &acldat[i];
1512 
1513  if (ai->ai_grantee != ACL_ID_PUBLIC)
1514  list[j++] = ai->ai_grantee;
1515  /* grantor is currently never PUBLIC, but let's check anyway */
1516  if (ai->ai_grantor != ACL_ID_PUBLIC)
1517  list[j++] = ai->ai_grantor;
1518  }
1519 
1520  /* Sort the array */
1521  qsort(list, j, sizeof(Oid), oid_cmp);
1522 
1523  /*
1524  * We could repalloc the array down to minimum size, but it's hardly worth
1525  * it since it's only transient memory.
1526  */
1527  *roleids = list;
1528 
1529  /* Remove duplicates from the array */
1530  return qunique(list, j, sizeof(Oid), oid_cmp);
1531 }
int j
Definition: isn.c:74
void * palloc(Size size)
Definition: mcxt.c:1199
int oid_cmp(const void *p1, const void *p2)
Definition: oid.c:336
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_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Parameter(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), recordDependencyOnNewAcl(), and SetDefaultACL().

◆ aclmerge()

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

Definition at line 458 of file acl.c.

459 {
460  Acl *result_acl;
461  AclItem *aip;
462  int i,
463  num;
464 
465  /* Check for cases where one or both are empty/null */
466  if (left_acl == NULL || ACL_NUM(left_acl) == 0)
467  {
468  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
469  return NULL;
470  else
471  return aclcopy(right_acl);
472  }
473  else
474  {
475  if (right_acl == NULL || ACL_NUM(right_acl) == 0)
476  return aclcopy(left_acl);
477  }
478 
479  /* Merge them the hard way, one item at a time */
480  result_acl = aclcopy(left_acl);
481 
482  aip = ACL_DAT(right_acl);
483  num = ACL_NUM(right_acl);
484 
485  for (i = 0; i < num; i++, aip++)
486  {
487  Acl *tmp_acl;
488 
489  tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
490  ownerId, DROP_RESTRICT);
491  pfree(result_acl);
492  result_acl = tmp_acl;
493  }
494 
495  return result_acl;
496 }
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition: acl.c:944
Acl * aclcopy(const Acl *orig_acl)
Definition: acl.c:414
#define ACL_MODECHG_ADD
Definition: acl.h:129
void pfree(void *pointer)
Definition: mcxt.c:1306
@ DROP_RESTRICT
Definition: parsenodes.h:1935

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

1066 {
1067  Acl *new_acl;
1068  AclItem *new_aip;
1069  AclItem *old_aip;
1070  AclItem *dst_aip;
1071  AclItem *src_aip;
1072  AclItem *targ_aip;
1073  bool newpresent = false;
1074  int dst,
1075  src,
1076  targ,
1077  num;
1078 
1079  check_acl(old_acl);
1080 
1081  /*
1082  * Make a copy of the given ACL, substituting new owner ID for old
1083  * wherever it appears as either grantor or grantee. Also note if the new
1084  * owner ID is already present.
1085  */
1086  num = ACL_NUM(old_acl);
1087  old_aip = ACL_DAT(old_acl);
1088  new_acl = allocacl(num);
1089  new_aip = ACL_DAT(new_acl);
1090  memcpy(new_aip, old_aip, num * sizeof(AclItem));
1091  for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1092  {
1093  if (dst_aip->ai_grantor == oldOwnerId)
1094  dst_aip->ai_grantor = newOwnerId;
1095  else if (dst_aip->ai_grantor == newOwnerId)
1096  newpresent = true;
1097  if (dst_aip->ai_grantee == oldOwnerId)
1098  dst_aip->ai_grantee = newOwnerId;
1099  else if (dst_aip->ai_grantee == newOwnerId)
1100  newpresent = true;
1101  }
1102 
1103  /*
1104  * If the old ACL contained any references to the new owner, then we may
1105  * now have generated an ACL containing duplicate entries. Find them and
1106  * merge them so that there are not duplicates. (This is relatively
1107  * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1108  * be the normal case.)
1109  *
1110  * To simplify deletion of duplicate entries, we temporarily leave them in
1111  * the array but set their privilege masks to zero; when we reach such an
1112  * entry it's just skipped. (Thus, a side effect of this code will be to
1113  * remove privilege-free entries, should there be any in the input.) dst
1114  * is the next output slot, targ is the currently considered input slot
1115  * (always >= dst), and src scans entries to the right of targ looking for
1116  * duplicates. Once an entry has been emitted to dst it is known
1117  * duplicate-free and need not be considered anymore.
1118  */
1119  if (newpresent)
1120  {
1121  dst = 0;
1122  for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1123  {
1124  /* ignore if deleted in an earlier pass */
1125  if (ACLITEM_GET_RIGHTS(*targ_aip) == ACL_NO_RIGHTS)
1126  continue;
1127  /* find and merge any duplicates */
1128  for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1129  src++, src_aip++)
1130  {
1131  if (ACLITEM_GET_RIGHTS(*src_aip) == ACL_NO_RIGHTS)
1132  continue;
1133  if (aclitem_match(targ_aip, src_aip))
1134  {
1135  ACLITEM_SET_RIGHTS(*targ_aip,
1136  ACLITEM_GET_RIGHTS(*targ_aip) |
1137  ACLITEM_GET_RIGHTS(*src_aip));
1138  /* mark the duplicate deleted */
1139  ACLITEM_SET_RIGHTS(*src_aip, ACL_NO_RIGHTS);
1140  }
1141  }
1142  /* and emit to output */
1143  new_aip[dst] = *targ_aip;
1144  dst++;
1145  }
1146  /* Adjust array size to be 'dst' items */
1147  ARR_DIMS(new_acl)[0] = dst;
1148  SET_VARSIZE(new_acl, ACL_N_SIZE(dst));
1149  }
1150 
1151  return new_acl;
1152 }
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition: acl.c:665
#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:287
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:343

References ACL_DAT, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), ARR_DIMS, check_acl(), and SET_VARSIZE.

Referenced by AlterDatabaseOwner(), AlterForeignDataWrapperOwner_internal(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterSchemaOwner_internal(), AlterTypeOwnerInternal(), ATExecChangeOwner(), and change_owner_fix_column_acls().

◆ aclupdate()

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

Definition at line 944 of file acl.c.

946 {
947  Acl *new_acl = NULL;
948  AclItem *old_aip,
949  *new_aip = NULL;
950  AclMode old_rights,
951  old_goptions,
952  new_rights,
953  new_goptions;
954  int dst,
955  num;
956 
957  /* Caller probably already checked old_acl, but be safe */
958  check_acl(old_acl);
959 
960  /* If granting grant options, check for circularity */
961  if (modechg != ACL_MODECHG_DEL &&
962  ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS)
963  check_circularity(old_acl, mod_aip, ownerId);
964 
965  num = ACL_NUM(old_acl);
966  old_aip = ACL_DAT(old_acl);
967 
968  /*
969  * Search the ACL for an existing entry for this grantee and grantor. If
970  * one exists, just modify the entry in-place (well, in the same position,
971  * since we actually return a copy); otherwise, insert the new entry at
972  * the end.
973  */
974 
975  for (dst = 0; dst < num; ++dst)
976  {
977  if (aclitem_match(mod_aip, old_aip + dst))
978  {
979  /* found a match, so modify existing item */
980  new_acl = allocacl(num);
981  new_aip = ACL_DAT(new_acl);
982  memcpy(new_acl, old_acl, ACL_SIZE(old_acl));
983  break;
984  }
985  }
986 
987  if (dst == num)
988  {
989  /* need to append a new item */
990  new_acl = allocacl(num + 1);
991  new_aip = ACL_DAT(new_acl);
992  memcpy(new_aip, old_aip, num * sizeof(AclItem));
993 
994  /* initialize the new entry with no permissions */
995  new_aip[dst].ai_grantee = mod_aip->ai_grantee;
996  new_aip[dst].ai_grantor = mod_aip->ai_grantor;
997  ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
999  num++; /* set num to the size of new_acl */
1000  }
1001 
1002  old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1003  old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1004 
1005  /* apply the specified permissions change */
1006  switch (modechg)
1007  {
1008  case ACL_MODECHG_ADD:
1009  ACLITEM_SET_RIGHTS(new_aip[dst],
1010  old_rights | ACLITEM_GET_RIGHTS(*mod_aip));
1011  break;
1012  case ACL_MODECHG_DEL:
1013  ACLITEM_SET_RIGHTS(new_aip[dst],
1014  old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip));
1015  break;
1016  case ACL_MODECHG_EQL:
1017  ACLITEM_SET_RIGHTS(new_aip[dst],
1018  ACLITEM_GET_RIGHTS(*mod_aip));
1019  break;
1020  }
1021 
1022  new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]);
1023  new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]);
1024 
1025  /*
1026  * If the adjusted entry has no permissions, delete it from the list.
1027  */
1028  if (new_rights == ACL_NO_RIGHTS)
1029  {
1030  memmove(new_aip + dst,
1031  new_aip + dst + 1,
1032  (num - dst - 1) * sizeof(AclItem));
1033  /* Adjust array size to be 'num - 1' items */
1034  ARR_DIMS(new_acl)[0] = num - 1;
1035  SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1036  }
1037 
1038  /*
1039  * Remove abandoned privileges (cascading revoke). Currently we can only
1040  * handle this when the grantee is not PUBLIC.
1041  */
1042  if ((old_goptions & ~new_goptions) != 0)
1043  {
1044  Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1045  new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1046  (old_goptions & ~new_goptions),
1047  ownerId, behavior);
1048  }
1049 
1050  return new_acl;
1051 }
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition: acl.c:1248
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition: acl.c:1168
#define ACL_SIZE(ACL)
Definition: acl.h:111
#define ACL_MODECHG_DEL
Definition: acl.h:130
#define ACLITEM_GET_GOPTIONS(item)
Definition: acl.h:67
#define ACL_MODECHG_EQL
Definition: acl.h:131
Assert(fmt[strlen(fmt) - 1] !='\n')

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

5007 {
5008  if (!member_can_set_role(member, role))
5009  ereport(ERROR,
5010  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5011  errmsg("must be able to SET ROLE \"%s\"",
5012  GetUserNameFromId(role, false))));
5013 }
bool member_can_set_role(Oid member, Oid role)
Definition: acl.c:4983
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition: miscinit.c:967

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

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

◆ check_rolespec_name()

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

Definition at line 5376 of file acl.c.

5377 {
5378  if (!role)
5379  return;
5380 
5381  if (role->roletype != ROLESPEC_CSTRING)
5382  return;
5383 
5384  if (IsReservedName(role->rolename))
5385  {
5386  if (detail_msg)
5387  ereport(ERROR,
5388  (errcode(ERRCODE_RESERVED_NAME),
5389  errmsg("role name \"%s\" is reserved",
5390  role->rolename),
5391  errdetail_internal("%s", detail_msg)));
5392  else
5393  ereport(ERROR,
5394  (errcode(ERRCODE_RESERVED_NAME),
5395  errmsg("role name \"%s\" is reserved",
5396  role->rolename)));
5397  }
5398 }
bool IsReservedName(const char *name)
Definition: catalog.c:219
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1066
@ ROLESPEC_CSTRING
Definition: parsenodes.h:359
RoleSpecType roletype
Definition: parsenodes.h:369
char * rolename
Definition: parsenodes.h:370

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

971 {
972  GrantStmt *action = stmt->action;
973  InternalDefaultACL iacls;
974  ListCell *cell;
975  List *rolespecs = NIL;
976  List *nspnames = NIL;
977  DefElem *drolespecs = NULL;
978  DefElem *dnspnames = NULL;
979  AclMode all_privileges;
980  const char *errormsg;
981 
982  /* Deconstruct the "options" part of the statement */
983  foreach(cell, stmt->options)
984  {
985  DefElem *defel = (DefElem *) lfirst(cell);
986 
987  if (strcmp(defel->defname, "schemas") == 0)
988  {
989  if (dnspnames)
990  errorConflictingDefElem(defel, pstate);
991  dnspnames = defel;
992  }
993  else if (strcmp(defel->defname, "roles") == 0)
994  {
995  if (drolespecs)
996  errorConflictingDefElem(defel, pstate);
997  drolespecs = defel;
998  }
999  else
1000  elog(ERROR, "option \"%s\" not recognized", defel->defname);
1001  }
1002 
1003  if (dnspnames)
1004  nspnames = (List *) dnspnames->arg;
1005  if (drolespecs)
1006  rolespecs = (List *) drolespecs->arg;
1007 
1008  /* Prepare the InternalDefaultACL representation of the statement */
1009  /* roleid to be filled below */
1010  /* nspid to be filled in SetDefaultACLsInSchemas */
1011  iacls.is_grant = action->is_grant;
1012  iacls.objtype = action->objtype;
1013  /* all_privs to be filled below */
1014  /* privileges to be filled below */
1015  iacls.grantees = NIL; /* filled below */
1016  iacls.grant_option = action->grant_option;
1017  iacls.behavior = action->behavior;
1018 
1019  /*
1020  * Convert the RoleSpec list into an Oid list. Note that at this point we
1021  * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
1022  * there shouldn't be any additional work needed to support this case.
1023  */
1024  foreach(cell, action->grantees)
1025  {
1026  RoleSpec *grantee = (RoleSpec *) lfirst(cell);
1027  Oid grantee_uid;
1028 
1029  switch (grantee->roletype)
1030  {
1031  case ROLESPEC_PUBLIC:
1032  grantee_uid = ACL_ID_PUBLIC;
1033  break;
1034  default:
1035  grantee_uid = get_rolespec_oid(grantee, false);
1036  break;
1037  }
1038  iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
1039  }
1040 
1041  /*
1042  * Convert action->privileges, a list of privilege strings, into an
1043  * AclMode bitmask.
1044  */
1045  switch (action->objtype)
1046  {
1047  case OBJECT_TABLE:
1048  all_privileges = ACL_ALL_RIGHTS_RELATION;
1049  errormsg = gettext_noop("invalid privilege type %s for relation");
1050  break;
1051  case OBJECT_SEQUENCE:
1052  all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
1053  errormsg = gettext_noop("invalid privilege type %s for sequence");
1054  break;
1055  case OBJECT_FUNCTION:
1056  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1057  errormsg = gettext_noop("invalid privilege type %s for function");
1058  break;
1059  case OBJECT_PROCEDURE:
1060  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1061  errormsg = gettext_noop("invalid privilege type %s for procedure");
1062  break;
1063  case OBJECT_ROUTINE:
1064  all_privileges = ACL_ALL_RIGHTS_FUNCTION;
1065  errormsg = gettext_noop("invalid privilege type %s for routine");
1066  break;
1067  case OBJECT_TYPE:
1068  all_privileges = ACL_ALL_RIGHTS_TYPE;
1069  errormsg = gettext_noop("invalid privilege type %s for type");
1070  break;
1071  case OBJECT_SCHEMA:
1072  all_privileges = ACL_ALL_RIGHTS_SCHEMA;
1073  errormsg = gettext_noop("invalid privilege type %s for schema");
1074  break;
1075  default:
1076  elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1077  (int) action->objtype);
1078  /* keep compiler quiet */
1079  all_privileges = ACL_NO_RIGHTS;
1080  errormsg = NULL;
1081  }
1082 
1083  if (action->privileges == NIL)
1084  {
1085  iacls.all_privs = true;
1086 
1087  /*
1088  * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1089  * depending on the object type
1090  */
1091  iacls.privileges = ACL_NO_RIGHTS;
1092  }
1093  else
1094  {
1095  iacls.all_privs = false;
1096  iacls.privileges = ACL_NO_RIGHTS;
1097 
1098  foreach(cell, action->privileges)
1099  {
1100  AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1101  AclMode priv;
1102 
1103  if (privnode->cols)
1104  ereport(ERROR,
1105  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1106  errmsg("default privileges cannot be set for columns")));
1107 
1108  if (privnode->priv_name == NULL) /* parser mistake? */
1109  elog(ERROR, "AccessPriv node must specify privilege");
1110  priv = string_to_privilege(privnode->priv_name);
1111 
1112  if (priv & ~((AclMode) all_privileges))
1113  ereport(ERROR,
1114  (errcode(ERRCODE_INVALID_GRANT_OPERATION),
1115  errmsg(errormsg, privilege_to_string(priv))));
1116 
1117  iacls.privileges |= priv;
1118  }
1119  }
1120 
1121  if (rolespecs == NIL)
1122  {
1123  /* Set permissions for myself */
1124  iacls.roleid = GetUserId();
1125 
1126  SetDefaultACLsInSchemas(&iacls, nspnames);
1127  }
1128  else
1129  {
1130  /* Look up the role OIDs and do permissions checks */
1131  ListCell *rolecell;
1132 
1133  foreach(rolecell, rolespecs)
1134  {
1135  RoleSpec *rolespec = lfirst(rolecell);
1136 
1137  iacls.roleid = get_rolespec_oid(rolespec, false);
1138 
1139  if (!has_privs_of_role(GetUserId(), iacls.roleid))
1140  ereport(ERROR,
1141  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1142  errmsg("permission denied to change default privileges")));
1143 
1144  SetDefaultACLsInSchemas(&iacls, nspnames);
1145  }
1146  }
1147 }
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition: acl.c:5269
static AclMode string_to_privilege(const char *privname)
Definition: aclchk.c:3391
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition: aclchk.c:1155
static const char * privilege_to_string(AclMode privilege)
Definition: aclchk.c:3436
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:385
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
Oid GetUserId(void)
Definition: miscinit.c:497
@ ROLESPEC_PUBLIC
Definition: parsenodes.h:363
#define lfirst(lc)
Definition: pg_list.h:170
#define NIL
Definition: pg_list.h:66
char * priv_name
Definition: parsenodes.h:2151
List * cols
Definition: parsenodes.h:2152
char * defname
Definition: parsenodes.h:777
Node * arg
Definition: parsenodes.h:778
bool grant_option
Definition: aclchk.c:96
AclMode privileges
Definition: aclchk.c:94
List * grantees
Definition: aclchk.c:95
DropBehavior behavior
Definition: aclchk.c:97
ObjectType objtype
Definition: aclchk.c:92
Definition: pg_list.h:52

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, AlterDefaultPrivilegesStmt::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, AlterDefaultPrivilegesStmt::options, AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, InternalDefaultACL::roleid, ROLESPEC_PUBLIC, RoleSpec::roletype, SetDefaultACLsInSchemas(), and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 386 of file aclchk.c.

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

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char *  rolname,
bool  missing_ok 
)

Definition at line 5235 of file acl.c.

5236 {
5237  Oid oid;
5238 
5239  oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid,
5241  if (!OidIsValid(oid) && !missing_ok)
5242  ereport(ERROR,
5243  (errcode(ERRCODE_UNDEFINED_OBJECT),
5244  errmsg("role \"%s\" does not exist", rolname)));
5245  return oid;
5246 }
#define OidIsValid(objectId)
Definition: c.h:711
NameData rolname
Definition: pg_authid.h:34
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:698
@ AUTHNAME
Definition: syscache.h:44
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition: syscache.h:197

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

Referenced by aclparse(), check_hba(), createdb(), CreateRole(), get_object_address_unqualified(), get_role_oid_or_public(), get_rolespec_oid(), GrantRole(), is_member(), pg_has_role_id_name(), pg_has_role_name(), pg_has_role_name_id(), pg_has_role_name_name(), regrolein(), shell_check_detail(), and to_regrole().

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char* get_rolespec_name ( const RoleSpec role)

Definition at line 5354 of file acl.c.

5355 {
5356  HeapTuple tp;
5357  Form_pg_authid authForm;
5358  char *rolename;
5359 
5360  tp = get_rolespec_tuple(role);
5361  authForm = (Form_pg_authid) GETSTRUCT(tp);
5362  rolename = pstrdup(NameStr(authForm->rolname));
5363  ReleaseSysCache(tp);
5364 
5365  return rolename;
5366 }
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition: acl.c:5308
#define NameStr(name)
Definition: c.h:682
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
char * pstrdup(const char *in)
Definition: mcxt.c:1483
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221

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

5270 {
5271  Oid oid;
5272 
5273  switch (role->roletype)
5274  {
5275  case ROLESPEC_CSTRING:
5276  Assert(role->rolename);
5277  oid = get_role_oid(role->rolename, missing_ok);
5278  break;
5279 
5280  case ROLESPEC_CURRENT_ROLE:
5281  case ROLESPEC_CURRENT_USER:
5282  oid = GetUserId();
5283  break;
5284 
5285  case ROLESPEC_SESSION_USER:
5286  oid = GetSessionUserId();
5287  break;
5288 
5289  case ROLESPEC_PUBLIC:
5290  ereport(ERROR,
5291  (errcode(ERRCODE_UNDEFINED_OBJECT),
5292  errmsg("role \"%s\" does not exist", "public")));
5293  oid = InvalidOid; /* make compiler happy */
5294  break;
5295 
5296  default:
5297  elog(ERROR, "unexpected role type %d", role->roletype);
5298  }
5299 
5300  return oid;
5301 }
Oid GetSessionUserId(void)
Definition: miscinit.c:531
@ ROLESPEC_CURRENT_USER
Definition: parsenodes.h:361
@ ROLESPEC_SESSION_USER
Definition: parsenodes.h:362
@ ROLESPEC_CURRENT_ROLE
Definition: parsenodes.h:360
#define InvalidOid
Definition: postgres_ext.h:36

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

5309 {
5310  HeapTuple tuple;
5311 
5312  switch (role->roletype)
5313  {
5314  case ROLESPEC_CSTRING:
5315  Assert(role->rolename);
5317  if (!HeapTupleIsValid(tuple))
5318  ereport(ERROR,
5319  (errcode(ERRCODE_UNDEFINED_OBJECT),
5320  errmsg("role \"%s\" does not exist", role->rolename)));
5321  break;
5322 
5323  case ROLESPEC_CURRENT_ROLE:
5324  case ROLESPEC_CURRENT_USER:
5325  tuple = SearchSysCache1(AUTHOID, GetUserId());
5326  if (!HeapTupleIsValid(tuple))
5327  elog(ERROR, "cache lookup failed for role %u", GetUserId());
5328  break;
5329 
5330  case ROLESPEC_SESSION_USER:
5332  if (!HeapTupleIsValid(tuple))
5333  elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5334  break;
5335 
5336  case ROLESPEC_PUBLIC:
5337  ereport(ERROR,
5338  (errcode(ERRCODE_UNDEFINED_OBJECT),
5339  errmsg("role \"%s\" does not exist", "public")));
5340  tuple = NULL; /* make compiler happy */
5341  break;
5342 
5343  default:
5344  elog(ERROR, "unexpected role type %d", role->roletype);
5345  }
5346 
5347  return tuple;
5348 }
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
@ AUTHOID
Definition: syscache.h:45

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

4959 {
4960  Acl *result;
4961  Acl *glob_acl;
4962  Acl *schema_acl;
4963  Acl *def_acl;
4964  char defaclobjtype;
4965 
4966  /*
4967  * Use NULL during bootstrap, since pg_default_acl probably isn't there
4968  * yet.
4969  */
4971  return NULL;
4972 
4973  /* Check if object type is supported in pg_default_acl */
4974  switch (objtype)
4975  {
4976  case OBJECT_TABLE:
4977  defaclobjtype = DEFACLOBJ_RELATION;
4978  break;
4979 
4980  case OBJECT_SEQUENCE:
4981  defaclobjtype = DEFACLOBJ_SEQUENCE;
4982  break;
4983 
4984  case OBJECT_FUNCTION:
4985  defaclobjtype = DEFACLOBJ_FUNCTION;
4986  break;
4987 
4988  case OBJECT_TYPE:
4989  defaclobjtype = DEFACLOBJ_TYPE;
4990  break;
4991 
4992  case OBJECT_SCHEMA:
4993  defaclobjtype = DEFACLOBJ_NAMESPACE;
4994  break;
4995 
4996  default:
4997  return NULL;
4998  }
4999 
5000  /* Look up the relevant pg_default_acl entries */
5001  glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
5002  schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
5003 
5004  /* Quick out if neither entry exists */
5005  if (glob_acl == NULL && schema_acl == NULL)
5006  return NULL;
5007 
5008  /* We need to know the hard-wired default value, too */
5009  def_acl = acldefault(objtype, ownerId);
5010 
5011  /* If there's no global entry, substitute the hard-wired default */
5012  if (glob_acl == NULL)
5013  glob_acl = def_acl;
5014 
5015  /* Merge in any per-schema privileges */
5016  result = aclmerge(glob_acl, schema_acl, ownerId);
5017 
5018  /*
5019  * For efficiency, we want to return NULL if the result equals default.
5020  * This requires sorting both arrays to get an accurate comparison.
5021  */
5022  aclitemsort(result);
5023  aclitemsort(def_acl);
5024  if (aclequal(result, def_acl))
5025  result = NULL;
5026 
5027  return result;
5028 }
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition: acl.c:516
void aclitemsort(Acl *acl)
Definition: acl.c:502
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition: acl.c:755
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition: acl.c:458
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition: aclchk.c:4923
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:402

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

4900 {
4901  bool result = false;
4902  HeapTuple utup;
4903 
4904  /* Superusers bypass all permission checking. */
4905  if (superuser_arg(roleid))
4906  return true;
4907 
4908  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4909  if (HeapTupleIsValid(utup))
4910  {
4911  result = ((Form_pg_authid) GETSTRUCT(utup))->rolbypassrls;
4912  ReleaseSysCache(utup);
4913  }
4914  return result;
4915 }
bool rolbypassrls
Definition: pg_authid.h:41
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
bool superuser_arg(Oid roleid)
Definition: superuser.c:56

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

Referenced by check_enable_rls(), and RI_Initial_Check().

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4880 of file aclchk.c.

4881 {
4882  bool result = false;
4883  HeapTuple utup;
4884 
4885  /* Superusers bypass all permission checking. */
4886  if (superuser_arg(roleid))
4887  return true;
4888 
4889  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
4890  if (HeapTupleIsValid(utup))
4891  {
4892  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
4893  ReleaseSysCache(utup);
4894  }
4895  return result;
4896 }
bool rolcreaterole
Definition: pg_authid.h:37

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)

Definition at line 4949 of file acl.c.

4950 {
4951  /* Fast path for simple case */
4952  if (member == role)
4953  return true;
4954 
4955  /* Superusers have every privilege, so are part of every role */
4956  if (superuser_arg(member))
4957  return true;
4958 
4959  /*
4960  * Find all the roles that member has the privileges of, including
4961  * multi-level recursion, then see if target role is any one of them.
4962  */
4964  InvalidOid, NULL),
4965  role);
4966 }
@ ROLERECURSE_PRIVS
Definition: acl.c:76
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition: acl.c:4824
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721

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(), convert_and_check_filename(), DoCopy(), DropOwnedObjects(), ExecAlterDefaultPrivilegesStmt(), file_fdw_validator(), get_explain_guc_options(), GetConfigOption(), GetConfigOptionByName(), GetConfigOptionResetString(), GetConfigOptionValues(), object_ownercheck(), pg_class_aclmask_ext(), pg_namespace_aclmask(), pg_role_aclcheck(), pg_signal_backend(), pg_stat_get_wal_receiver(), pg_stat_get_wal_senders(), pg_stat_statements_internal(), pgrowlocks(), ReassignOwnedObjects(), shell_check_detail(), ShowAllGUCConfig(), standard_ProcessUtility(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )

Definition at line 4759 of file acl.c.

4760 {
4762  {
4763  cached_db_hash =
4766 
4767  /*
4768  * In normal mode, set a callback on any syscache invalidation of rows
4769  * of pg_auth_members (for roles_is_member_of()) pg_database (for
4770  * roles_is_member_of())
4771  */
4774  (Datum) 0);
4777  (Datum) 0);
4780  (Datum) 0);
4781  }
4782 }
static uint32 cached_db_hash
Definition: acl.c:81
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Definition: acl.c:4789
Oid MyDatabaseId
Definition: globals.c:89
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
Definition: inval.c:1519
uintptr_t Datum
Definition: postgres.h:412
@ AUTHMEMROLEMEM
Definition: syscache.h:43
@ DATABASEOID
Definition: syscache.h:55
#define GetSysCacheHashValue1(cacheId, key1)
Definition: syscache.h:206

References AUTHMEMROLEMEM, AUTHOID, cached_db_hash, CacheRegisterSyscacheCallback(), DATABASEOID, 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 5079 of file acl.c.

5080 {
5081  Oid admin_role;
5082 
5083  if (superuser_arg(member))
5084  return true;
5085 
5086  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5087  if (member == role)
5088  return false;
5089 
5090  (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &admin_role);
5091  return OidIsValid(admin_role);
5092 }
@ ROLERECURSE_MEMBERS
Definition: acl.c:75

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

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

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)

Definition at line 5029 of file acl.c.

5030 {
5031  /* Fast path for simple case */
5032  if (member == role)
5033  return true;
5034 
5035  /* Superusers have every privilege, so are part of every role */
5036  if (superuser_arg(member))
5037  return true;
5038 
5039  /*
5040  * Find all the roles that member is a member of, including multi-level
5041  * recursion, then see if target role is any one of them.
5042  */
5044  InvalidOid, NULL),
5045  role);
5046 }

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

5058 {
5059  /* Fast path for simple case */
5060  if (member == role)
5061  return true;
5062 
5063  /*
5064  * Find all the roles that member is a member of, including multi-level
5065  * recursion, then see if target role is any one of them.
5066  */
5068  InvalidOid, NULL),
5069  role);
5070 }

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

406 {
407  return allocacl(0);
408 }

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)

Definition at line 4983 of file acl.c.

4984 {
4985  /* Fast path for simple case */
4986  if (member == role)
4987  return true;
4988 
4989  /* Superusers have every privilege, so can always SET ROLE */
4990  if (superuser_arg(member))
4991  return true;
4992 
4993  /*
4994  * Find all the roles that member can access via SET ROLE, including
4995  * multi-level recursion, then see if target role is any one of them.
4996  */
4998  InvalidOid, NULL),
4999  role);
5000 }
@ ROLERECURSE_SETROLE
Definition: acl.c:77

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

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

◆ object_aclcheck()

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

Definition at line 4598 of file aclchk.c.

4599 {
4600  if (object_aclmask(classid, objectid, roleid, mode, ACLMASK_ANY) != 0)
4601  return ACLCHECK_OK;
4602  else
4603  return ACLCHECK_NO_PRIV;
4604 }
static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3881
static PgChecksumMode mode
Definition: pg_checksums.c:65

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

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterForeignServerOwner_internal(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterTableMoveAll(), AlterTypeOwner(), ATExecAddColumn(), 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(), 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(), has_database_privilege_id_id(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_id(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id(), has_foreign_data_wrapper_privilege_id_id(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_id(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id(), has_function_privilege_id_id(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_id(), has_function_privilege_name_name(), has_language_privilege_id(), has_language_privilege_id_id(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_id(), has_language_privilege_name_name(), has_schema_privilege_id(), has_schema_privilege_id_id(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_id(), has_schema_privilege_name_name(), has_server_privilege_id(), has_server_privilege_id_id(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_id(), has_server_privilege_name_name(), has_tablespace_privilege_id(), has_tablespace_privilege_id_id(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_id(), has_tablespace_privilege_name_name(), has_type_privilege_id(), has_type_privilege_id_id(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_id(), 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(), pg_namespace_aclmask(), PrepareTempTablespaces(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), recomputeNamespacePath(), ReindexMultipleInternal(), RenameSchema(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_ownercheck()

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

Definition at line 4799 of file aclchk.c.

4800 {
4801  int cacheid;
4802  Oid ownerId;
4803 
4804  /* Superusers bypass all permission checking. */
4805  if (superuser_arg(roleid))
4806  return true;
4807 
4808  cacheid = get_object_catcache_oid(classid);
4809  if (cacheid != -1)
4810  {
4811  HeapTuple tuple;
4812  bool isnull;
4813 
4814  tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
4815  if (!HeapTupleIsValid(tuple))
4816  ereport(ERROR,
4817  (errcode(ERRCODE_UNDEFINED_OBJECT),
4818  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4819 
4820  ownerId = DatumGetObjectId(SysCacheGetAttr(cacheid,
4821  tuple,
4822  get_object_attnum_owner(classid),
4823  &isnull));
4824  Assert(!isnull);
4825 
4826  ReleaseSysCache(tuple);
4827  }
4828  else
4829  {
4830  /* for catalogs without an appropriate syscache */
4831 
4832  Relation rel;
4833  ScanKeyData entry[1];
4834  SysScanDesc scan;
4835  HeapTuple tuple;
4836  bool isnull;
4837 
4838  rel = table_open(classid, AccessShareLock);
4839 
4840  ScanKeyInit(&entry[0],
4841  get_object_attnum_oid(classid),
4842  BTEqualStrategyNumber, F_OIDEQ,
4843  ObjectIdGetDatum(objectid));
4844 
4845  scan = systable_beginscan(rel,
4846  get_object_oid_index(classid), true,
4847  NULL, 1, entry);
4848 
4849  tuple = systable_getnext(scan);
4850  if (!HeapTupleIsValid(tuple))
4851  ereport(ERROR,
4852  (errcode(ERRCODE_UNDEFINED_OBJECT),
4853  errmsg("%s with OID %u does not exist", get_object_class_descr(classid), objectid)));
4854 
4855  ownerId = DatumGetObjectId(heap_getattr(tuple,
4856  get_object_attnum_owner(classid),
4857  RelationGetDescr(rel),
4858  &isnull));
4859  Assert(!isnull);
4860 
4861  systable_endscan(scan);
4863  }
4864 
4865  return has_privs_of_role(roleid, ownerId);
4866 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
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:788
#define AccessShareLock
Definition: lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
int get_object_catcache_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)
const char * get_object_class_descr(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:590
#define RelationGetDescr(relation)
Definition: rel.h:527
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1434
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(), ereport, errcode(), errmsg(), 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(), SysCacheGetAttr(), 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(), cluster_rel(), CreateCast(), createdb(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), DefineOpClass(), DefineQueryRewrite(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecuteTruncateGuts(), get_tables_to_cluster(), get_tables_to_cluster_partitioned(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), movedb(), OperatorCreate(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsRelation(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), user_mapping_ddl_aclcheck(), and vacuum_is_permitted_for_relation().

◆ pg_attribute_aclcheck()

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

Definition at line 4617 of file aclchk.c.

4619 {
4620  return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL);
4621 }
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:4631
int16 attnum
Definition: pg_attribute.h:83

References attnum, mode, and pg_attribute_aclcheck_ext().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), examine_simple_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckRTEPerms(), ExecCheckRTEPermsModified(), 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 4661 of file aclchk.c.

4663 {
4664  AclResult result;
4665  HeapTuple classTuple;
4666  Form_pg_class classForm;
4667  AttrNumber nattrs;
4668  AttrNumber curr_att;
4669 
4670  /*
4671  * Must fetch pg_class row to check number of attributes. As in
4672  * pg_attribute_aclmask, we prefer to return "no privileges" instead of
4673  * throwing an error if we get any unexpected lookup errors.
4674  */
4675  classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid));
4676  if (!HeapTupleIsValid(classTuple))
4677  return ACLCHECK_NO_PRIV;
4678  classForm = (Form_pg_class) GETSTRUCT(classTuple);
4679 
4680  nattrs = classForm->relnatts;
4681 
4682  ReleaseSysCache(classTuple);
4683 
4684  /*
4685  * Initialize result in case there are no non-dropped columns. We want to
4686  * report failure in such cases for either value of 'how'.
4687  */
4688  result = ACLCHECK_NO_PRIV;
4689 
4690  for (curr_att = 1; curr_att <= nattrs; curr_att++)
4691  {
4692  HeapTuple attTuple;
4693  AclMode attmask;
4694 
4695  attTuple = SearchSysCache2(ATTNUM,
4696  ObjectIdGetDatum(table_oid),
4697  Int16GetDatum(curr_att));
4698  if (!HeapTupleIsValid(attTuple))
4699  continue;
4700 
4701  /* ignore dropped columns */
4702  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4703  {
4704  ReleaseSysCache(attTuple);
4705  continue;
4706  }
4707 
4708  /*
4709  * Here we hard-wire knowledge that the default ACL for a column
4710  * grants no privileges, so that we can fall out quickly in the very
4711  * common case where attacl is null.
4712  */
4713  if (heap_attisnull(attTuple, Anum_pg_attribute_attacl, NULL))
4714  attmask = 0;
4715  else
4716  attmask = pg_attribute_aclmask(table_oid, curr_att, roleid,
4717  mode, ACLMASK_ANY);
4718 
4719  ReleaseSysCache(attTuple);
4720 
4721  if (attmask != 0)
4722  {
4723  result = ACLCHECK_OK;
4724  if (how == ACLMASK_ANY)
4725  break; /* succeed on any success */
4726  }
4727  else
4728  {
4729  result = ACLCHECK_NO_PRIV;
4730  if (how == ACLMASK_ALL)
4731  break; /* fail on any failure */
4732  }
4733  }
4734 
4735  return result;
4736 }
static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:3962
int16 AttrNumber
Definition: attnum.h:21
bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
Definition: heaptuple.c:359
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:520
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition: syscache.c:1184
@ ATTNUM
Definition: syscache.h:41
@ RELOID
Definition: syscache.h:89

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

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

◆ pg_attribute_aclcheck_ext()

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

Definition at line 4631 of file aclchk.c.

4633 {
4634  if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode,
4635  ACLMASK_ANY, is_missing) != 0)
4636  return ACLCHECK_OK;
4637  else
4638  return ACLCHECK_NO_PRIV;
4639 }
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:3976

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()

AclResult pg_class_aclcheck ( Oid  table_oid,
Oid  roleid,
AclMode  mode 
)

Definition at line 4746 of file aclchk.c.

4747 {
4748  return pg_class_aclcheck_ext(table_oid, roleid, mode, NULL);
4749 }
AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
Definition: aclchk.c:4758

References mode, and pg_class_aclcheck_ext().

Referenced by BuildIndexValueDescription(), checkFkeyPermissions(), CreateTriggerFiringOn(), currtid_internal(), currval_oid(), do_setval(), examine_simple_variable(), examine_variable(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), get_rel_from_relname(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), lastval(), LockTableAclCheck(), LogicalRepSyncTableStart(), nextval_internal(), pg_prewarm(), pg_sequence_last_value(), pg_sequence_parameters(), pgrowlocks(), ri_ReportViolation(), statext_is_compatible_clause(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), and vacuum_is_permitted_for_relation().

◆ pg_class_aclcheck_ext()

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

Definition at line 4758 of file aclchk.c.

4760 {
4761  if (pg_class_aclmask_ext(table_oid, roleid, mode,
4762  ACLMASK_ANY, is_missing) != 0)
4763  return ACLCHECK_OK;
4764  else
4765  return ACLCHECK_NO_PRIV;
4766 }
static AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition: aclchk.c:4094

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

Referenced by column_privilege_check(), and pg_class_aclcheck().

◆ pg_class_aclmask()

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

Definition at line 4081 of file aclchk.c.

4083 {
4084  return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
4085 }

References pg_class_aclmask_ext().

Referenced by ExecCheckRTEPerms(), and pg_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4785 of file aclchk.c.

4787 {
4788  if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode,
4789  ACLMASK_ANY, snapshot) != 0)
4790  return ACLCHECK_OK;
4791  else
4792  return ACLCHECK_NO_PRIV;
4793 }
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition: aclchk.c:4356

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

Referenced by be_lo_put(), and inv_open().

◆ pg_parameter_aclcheck()

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

Definition at line 4773 of file aclchk.c.

4774 {
4775  if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4776  return ACLCHECK_OK;
4777  else
4778  return ACLCHECK_NO_PRIV;
4779 }
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition: aclchk.c:4233
const char * name
Definition: encode.c:561

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

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

◆ recordDependencyOnNewAcl()

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

Definition at line 5034 of file aclchk.c.

5036 {
5037  int nmembers;
5038  Oid *members;
5039 
5040  /* Nothing to do if ACL is defaulted */
5041  if (acl == NULL)
5042  return;
5043 
5044  /* Extract roles mentioned in ACL */
5045  nmembers = aclmembers(acl, &members);
5046 
5047  /* Update the shared dependency ACL info */
5048  updateAclDependencies(classId, objectId, objsubId,
5049  ownerId,
5050  0, NULL,
5051  nmembers, members);
5052 }
int aclmembers(const Acl *acl, Oid **roleids)
Definition: acl.c:1486
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
Definition: pg_shdepend.c:482

References aclmembers(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 5064 of file aclchk.c.

5065 {
5066  /*
5067  * pg_class / pg_attribute
5068  *
5069  * If this is a relation then we need to see if there are any sub-objects
5070  * (eg: columns) for it and, if so, be sure to call
5071  * recordExtensionInitPrivWorker() for each one.
5072  */
5073  if (classoid == RelationRelationId)
5074  {
5075  Form_pg_class pg_class_tuple;
5076  Datum aclDatum;
5077  bool isNull;
5078  HeapTuple tuple;
5079 
5080  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
5081  if (!HeapTupleIsValid(tuple))
5082  elog(ERROR, "cache lookup failed for relation %u", objoid);
5083  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
5084 
5085  /*
5086  * Indexes don't have permissions, neither do the pg_class rows for
5087  * composite types. (These cases are unreachable given the
5088  * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
5089  */
5090  if (pg_class_tuple->relkind == RELKIND_INDEX ||
5091  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
5092  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
5093  {
5094  ReleaseSysCache(tuple);
5095  return;
5096  }
5097 
5098  /*
5099  * If this isn't a sequence then it's possibly going to have
5100  * column-level ACLs associated with it.
5101  */
5102  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
5103  {
5104  AttrNumber curr_att;
5105  AttrNumber nattrs = pg_class_tuple->relnatts;
5106 
5107  for (curr_att = 1; curr_att <= nattrs; curr_att++)
5108  {
5109  HeapTuple attTuple;
5110  Datum attaclDatum;
5111 
5112  attTuple = SearchSysCache2(ATTNUM,
5113  ObjectIdGetDatum(objoid),
5114  Int16GetDatum(curr_att));
5115 
5116  if (!HeapTupleIsValid(attTuple))
5117  continue;
5118 
5119  /* ignore dropped columns */
5120  if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
5121  {
5122  ReleaseSysCache(attTuple);
5123  continue;
5124  }
5125 
5126  attaclDatum = SysCacheGetAttr(ATTNUM, attTuple,
5127  Anum_pg_attribute_attacl,
5128  &isNull);
5129 
5130  /* no need to do anything for a NULL ACL */
5131  if (isNull)
5132  {
5133  ReleaseSysCache(attTuple);
5134  continue;
5135  }
5136 
5137  recordExtensionInitPrivWorker(objoid, classoid, curr_att,
5138  DatumGetAclP(attaclDatum));
5139 
5140  ReleaseSysCache(attTuple);
5141  }
5142  }
5143 
5144  aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
5145  &isNull);
5146 
5147  /* Add the record, if any, for the top-level object */
5148  if (!isNull)
5149  recordExtensionInitPrivWorker(objoid, classoid, 0,
5150  DatumGetAclP(aclDatum));
5151 
5152  ReleaseSysCache(tuple);
5153  }
5154  /* pg_foreign_data_wrapper */
5155  else if (classoid == ForeignDataWrapperRelationId)
5156  {
5157  Datum aclDatum;
5158  bool isNull;
5159  HeapTuple tuple;
5160 
5162  ObjectIdGetDatum(objoid));
5163  if (!HeapTupleIsValid(tuple))
5164  elog(ERROR, "cache lookup failed for foreign data wrapper %u",
5165  objoid);
5166 
5167  aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple,
5168  Anum_pg_foreign_data_wrapper_fdwacl,
5169  &isNull);
5170 
5171  /* Add the record, if any, for the top-level object */
5172  if (!isNull)
5173  recordExtensionInitPrivWorker(objoid, classoid, 0,
5174  DatumGetAclP(aclDatum));
5175 
5176  ReleaseSysCache(tuple);
5177  }
5178  /* pg_foreign_server */
5179  else if (classoid == ForeignServerRelationId)
5180  {
5181  Datum aclDatum;
5182  bool isNull;
5183  HeapTuple tuple;
5184 
5186  if (!HeapTupleIsValid(tuple))
5187  elog(ERROR, "cache lookup failed for foreign data wrapper %u",
5188  objoid);
5189 
5190  aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple,
5191  Anum_pg_foreign_server_srvacl,
5192  &isNull);
5193 
5194  /* Add the record, if any, for the top-level object */
5195  if (!isNull)
5196  recordExtensionInitPrivWorker(objoid, classoid, 0,
5197  DatumGetAclP(aclDatum));
5198 
5199  ReleaseSysCache(tuple);
5200  }
5201  /* pg_language */
5202  else if (classoid == LanguageRelationId)
5203  {
5204  Datum aclDatum;
5205  bool isNull;
5206  HeapTuple tuple;
5207 
5208  tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(objoid));
5209  if (!HeapTupleIsValid(tuple))
5210  elog(ERROR, "cache lookup failed for language %u", objoid);
5211 
5212  aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
5213  &isNull);
5214 
5215  /* Add the record, if any, for the top-level object */
5216  if (!isNull)
5217  recordExtensionInitPrivWorker(objoid, classoid, 0,
5218  DatumGetAclP(aclDatum));
5219 
5220  ReleaseSysCache(tuple);
5221  }
5222  /* pg_largeobject_metadata */
5223  else if (classoid == LargeObjectMetadataRelationId)
5224  {
5225  Datum aclDatum;
5226  bool isNull;
5227  HeapTuple tuple;
5228  ScanKeyData entry[1];
5229  SysScanDesc scan;
5230  Relation relation;
5231 
5232  /*
5233  * Note: this is dead code, given that we don't allow large objects to
5234  * be made extension members. But it seems worth carrying in case
5235  * some future caller of this function has need for it.
5236  */
5237  relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock);
5238 
5239  /* There's no syscache for pg_largeobject_metadata */
5240  ScanKeyInit(&entry[0],
5241  Anum_pg_largeobject_metadata_oid,
5242  BTEqualStrategyNumber, F_OIDEQ,
5243  ObjectIdGetDatum(objoid));
5244 
5245  scan = systable_beginscan(relation,
5246  LargeObjectMetadataOidIndexId, true,
5247  NULL, 1, entry);
5248 
5249  tuple = systable_getnext(scan);
5250  if (!HeapTupleIsValid(tuple))
5251  elog(ERROR, "could not find tuple for large object %u", objoid);
5252 
5253  aclDatum = heap_getattr(tuple,
5254  Anum_pg_largeobject_metadata_lomacl,
5255  RelationGetDescr(relation), &isNull);
5256 
5257  /* Add the record, if any, for the top-level object */
5258  if (!isNull)
5259  recordExtensionInitPrivWorker(objoid, classoid, 0,
5260  DatumGetAclP(aclDatum));
5261 
5262  systable_endscan(scan);
5263  }
5264  /* pg_namespace */
5265  else if (classoid == NamespaceRelationId)
5266  {
5267  Datum aclDatum;
5268  bool isNull;
5269  HeapTuple tuple;
5270 
5271  tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(objoid));
5272  if (!HeapTupleIsValid(tuple))
5273  elog(ERROR, "cache lookup failed for function %u", objoid);
5274 
5275  aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple,
5276  Anum_pg_namespace_nspacl, &isNull);
5277 
5278  /* Add the record, if any, for the top-level object */
5279  if (!isNull)
5280  recordExtensionInitPrivWorker(objoid, classoid, 0,
5281  DatumGetAclP(aclDatum));
5282 
5283  ReleaseSysCache(tuple);
5284  }
5285  /* pg_proc */
5286  else if (classoid == ProcedureRelationId)
5287  {
5288  Datum aclDatum;
5289  bool isNull;
5290  HeapTuple tuple;
5291 
5292  tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(objoid));
5293  if (!HeapTupleIsValid(tuple))
5294  elog(ERROR, "cache lookup failed for function %u", objoid);
5295 
5296  aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl,
5297  &isNull);
5298 
5299  /* Add the record, if any, for the top-level object */
5300  if (!isNull)
5301  recordExtensionInitPrivWorker(objoid, classoid, 0,
5302  DatumGetAclP(aclDatum));
5303 
5304  ReleaseSysCache(tuple);
5305  }
5306  /* pg_type */
5307  else if (classoid == TypeRelationId)
5308  {
5309  Datum aclDatum;
5310  bool isNull;
5311  HeapTuple tuple;
5312 
5313  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(objoid));
5314  if (!HeapTupleIsValid(tuple))
5315  elog(ERROR, "cache lookup failed for function %u", objoid);
5316 
5317  aclDatum = SysCacheGetAttr(TYPEOID, tuple, Anum_pg_type_typacl,
5318  &isNull);
5319 
5320  /* Add the record, if any, for the top-level object */
5321  if (!isNull)
5322  recordExtensionInitPrivWorker(objoid, classoid, 0,
5323  DatumGetAclP(aclDatum));
5324 
5325  ReleaseSysCache(tuple);
5326  }
5327  else if (classoid == AccessMethodRelationId ||
5328  classoid == AggregateRelationId ||
5329  classoid == CastRelationId ||
5330  classoid == CollationRelationId ||
5331  classoid == ConversionRelationId ||
5332  classoid == EventTriggerRelationId ||
5333  classoid == OperatorRelationId ||
5334  classoid == OperatorClassRelationId ||
5335  classoid == OperatorFamilyRelationId ||
5336  classoid == NamespaceRelationId ||
5337  classoid == TSConfigRelationId ||
5338  classoid == TSDictionaryRelationId ||
5339  classoid == TSParserRelationId ||
5340  classoid == TSTemplateRelationId ||
5341  classoid == TransformRelationId
5342  )
5343  {
5344  /* no ACL for these object types, so do nothing. */
5345  }
5346 
5347  /*
5348  * complain if we are given a class OID for a class that extensions don't
5349  * support or that we don't recognize.
5350  */
5351  else
5352  {
5353  elog(ERROR, "unrecognized or unsupported class OID: %u", classoid);
5354  }
5355 }
#define DatumGetAclP(X)
Definition: acl.h:120
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition: aclchk.c:5474
#define RowExclusiveLock
Definition: lockdefs.h:38
@ FOREIGNSERVEROID
Definition: syscache.h:64
@ TYPEOID
Definition: syscache.h:114
@ PROCOID
Definition: syscache.h:79
@ FOREIGNDATAWRAPPEROID
Definition: syscache.h:62
@ LANGOID
Definition: syscache.h:68
@ NAMESPACEOID
Definition: syscache.h:70

References ATTNUM, BTEqualStrategyNumber, DatumGetAclP, elog(), ERROR, FOREIGNDATAWRAPPEROID, FOREIGNSERVEROID, GETSTRUCT, heap_getattr(), HeapTupleIsValid, Int16GetDatum(), LANGOID, NAMESPACEOID, ObjectIdGetDatum(), PROCOID, recordExtensionInitPrivWorker(), RelationGetDescr, ReleaseSysCache(), RELOID, RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SearchSysCache2(), SysCacheGetAttr(), systable_beginscan(), systable_endscan(), systable_getnext(), table_open(), and TYPEOID.

Referenced by ExecAlterExtensionContentsStmt().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 5362 of file aclchk.c.

5363 {
5364  /*
5365  * If this is a relation then we need to see if there are any sub-objects
5366  * (eg: columns) for it and, if so, be sure to call
5367  * recordExtensionInitPrivWorker() for each one.
5368  */
5369  if (classoid == RelationRelationId)
5370  {
5371  Form_pg_class pg_class_tuple;
5372  HeapTuple tuple;
5373 
5374  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
5375  if (!HeapTupleIsValid(tuple))
5376  elog(ERROR, "cache lookup failed for relation %u", objoid);
5377  pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
5378 
5379  /*
5380  * Indexes don't have permissions, neither do the pg_class rows for
5381  * composite types. (These cases are unreachable given the
5382  * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
5383  */
5384  if (pg_class_tuple->relkind == RELKIND_INDEX ||
5385  pg_class_tuple->relkind == RELKIND_PARTITIONED_INDEX ||
5386  pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
5387  {
5388  ReleaseSysCache(tuple);
5389  return;
5390  }
5391 
5392  /*
5393  * If this isn't a sequence then it's possibly going to have
5394  * column-level ACLs associated with it.
5395  */
5396  if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
5397  {
5398  AttrNumber curr_att;
5399  AttrNumber nattrs = pg_class_tuple->relnatts;
5400 
5401  for (curr_att = 1; curr_att <= nattrs; curr_att++)
5402  {
5403  HeapTuple attTuple;
5404 
5405  attTuple = SearchSysCache2(ATTNUM,
5406  ObjectIdGetDatum(objoid),
5407  Int16GetDatum(curr_att));
5408 
5409  if (!HeapTupleIsValid(attTuple))
5410  continue;
5411 
5412  /* when removing, remove all entries, even dropped columns */
5413 
5414  recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
5415 
5416  ReleaseSysCache(attTuple);
5417  }
5418  }
5419 
5420  ReleaseSysCache(tuple);
5421  }
5422 
5423  /* Remove the record, if any, for the top-level object */
5424  recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
5425 }

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

Referenced by ExecAlterExtensionContentsStmt().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1448 of file aclchk.c.

1449 {
1450  if (classid == DefaultAclRelationId)
1451  {
1452  InternalDefaultACL iacls;
1453  Form_pg_default_acl pg_default_acl_tuple;
1454  Relation rel;
1455  ScanKeyData skey[1];
1456  SysScanDesc scan;
1457  HeapTuple tuple;
1458 
1459  /* first fetch info needed by SetDefaultACL */
1460  rel = table_open(DefaultAclRelationId, AccessShareLock);
1461 
1462  ScanKeyInit(&skey[0],
1463  Anum_pg_default_acl_oid,
1464  BTEqualStrategyNumber, F_OIDEQ,
1465  ObjectIdGetDatum(objid));
1466 
1467  scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1468  NULL, 1, skey);
1469 
1470  tuple = systable_getnext(scan);
1471 
1472  if (!HeapTupleIsValid(tuple))
1473  elog(ERROR, "could not find tuple for default ACL %u", objid);
1474 
1475  pg_default_acl_tuple = (Form_pg_default_acl) GETSTRUCT(tuple);
1476 
1477  iacls.roleid = pg_default_acl_tuple->defaclrole;
1478  iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1479 
1480  switch (pg_default_acl_tuple->defaclobjtype)
1481  {
1482  case DEFACLOBJ_RELATION:
1483  iacls.objtype = OBJECT_TABLE;
1484  break;
1485  case DEFACLOBJ_SEQUENCE:
1486  iacls.objtype = OBJECT_SEQUENCE;
1487  break;
1488  case DEFACLOBJ_FUNCTION:
1489  iacls.objtype = OBJECT_FUNCTION;
1490  break;
1491  case DEFACLOBJ_TYPE:
1492  iacls.objtype = OBJECT_TYPE;
1493  break;
1494  case DEFACLOBJ_NAMESPACE:
1495  iacls.objtype = OBJECT_SCHEMA;
1496  break;
1497  default:
1498  /* Shouldn't get here */
1499  elog(ERROR, "unexpected default ACL type: %d",
1500  (int) pg_default_acl_tuple->defaclobjtype);
1501  break;
1502  }
1503 
1504  systable_endscan(scan);
1506 
1507  iacls.is_grant = false;
1508  iacls.all_privs = true;
1509  iacls.privileges = ACL_NO_RIGHTS;
1510  iacls.grantees = list_make1_oid(roleid);
1511  iacls.grant_option = false;
1512  iacls.behavior = DROP_CASCADE;
1513 
1514  /* Do it */
1515  SetDefaultACL(&iacls);
1516  }
1517  else
1518  {
1519  InternalGrant istmt;
1520 
1521  switch (classid)
1522  {
1523  case RelationRelationId:
1524  /* it's OK to use TABLE for a sequence */
1525  istmt.objtype = OBJECT_TABLE;
1526  break;
1527  case DatabaseRelationId:
1528  istmt.objtype = OBJECT_DATABASE;
1529  break;
1530  case TypeRelationId:
1531  istmt.objtype = OBJECT_TYPE;
1532  break;
1533  case ProcedureRelationId:
1534  istmt.objtype = OBJECT_ROUTINE;
1535  break;
1536  case LanguageRelationId:
1537  istmt.objtype = OBJECT_LANGUAGE;
1538  break;
1539  case LargeObjectRelationId:
1540  istmt.objtype = OBJECT_LARGEOBJECT;
1541  break;
1542  case NamespaceRelationId:
1543  istmt.objtype = OBJECT_SCHEMA;
1544  break;
1545  case TableSpaceRelationId:
1546  istmt.objtype = OBJECT_TABLESPACE;
1547  break;
1548  case ForeignServerRelationId:
1550  break;
1551  case ForeignDataWrapperRelationId:
1552  istmt.objtype = OBJECT_FDW;
1553  break;
1554  case ParameterAclRelationId:
1555  istmt.objtype = OBJECT_PARAMETER_ACL;
1556  break;
1557  default:
1558  elog(ERROR, "unexpected object class %u", classid);
1559  break;
1560  }
1561  istmt.is_grant = false;
1562  istmt.objects = list_make1_oid(objid);
1563  istmt.all_privs = true;
1564  istmt.privileges = ACL_NO_RIGHTS;
1565  istmt.col_privs = NIL;
1566  istmt.grantees = list_make1_oid(roleid);
1567  istmt.grant_option = false;
1568  istmt.behavior = DROP_CASCADE;
1569 
1570  ExecGrantStmt_oids(&istmt);
1571  }
1572 }
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition: aclchk.c:1197
@ DROP_CASCADE
Definition: parsenodes.h:1936
FormData_pg_default_acl * Form_pg_default_acl
#define list_make1_oid(x1)
Definition: pg_list.h:240

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().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)

Definition at line 5104 of file acl.c.

5105 {
5106  Oid admin_role;
5107 
5108  /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5109  if (member == role)
5110  return InvalidOid;
5111 
5112  (void) roles_is_member_of(member, ROLERECURSE_PRIVS, role, &admin_role);
5113  return admin_role;
5114 }

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

5162 {
5163  AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges);
5164  List *roles_list;
5165  int nrights;
5166  ListCell *l;
5167 
5168  /*
5169  * The object owner is always treated as having all grant options, so if
5170  * roleId is the owner it's easy. Also, if roleId is a superuser it's
5171  * easy: superusers are implicitly members of every role, so they act as
5172  * the object owner.
5173  */
5174  if (roleId == ownerId || superuser_arg(roleId))
5175  {
5176  *grantorId = ownerId;
5177  *grantOptions = needed_goptions;
5178  return;
5179  }
5180 
5181  /*
5182  * Otherwise we have to do a careful search to see if roleId has the
5183  * privileges of any suitable role. Note: we can hang onto the result of
5184  * roles_is_member_of() throughout this loop, because aclmask_direct()
5185  * doesn't query any role memberships.
5186  */
5187  roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS,
5188  InvalidOid, NULL);
5189 
5190  /* initialize candidate result as default */
5191  *grantorId = roleId;
5192  *grantOptions = ACL_NO_RIGHTS;
5193  nrights = 0;
5194 
5195  foreach(l, roles_list)
5196  {
5197  Oid otherrole = lfirst_oid(l);
5198  AclMode otherprivs;
5199 
5200  otherprivs = aclmask_direct(acl, otherrole, ownerId,
5201  needed_goptions, ACLMASK_ALL);
5202  if (otherprivs == needed_goptions)
5203  {
5204  /* Found a suitable grantor */
5205  *grantorId = otherrole;
5206  *grantOptions = otherprivs;
5207  return;
5208  }
5209 
5210  /*
5211  * If it has just some of the needed privileges, remember best
5212  * candidate.
5213  */
5214  if (otherprivs != ACL_NO_RIGHTS)
5215  {
5216  int nnewrights = count_one_bits(otherprivs);
5217 
5218  if (nnewrights > nrights)
5219  {
5220  *grantorId = otherrole;
5221  *grantOptions = otherprivs;
5222  nrights = nnewrights;
5223  }
5224  }
5225  }
5226 }
static int count_one_bits(AclMode mask)
Definition: acl.c:5119
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition: acl.c:1423
#define ACL_GRANT_OPTION_FOR(privs)
Definition: acl.h:70
#define lfirst_oid(lc)
Definition: pg_list.h:172

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_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Parameter(), ExecGrant_Relation(), ExecGrant_Tablespace(), and ExecGrant_Type().