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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

#define ACL_ID_PUBLIC   0 /* placeholder for id in a PUBLIC acl item */
 
#define ACLITEM_GET_PRIVS(item)   ((item).ai_privs & 0xFFFFFFFF)
 
#define ACLITEM_GET_GOPTIONS(item)   (((item).ai_privs >> 32) & 0xFFFFFFFF)
 
#define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
 
#define ACL_GRANT_OPTION_FOR(privs)   (((AclMode) (privs) & 0xFFFFFFFF) << 32)
 
#define ACL_OPTION_TO_PRIVS(privs)   (((AclMode) (privs) >> 32) & 0xFFFFFFFF)
 
#define ACLITEM_SET_PRIVS(item, privs)
 
#define ACLITEM_SET_GOPTIONS(item, goptions)
 
#define ACLITEM_SET_RIGHTS(item, rights)    ((item).ai_privs = (AclMode) (rights))
 
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
 
#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)
 
#define ACLITEM_ALL_GOPTION_BITS   ((AclMode) 0xFFFFFFFF << 32)
 
#define ACL_NUM(ACL)   (ARR_DIMS(ACL)[0])
 
#define ACL_DAT(ACL)   ((AclItem *) ARR_DATA_PTR(ACL))
 
#define ACL_N_SIZE(N)   (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
 
#define ACL_SIZE(ACL)   ARR_SIZE(ACL)
 
#define DatumGetAclItemP(X)   ((AclItem *) DatumGetPointer(X))
 
#define PG_GETARG_ACLITEM_P(n)   DatumGetAclItemP(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ACLITEM_P(x)   PG_RETURN_POINTER(x)
 
#define DatumGetAclP(X)   ((Acl *) PG_DETOAST_DATUM(X))
 
#define DatumGetAclPCopy(X)   ((Acl *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_ACL_P(n)   DatumGetAclP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_ACL_P_COPY(n)   DatumGetAclPCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_ACL_P(x)   PG_RETURN_POINTER(x)
 
#define ACL_MODECHG_ADD   1
 
#define ACL_MODECHG_DEL   2
 
#define ACL_MODECHG_EQL   3
 
#define ACL_INSERT_CHR   'a' /* formerly known as "append" */
 
#define ACL_SELECT_CHR   'r' /* formerly known as "read" */
 
#define ACL_UPDATE_CHR   'w' /* formerly known as "write" */
 
#define ACL_DELETE_CHR   'd'
 
#define ACL_TRUNCATE_CHR   'D' /* super-delete, as it were */
 
#define ACL_REFERENCES_CHR   'x'
 
#define ACL_TRIGGER_CHR   't'
 
#define ACL_EXECUTE_CHR   'X'
 
#define ACL_USAGE_CHR   'U'
 
#define ACL_CREATE_CHR   'C'
 
#define ACL_CREATE_TEMP_CHR   'T'
 
#define ACL_CONNECT_CHR   'c'
 
#define ACL_SET_CHR   's'
 
#define ACL_ALTER_SYSTEM_CHR   'A'
 
#define ACL_MAINTAIN_CHR   'm'
 
#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"
 
#define ACL_ALL_RIGHTS_COLUMN   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
 
#define ACL_ALL_RIGHTS_RELATION   (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER|ACL_MAINTAIN)
 
#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
 
#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)
 
#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)
 
#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)
 
#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)
 
#define ACL_ALL_RIGHTS_PROPGRAPH   (ACL_SELECT)
 
#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)
 
charget_rolespec_name (const RoleSpec *role)
 
void select_best_grantor (const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult object_aclcheck (Oid classid, Oid objectid, Oid roleid, AclMode mode)
 
AclResult object_aclcheck_ext (Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_attribute_aclcheck_all_ext (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_parameter_aclcheck (const char *name, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
void ReplaceRoleInInitPriv (Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
 
void RemoveRoleFromInitPriv (Oid roleid, Oid classid, Oid objid, int32 objsubid)
 
bool object_ownercheck (Oid classid, Oid objectid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_PROPGRAPH

#define ACL_ALL_RIGHTS_PROPGRAPH   (ACL_SELECT)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 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_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

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

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

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

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

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

Definition at line 76 of file acl.h.

176{
177 ACLMASK_ALL, /* normal case: compute all bits */
178 ACLMASK_ANY, /* return when result is known nonzero */
179} AclMaskHow;
180
181/* result codes for pg_*_aclcheck */
182typedef enum
183{
184 ACLCHECK_OK = 0,
187} AclResult;
188
189
190/*
191 * routines used internally
192 */
193extern Acl *acldefault(ObjectType objtype, Oid ownerId);
194extern Acl *get_user_default_acl(ObjectType objtype, Oid ownerId,
195 Oid nsp_oid);
196extern void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId,
197 Oid ownerId, Acl *acl);
198
199extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
200 int modechg, Oid ownerId, DropBehavior behavior);
202extern Acl *make_empty_acl(void);
203extern Acl *aclcopy(const Acl *orig_acl);
204extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl);
205extern Acl *aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId);
206extern void aclitemsort(Acl *acl);
207extern bool aclequal(const Acl *left_acl, const Acl *right_acl);
208
209extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
210 AclMode mask, AclMaskHow how);
211extern int aclmembers(const Acl *acl, Oid **roleids);
212
213extern bool has_privs_of_role(Oid member, Oid role);
214extern bool member_can_set_role(Oid member, Oid role);
215extern void check_can_set_role(Oid member, Oid role);
216extern bool is_member_of_role(Oid member, Oid role);
217extern bool is_member_of_role_nosuper(Oid member, Oid role);
218extern bool is_admin_of_role(Oid member, Oid role);
219extern Oid select_best_admin(Oid member, Oid role);
220extern Oid get_role_oid(const char *rolname, bool missing_ok);
221extern Oid get_role_oid_or_public(const char *rolname);
222extern Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok);
223extern void check_rolespec_name(const RoleSpec *role, const char *detail_msg);
224extern HeapTuple get_rolespec_tuple(const RoleSpec *role);
225extern char *get_rolespec_name(const RoleSpec *role);
226
227extern void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges,
228 const Acl *acl, Oid ownerId,
230
231extern void initialize_acl(void);
232
233/*
234 * prototypes for functions in aclchk.c
235 */
236extern void ExecuteGrantStmt(GrantStmt *stmt);
238
239extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
240
242 AclMode mask, AclMaskHow how);
243
244/* generic functions */
246 Oid roleid, AclMode mode);
248 Oid roleid, AclMode mode,
249 bool *is_missing);
250
251/* special cases */
253 Oid roleid, AclMode mode);
255 Oid roleid, AclMode mode,
256 bool *is_missing);
261 bool *is_missing);
264 AclMode mode, bool *is_missing);
265extern AclResult pg_parameter_aclcheck(const char *name, Oid roleid,
266 AclMode mode);
268 AclMode mode, Snapshot snapshot);
269
270extern void aclcheck_error(AclResult aclerr, ObjectType objtype,
271 const char *objectname);
272
273extern void aclcheck_error_col(AclResult aclerr, ObjectType objtype,
274 const char *objectname, const char *colname);
275
276extern void aclcheck_error_type(AclResult aclerr, Oid typeOid);
277
278extern void recordExtObjInitPriv(Oid objoid, Oid classoid);
279extern void removeExtObjInitPriv(Oid objoid, Oid classoid);
281 Oid classid, Oid objid, int32 objsubid);
282extern void RemoveRoleFromInitPriv(Oid roleid,
283 Oid classid, Oid objid, int32 objsubid);
284
285
286/* ownercheck routines just return true (owner) or false (not) */
287extern bool object_ownercheck(Oid classid, Oid objectid, Oid roleid);
288extern bool has_createrole_privilege(Oid roleid);
289extern bool has_bypassrls_privilege(Oid roleid);
290
291#endif /* ACL_H */
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3890
void initialize_acl(void)
Definition acl.c:5069
void ExecuteGrantStmt(GrantStmt *stmt)
Definition aclchk.c:395
AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
Definition aclchk.c:4120
void RemoveRoleFromInitPriv(Oid roleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4911
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5444
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:491
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition acl.c:515
bool has_bypassrls_privilege(Oid roleid)
Definition aclchk.c:4232
AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:4093
void aclcheck_error_col(AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
Definition aclchk.c:2967
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3965
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4371
Oid select_best_admin(Oid member, Oid role)
Definition acl.c:5469
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
Oid get_role_oid_or_public(const char *rolname)
Definition acl.c:5623
void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
Definition aclchk.c:915
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:573
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
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
Definition aclchk.c:3954
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1020
bool is_member_of_role(Oid member, Oid role)
Definition acl.c:5394
AclResult pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
Definition aclchk.c:4108
void ReplaceRoleInInitPriv(Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4802
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition acl.c:5422
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
Acl * make_empty_acl(void)
Definition acl.c:462
void recordExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4398
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1568
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1147
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5348
Acl * aclcopy(const Acl *orig_acl)
Definition acl.c:471
void aclitemsort(Acl *acl)
Definition acl.c:559
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1416
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
Definition aclchk.c:3912
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5605
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3880
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4134
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3924
char * get_rolespec_name(const RoleSpec *role)
Definition acl.c:5724
void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5508
void check_can_set_role(Oid member, Oid role)
Definition acl.c:5371
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3298
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5746
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition aclchk.c:2997
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4213
AclMaskHow
Definition acl.h:176
@ ACLMASK_ANY
Definition acl.h:178
@ ACLMASK_ALL
Definition acl.h:177
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5639
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4291
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition aclchk.c:1426
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition aclchk.c:4083
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5678
void removeExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4562
int16 AttrNumber
Definition attnum.h:21
int32_t int32
Definition c.h:620
#define stmt
DropBehavior
ObjectType
int16 attnum
NameData rolname
Definition pg_authid.h:36
static PgChecksumMode mode
unsigned int Oid
Definition acl.h:55
const char * name

◆ 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

Definition at line 106 of file acl.h.

◆ AclItem

Enumeration Type Documentation

◆ 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;

◆ AclResult

Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 182 of file acl.h.

Function Documentation

◆ aclcheck_error()

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

Definition at line 2672 of file aclchk.c.

2674{
2675 switch (aclerr)
2676 {
2677 case ACLCHECK_OK:
2678 /* no error, so return to caller */
2679 break;
2680 case ACLCHECK_NO_PRIV:
2681 {
2682 const char *msg = "???";
2683
2684 switch (objtype)
2685 {
2686 case OBJECT_AGGREGATE:
2687 msg = gettext_noop("permission denied for aggregate %s");
2688 break;
2689 case OBJECT_COLLATION:
2690 msg = gettext_noop("permission denied for collation %s");
2691 break;
2692 case OBJECT_COLUMN:
2693 msg = gettext_noop("permission denied for column %s");
2694 break;
2695 case OBJECT_CONVERSION:
2696 msg = gettext_noop("permission denied for conversion %s");
2697 break;
2698 case OBJECT_DATABASE:
2699 msg = gettext_noop("permission denied for database %s");
2700 break;
2701 case OBJECT_DOMAIN:
2702 msg = gettext_noop("permission denied for domain %s");
2703 break;
2705 msg = gettext_noop("permission denied for event trigger %s");
2706 break;
2707 case OBJECT_EXTENSION:
2708 msg = gettext_noop("permission denied for extension %s");
2709 break;
2710 case OBJECT_FDW:
2711 msg = gettext_noop("permission denied for foreign-data wrapper %s");
2712 break;
2714 msg = gettext_noop("permission denied for foreign server %s");
2715 break;
2717 msg = gettext_noop("permission denied for foreign table %s");
2718 break;
2719 case OBJECT_FUNCTION:
2720 msg = gettext_noop("permission denied for function %s");
2721 break;
2722 case OBJECT_INDEX:
2723 msg = gettext_noop("permission denied for index %s");
2724 break;
2725 case OBJECT_LANGUAGE:
2726 msg = gettext_noop("permission denied for language %s");
2727 break;
2728 case OBJECT_LARGEOBJECT:
2729 msg = gettext_noop("permission denied for large object %s");
2730 break;
2731 case OBJECT_MATVIEW:
2732 msg = gettext_noop("permission denied for materialized view %s");
2733 break;
2734 case OBJECT_OPCLASS:
2735 msg = gettext_noop("permission denied for operator class %s");
2736 break;
2737 case OBJECT_OPERATOR:
2738 msg = gettext_noop("permission denied for operator %s");
2739 break;
2740 case OBJECT_OPFAMILY:
2741 msg = gettext_noop("permission denied for operator family %s");
2742 break;
2744 msg = gettext_noop("permission denied for parameter %s");
2745 break;
2746 case OBJECT_POLICY:
2747 msg = gettext_noop("permission denied for policy %s");
2748 break;
2749 case OBJECT_PROCEDURE:
2750 msg = gettext_noop("permission denied for procedure %s");
2751 break;
2752 case OBJECT_PROPGRAPH:
2753 msg = gettext_noop("permission denied for property graph %s");
2754 break;
2755 case OBJECT_PUBLICATION:
2756 msg = gettext_noop("permission denied for publication %s");
2757 break;
2758 case OBJECT_ROUTINE:
2759 msg = gettext_noop("permission denied for routine %s");
2760 break;
2761 case OBJECT_SCHEMA:
2762 msg = gettext_noop("permission denied for schema %s");
2763 break;
2764 case OBJECT_SEQUENCE:
2765 msg = gettext_noop("permission denied for sequence %s");
2766 break;
2768 msg = gettext_noop("permission denied for statistics object %s");
2769 break;
2771 msg = gettext_noop("permission denied for subscription %s");
2772 break;
2773 case OBJECT_TABLE:
2774 msg = gettext_noop("permission denied for table %s");
2775 break;
2776 case OBJECT_TABLESPACE:
2777 msg = gettext_noop("permission denied for tablespace %s");
2778 break;
2780 msg = gettext_noop("permission denied for text search configuration %s");
2781 break;
2783 msg = gettext_noop("permission denied for text search dictionary %s");
2784 break;
2785 case OBJECT_TYPE:
2786 msg = gettext_noop("permission denied for type %s");
2787 break;
2788 case OBJECT_VIEW:
2789 msg = gettext_noop("permission denied for view %s");
2790 break;
2791 /* these currently aren't used */
2793 case OBJECT_AMOP:
2794 case OBJECT_AMPROC:
2795 case OBJECT_ATTRIBUTE:
2796 case OBJECT_CAST:
2797 case OBJECT_DEFAULT:
2798 case OBJECT_DEFACL:
2802 case OBJECT_ROLE:
2803 case OBJECT_RULE:
2805 case OBJECT_TRANSFORM:
2806 case OBJECT_TRIGGER:
2807 case OBJECT_TSPARSER:
2808 case OBJECT_TSTEMPLATE:
2810 elog(ERROR, "unsupported object type: %d", objtype);
2811 }
2812
2813 ereport(ERROR,
2815 errmsg(msg, objectname)));
2816 break;
2817 }
2818 case ACLCHECK_NOT_OWNER:
2819 {
2820 const char *msg = "???";
2821
2822 switch (objtype)
2823 {
2824 case OBJECT_AGGREGATE:
2825 msg = gettext_noop("must be owner of aggregate %s");
2826 break;
2827 case OBJECT_COLLATION:
2828 msg = gettext_noop("must be owner of collation %s");
2829 break;
2830 case OBJECT_CONVERSION:
2831 msg = gettext_noop("must be owner of conversion %s");
2832 break;
2833 case OBJECT_DATABASE:
2834 msg = gettext_noop("must be owner of database %s");
2835 break;
2836 case OBJECT_DOMAIN:
2837 msg = gettext_noop("must be owner of domain %s");
2838 break;
2840 msg = gettext_noop("must be owner of event trigger %s");
2841 break;
2842 case OBJECT_EXTENSION:
2843 msg = gettext_noop("must be owner of extension %s");
2844 break;
2845 case OBJECT_FDW:
2846 msg = gettext_noop("must be owner of foreign-data wrapper %s");
2847 break;
2849 msg = gettext_noop("must be owner of foreign server %s");
2850 break;
2852 msg = gettext_noop("must be owner of foreign table %s");
2853 break;
2854 case OBJECT_FUNCTION:
2855 msg = gettext_noop("must be owner of function %s");
2856 break;
2857 case OBJECT_INDEX:
2858 msg = gettext_noop("must be owner of index %s");
2859 break;
2860 case OBJECT_LANGUAGE:
2861 msg = gettext_noop("must be owner of language %s");
2862 break;
2863 case OBJECT_LARGEOBJECT:
2864 msg = gettext_noop("must be owner of large object %s");
2865 break;
2866 case OBJECT_MATVIEW:
2867 msg = gettext_noop("must be owner of materialized view %s");
2868 break;
2869 case OBJECT_OPCLASS:
2870 msg = gettext_noop("must be owner of operator class %s");
2871 break;
2872 case OBJECT_OPERATOR:
2873 msg = gettext_noop("must be owner of operator %s");
2874 break;
2875 case OBJECT_OPFAMILY:
2876 msg = gettext_noop("must be owner of operator family %s");
2877 break;
2878 case OBJECT_PROCEDURE:
2879 msg = gettext_noop("must be owner of procedure %s");
2880 break;
2881 case OBJECT_PROPGRAPH:
2882 msg = gettext_noop("must be owner of property graph %s");
2883 break;
2884 case OBJECT_PUBLICATION:
2885 msg = gettext_noop("must be owner of publication %s");
2886 break;
2887 case OBJECT_ROUTINE:
2888 msg = gettext_noop("must be owner of routine %s");
2889 break;
2890 case OBJECT_SEQUENCE:
2891 msg = gettext_noop("must be owner of sequence %s");
2892 break;
2894 msg = gettext_noop("must be owner of subscription %s");
2895 break;
2896 case OBJECT_TABLE:
2897 msg = gettext_noop("must be owner of table %s");
2898 break;
2899 case OBJECT_TYPE:
2900 msg = gettext_noop("must be owner of type %s");
2901 break;
2902 case OBJECT_VIEW:
2903 msg = gettext_noop("must be owner of view %s");
2904 break;
2905 case OBJECT_SCHEMA:
2906 msg = gettext_noop("must be owner of schema %s");
2907 break;
2909 msg = gettext_noop("must be owner of statistics object %s");
2910 break;
2911 case OBJECT_TABLESPACE:
2912 msg = gettext_noop("must be owner of tablespace %s");
2913 break;
2915 msg = gettext_noop("must be owner of text search configuration %s");
2916 break;
2918 msg = gettext_noop("must be owner of text search dictionary %s");
2919 break;
2920
2921 /*
2922 * Special cases: For these, the error message talks
2923 * about "relation", because that's where the
2924 * ownership is attached. See also
2925 * check_object_ownership().
2926 */
2927 case OBJECT_COLUMN:
2928 case OBJECT_POLICY:
2929 case OBJECT_RULE:
2931 case OBJECT_TRIGGER:
2932 msg = gettext_noop("must be owner of relation %s");
2933 break;
2934 /* these currently aren't used */
2936 case OBJECT_AMOP:
2937 case OBJECT_AMPROC:
2938 case OBJECT_ATTRIBUTE:
2939 case OBJECT_CAST:
2940 case OBJECT_DEFAULT:
2941 case OBJECT_DEFACL:
2946 case OBJECT_ROLE:
2947 case OBJECT_TRANSFORM:
2948 case OBJECT_TSPARSER:
2949 case OBJECT_TSTEMPLATE:
2951 elog(ERROR, "unsupported object type: %d", objtype);
2952 }
2953
2954 ereport(ERROR,
2956 errmsg(msg, objectname)));
2957 break;
2958 }
2959 default:
2960 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2961 break;
2962 }
2963}
#define gettext_noop(x)
Definition c.h:1285
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
static char * errmsg
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ OBJECT_PROPGRAPH
@ OBJECT_ACCESS_METHOD
@ OBJECT_OPCLASS
@ OBJECT_DEFACL
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_SCHEMA
@ OBJECT_POLICY
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_COLUMN
@ OBJECT_TABLESPACE
@ OBJECT_ROLE
@ OBJECT_ROUTINE
@ OBJECT_LARGEOBJECT
@ OBJECT_PUBLICATION_NAMESPACE
@ OBJECT_PROCEDURE
@ OBJECT_EXTENSION
@ OBJECT_INDEX
@ OBJECT_DEFAULT
@ OBJECT_DATABASE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_LANGUAGE
@ OBJECT_AMOP
@ OBJECT_PUBLICATION_REL
@ OBJECT_FOREIGN_SERVER
@ OBJECT_TSDICTIONARY
@ OBJECT_ATTRIBUTE
@ OBJECT_PUBLICATION
@ OBJECT_RULE
@ OBJECT_CONVERSION
@ OBJECT_AMPROC
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_PARAMETER_ACL
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_SUBSCRIPTION
@ OBJECT_STATISTIC_EXT
@ OBJECT_CAST
@ OBJECT_TRIGGER
@ OBJECT_TRANSFORM

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg, ERROR, fb(), 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_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

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

◆ aclcheck_error_col()

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

Definition at line 2967 of file aclchk.c.

2969{
2970 switch (aclerr)
2971 {
2972 case ACLCHECK_OK:
2973 /* no error, so return to caller */
2974 break;
2975 case ACLCHECK_NO_PRIV:
2976 ereport(ERROR,
2978 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2979 colname, objectname)));
2980 break;
2981 case ACLCHECK_NOT_OWNER:
2982 /* relation msg is OK since columns don't have separate owners */
2983 aclcheck_error(aclerr, objtype, objectname);
2984 break;
2985 default:
2986 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2987 break;
2988 }
2989}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672

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

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

◆ aclconcat()

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

Definition at line 491 of file acl.c.

492{
494
496
499 ACL_NUM(left_acl) * sizeof(AclItem));
500
503 ACL_NUM(right_acl) * sizeof(AclItem));
504
505 return result_acl;
506}
static Acl * allocacl(int n)
Definition acl.c:440
#define ACL_DAT(ACL)
Definition acl.h:109
#define ACL_NUM(ACL)
Definition acl.h:108
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))

References ACL_DAT, ACL_NUM, allocacl(), fb(), and memcpy().

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl * aclcopy ( const Acl orig_acl)
extern

Definition at line 471 of file acl.c.

472{
474
476
479 ACL_NUM(orig_acl) * sizeof(AclItem));
480
481 return result_acl;
482}

References ACL_DAT, ACL_NUM, allocacl(), fb(), and memcpy().

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)
extern

Definition at line 827 of file acl.c.

828{
831 int nacl;
832 Acl *acl;
833 AclItem *aip;
834
835 switch (objtype)
836 {
837 case OBJECT_COLUMN:
838 /* by default, columns have no extra privileges */
841 break;
842 case OBJECT_TABLE:
845 break;
846 case OBJECT_SEQUENCE:
849 break;
850 case OBJECT_DATABASE:
851 /* for backwards compatibility, grant some rights by default */
854 break;
855 case OBJECT_FUNCTION:
856 /* Grant EXECUTE by default, for now */
859 break;
860 case OBJECT_LANGUAGE:
861 /* Grant USAGE by default, for now */
864 break;
868 break;
869 case OBJECT_SCHEMA:
872 break;
876 break;
877 case OBJECT_FDW:
880 break;
884 break;
885 case OBJECT_DOMAIN:
886 case OBJECT_TYPE:
889 break;
893 break;
894 case OBJECT_PROPGRAPH:
897 break;
898 default:
899 elog(ERROR, "unrecognized object type: %d", (int) objtype);
900 world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
902 break;
903 }
904
905 nacl = 0;
907 nacl++;
909 nacl++;
910
911 acl = allocacl(nacl);
912 aip = ACL_DAT(acl);
913
915 {
916 aip->ai_grantee = ACL_ID_PUBLIC;
917 aip->ai_grantor = ownerId;
919 aip++;
920 }
921
922 /*
923 * Note that the owner's entry shows all ordinary privileges but no grant
924 * options. This is because his grant options come "from the system" and
925 * not from his own efforts. (The SQL spec says that the owner's rights
926 * come from a "_SYSTEM" authid.) However, we do consider that the
927 * owner's ordinary privileges are self-granted; this lets him revoke
928 * them. We implement the owner's grant options without any explicit
929 * "_SYSTEM"-like ACL entry, by internally special-casing the owner
930 * wherever we are testing grant options.
931 */
933 {
934 aip->ai_grantee = ownerId;
935 aip->ai_grantor = ownerId;
937 }
938
939 return acl;
940}
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition acl.h:164
#define ACL_ALL_RIGHTS_TABLESPACE
Definition acl.h:171
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition acl.h:168
#define ACL_ALL_RIGHTS_SCHEMA
Definition acl.h:170
#define ACL_ALL_RIGHTS_SEQUENCE
Definition acl.h:161
#define ACL_ALL_RIGHTS_DATABASE
Definition acl.h:162
#define ACL_ALL_RIGHTS_PROPGRAPH
Definition acl.h:169
#define ACL_ALL_RIGHTS_FUNCTION
Definition acl.h:165
#define ACL_ALL_RIGHTS_LANGUAGE
Definition acl.h:166
#define ACL_ALL_RIGHTS_TYPE
Definition acl.h:172
#define ACL_ALL_RIGHTS_FDW
Definition acl.h:163
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition acl.h:160
#define ACL_ID_PUBLIC
Definition acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition acl.h:167
#define ACL_CREATE_TEMP
Definition parsenodes.h:86
#define ACL_USAGE
Definition parsenodes.h:84
#define ACL_NO_RIGHTS
Definition parsenodes.h:92
#define ACL_CONNECT
Definition parsenodes.h:87
#define ACL_EXECUTE
Definition parsenodes.h:83

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_PROPGRAPH, 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, allocacl(), elog, ERROR, fb(), OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROPGRAPH, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

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

◆ aclequal()

bool aclequal ( const Acl left_acl,
const Acl right_acl 
)
extern

Definition at line 573 of file acl.c.

574{
575 /* Check for cases where one or both are empty/null */
576 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
577 {
578 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
579 return true;
580 else
581 return false;
582 }
583 else
584 {
585 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
586 return false;
587 }
588
590 return false;
591
594 ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
595 return true;
596
597 return false;
598}

References ACL_DAT, ACL_NUM, and fb().

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

◆ aclitemsort()

void aclitemsort ( Acl acl)
extern

Definition at line 559 of file acl.c.

560{
561 if (acl != NULL && ACL_NUM(acl) > 1)
562 qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
563}
static int aclitemComparator(const void *arg1, const void *arg2)
Definition acl.c:748
#define qsort(a, b, c, d)
Definition port.h:496

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

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclmask()

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

Definition at line 1416 of file acl.c.

1418{
1421 AclItem *aidat;
1422 int i,
1423 num;
1424
1425 /*
1426 * Null ACL should not happen, since caller should have inserted
1427 * appropriate default
1428 */
1429 if (acl == NULL)
1430 elog(ERROR, "null ACL");
1431
1432 check_acl(acl);
1433
1434 /* Quick exit for mask == 0 */
1435 if (mask == 0)
1436 return 0;
1437
1438 result = 0;
1439
1440 /* Owner always implicitly has all grant options */
1441 if ((mask & ACLITEM_ALL_GOPTION_BITS) &&
1442 has_privs_of_role(roleid, ownerId))
1443 {
1445 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1446 return result;
1447 }
1448
1449 num = ACL_NUM(acl);
1450 aidat = ACL_DAT(acl);
1451
1452 /*
1453 * Check privileges granted directly to roleid or to public
1454 */
1455 for (i = 0; i < num; i++)
1456 {
1457 AclItem *aidata = &aidat[i];
1458
1459 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1460 aidata->ai_grantee == roleid)
1461 {
1462 result |= aidata->ai_privs & mask;
1463 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1464 return result;
1465 }
1466 }
1467
1468 /*
1469 * Check privileges granted indirectly via role memberships. We do this in
1470 * a separate pass to minimize expensive indirect membership tests. In
1471 * particular, it's worth testing whether a given ACL entry grants any
1472 * privileges still of interest before we perform the has_privs_of_role
1473 * test.
1474 */
1475 remaining = mask & ~result;
1476 for (i = 0; i < num; i++)
1477 {
1478 AclItem *aidata = &aidat[i];
1479
1480 if (aidata->ai_grantee == ACL_ID_PUBLIC ||
1481 aidata->ai_grantee == roleid)
1482 continue; /* already checked it */
1483
1484 if ((aidata->ai_privs & remaining) &&
1485 has_privs_of_role(roleid, aidata->ai_grantee))
1486 {
1487 result |= aidata->ai_privs & mask;
1488 if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
1489 return result;
1490 remaining = mask & ~result;
1491 }
1492 }
1493
1494 return result;
1495}
static void check_acl(const Acl *acl)
Definition acl.c:604
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
#define ACLITEM_ALL_GOPTION_BITS
Definition acl.h:88
uint32 result
int remaining
Definition informix.c:692
int i
Definition isn.c:77
AclMode ai_privs
Definition acl.h:58

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

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

◆ aclmembers()

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

Definition at line 1568 of file acl.c.

1569{
1570 Oid *list;
1571 const AclItem *acldat;
1572 int i,
1573 j;
1574
1575 if (acl == NULL || ACL_NUM(acl) == 0)
1576 {
1577 *roleids = NULL;
1578 return 0;
1579 }
1580
1581 check_acl(acl);
1582
1583 /* Allocate the worst-case space requirement */
1584 list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1585 acldat = ACL_DAT(acl);
1586
1587 /*
1588 * Walk the ACL collecting mentioned RoleIds.
1589 */
1590 j = 0;
1591 for (i = 0; i < ACL_NUM(acl); i++)
1592 {
1593 const AclItem *ai = &acldat[i];
1594
1595 if (ai->ai_grantee != ACL_ID_PUBLIC)
1596 list[j++] = ai->ai_grantee;
1597 /* grantor is currently never PUBLIC, but let's check anyway */
1598 if (ai->ai_grantor != ACL_ID_PUBLIC)
1599 list[j++] = ai->ai_grantor;
1600 }
1601
1602 /* Sort the array */
1603 qsort(list, j, sizeof(Oid), oid_cmp);
1604
1605 /*
1606 * We could repalloc the array down to minimum size, but it's hardly worth
1607 * it since it's only transient memory.
1608 */
1609 *roleids = list;
1610
1611 /* Remove duplicates from the array */
1612 return qunique(list, j, sizeof(Oid), oid_cmp);
1613}
int j
Definition isn.c:78
void * palloc(Size size)
Definition mcxt.c:1390
int oid_cmp(const void *p1, const void *p2)
Definition oid.c:287
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, check_acl(), fb(), i, j, oid_cmp(), palloc(), qsort, and qunique().

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

◆ aclmerge()

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

Definition at line 515 of file acl.c.

516{
518 AclItem *aip;
519 int i,
520 num;
521
522 /* Check for cases where one or both are empty/null */
523 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
524 {
525 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
526 return NULL;
527 else
528 return aclcopy(right_acl);
529 }
530 else
531 {
532 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
533 return aclcopy(left_acl);
534 }
535
536 /* Merge them the hard way, one item at a time */
538
540 num = ACL_NUM(right_acl);
541
542 for (i = 0; i < num; i++, aip++)
543 {
544 Acl *tmp_acl;
545
547 ownerId, DROP_RESTRICT);
550 }
551
552 return result_acl;
553}
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1020
Acl * aclcopy(const Acl *orig_acl)
Definition acl.c:471
#define ACL_MODECHG_ADD
Definition acl.h:129
void pfree(void *pointer)
Definition mcxt.c:1619
@ DROP_RESTRICT

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

Referenced by get_user_default_acl().

◆ aclnewowner()

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

Definition at line 1147 of file acl.c.

1148{
1149 Acl *new_acl;
1155 bool newpresent = false;
1156 int dst,
1157 src,
1158 targ,
1159 num;
1160
1162
1163 /*
1164 * Make a copy of the given ACL, substituting new owner ID for old
1165 * wherever it appears as either grantor or grantee. Also note if the new
1166 * owner ID is already present.
1167 */
1168 num = ACL_NUM(old_acl);
1170 new_acl = allocacl(num);
1172 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1173 for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1174 {
1175 if (dst_aip->ai_grantor == oldOwnerId)
1176 dst_aip->ai_grantor = newOwnerId;
1177 else if (dst_aip->ai_grantor == newOwnerId)
1178 newpresent = true;
1179 if (dst_aip->ai_grantee == oldOwnerId)
1180 dst_aip->ai_grantee = newOwnerId;
1181 else if (dst_aip->ai_grantee == newOwnerId)
1182 newpresent = true;
1183 }
1184
1185 /*
1186 * If the old ACL contained any references to the new owner, then we may
1187 * now have generated an ACL containing duplicate entries. Find them and
1188 * merge them so that there are not duplicates. (This is relatively
1189 * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1190 * be the normal case.)
1191 *
1192 * To simplify deletion of duplicate entries, we temporarily leave them in
1193 * the array but set their privilege masks to zero; when we reach such an
1194 * entry it's just skipped. (Thus, a side effect of this code will be to
1195 * remove privilege-free entries, should there be any in the input.) dst
1196 * is the next output slot, targ is the currently considered input slot
1197 * (always >= dst), and src scans entries to the right of targ looking for
1198 * duplicates. Once an entry has been emitted to dst it is known
1199 * duplicate-free and need not be considered anymore.
1200 */
1201 if (newpresent)
1202 {
1203 dst = 0;
1204 for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1205 {
1206 /* ignore if deleted in an earlier pass */
1208 continue;
1209 /* find and merge any duplicates */
1210 for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1211 src++, src_aip++)
1212 {
1214 continue;
1216 {
1220 /* mark the duplicate deleted */
1222 }
1223 }
1224 /* and emit to output */
1225 new_aip[dst] = *targ_aip;
1226 dst++;
1227 }
1228 /* Adjust array size to be 'dst' items */
1229 ARR_DIMS(new_acl)[0] = dst;
1231 }
1232
1233 return new_acl;
1234}
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition acl.c:737
#define ACL_N_SIZE(N)
Definition acl.h:110
#define ACLITEM_GET_RIGHTS(item)
Definition acl.h:68
#define ACLITEM_SET_RIGHTS(item, rights)
Definition acl.h:79
#define ARR_DIMS(a)
Definition array.h:294
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References ACL_DAT, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_RIGHTS, allocacl(), ARR_DIMS, check_acl(), fb(), memcpy(), and SET_VARSIZE().

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

◆ aclupdate()

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

Definition at line 1020 of file acl.c.

1022{
1023 Acl *new_acl = NULL;
1025 *new_aip = NULL;
1028 new_rights,
1030 int dst,
1031 num;
1032
1033 /* Caller probably already checked old_acl, but be safe */
1035
1036 /* If granting grant options, check for circularity */
1037 if (modechg != ACL_MODECHG_DEL &&
1040
1041 num = ACL_NUM(old_acl);
1043
1044 /*
1045 * Search the ACL for an existing entry for this grantee and grantor. If
1046 * one exists, just modify the entry in-place (well, in the same position,
1047 * since we actually return a copy); otherwise, insert the new entry at
1048 * the end.
1049 */
1050
1051 for (dst = 0; dst < num; ++dst)
1052 {
1054 {
1055 /* found a match, so modify existing item */
1056 new_acl = allocacl(num);
1059 break;
1060 }
1061 }
1062
1063 if (dst == num)
1064 {
1065 /* need to append a new item */
1066 new_acl = allocacl(num + 1);
1068 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1069
1070 /* initialize the new entry with no permissions */
1071 new_aip[dst].ai_grantee = mod_aip->ai_grantee;
1072 new_aip[dst].ai_grantor = mod_aip->ai_grantor;
1075 num++; /* set num to the size of new_acl */
1076 }
1077
1080
1081 /* apply the specified permissions change */
1082 switch (modechg)
1083 {
1084 case ACL_MODECHG_ADD:
1087 break;
1088 case ACL_MODECHG_DEL:
1091 break;
1092 case ACL_MODECHG_EQL:
1095 break;
1096 }
1097
1100
1101 /*
1102 * If the adjusted entry has no permissions, delete it from the list.
1103 */
1105 {
1107 new_aip + dst + 1,
1108 (num - dst - 1) * sizeof(AclItem));
1109 /* Adjust array size to be 'num - 1' items */
1110 ARR_DIMS(new_acl)[0] = num - 1;
1111 SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1112 }
1113
1114 /*
1115 * Remove abandoned privileges (cascading revoke). Currently we can only
1116 * handle this when the grantee is not PUBLIC.
1117 */
1118 if ((old_goptions & ~new_goptions) != 0)
1119 {
1120 Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1121 new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1123 ownerId, behavior);
1124 }
1125
1126 return new_acl;
1127}
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition acl.c:1330
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition acl.c:1250
#define ACL_SIZE(ACL)
Definition acl.h:111
#define ACL_MODECHG_DEL
Definition acl.h:130
#define ACLITEM_GET_GOPTIONS(item)
Definition acl.h:67
#define ACL_MODECHG_EQL
Definition acl.h:131
#define Assert(condition)
Definition c.h:943

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, allocacl(), ARR_DIMS, Assert, check_acl(), check_circularity(), fb(), memcpy(), 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 
)
extern

Definition at line 5371 of file acl.c.

5372{
5373 if (!member_can_set_role(member, role))
5374 ereport(ERROR,
5376 errmsg("must be able to SET ROLE \"%s\"",
5377 GetUserNameFromId(role, false))));
5378}
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5348
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:990

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

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

◆ check_rolespec_name()

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

Definition at line 5746 of file acl.c.

5747{
5748 if (!role)
5749 return;
5750
5751 if (role->roletype != ROLESPEC_CSTRING)
5752 return;
5753
5754 if (IsReservedName(role->rolename))
5755 {
5756 if (detail_msg)
5757 ereport(ERROR,
5759 errmsg("role name \"%s\" is reserved",
5760 role->rolename),
5762 else
5763 ereport(ERROR,
5765 errmsg("role name \"%s\" is reserved",
5766 role->rolename)));
5767 }
5768}
bool IsReservedName(const char *name)
Definition catalog.c:278
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
@ ROLESPEC_CSTRING
Definition parsenodes.h:422
RoleSpecType roletype
Definition parsenodes.h:432
char * rolename
Definition parsenodes.h:433

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

Referenced by AlterRole(), and AlterRoleSet().

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)
extern

Definition at line 915 of file aclchk.c.

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

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, elog, ereport, errcode(), errmsg, ERROR, errorConflictingDefElem(), fb(), get_rolespec_oid(), gettext_noop, GetUserId(), has_privs_of_role(), lappend_oid(), lfirst, NIL, OBJECT_FUNCTION, OBJECT_LARGEOBJECT, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, privilege_to_string(), ROLESPEC_PUBLIC, SetDefaultACLsInSchemas(), stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)
extern

Definition at line 395 of file aclchk.c.

396{
397 InternalGrant istmt;
398 ListCell *cell;
399 const char *errormsg;
401
402 /*
403 * Turn the regular GrantStmt into the InternalGrant form.
404 */
405 istmt.is_grant = stmt->is_grant;
406 istmt.objtype = stmt->objtype;
407
408 /* Collect the OIDs of the target objects */
409 switch (stmt->targtype)
410 {
412 istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects,
413 stmt->is_grant);
414 break;
416 istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
417 break;
418 /* ACL_TARGET_DEFAULTS should not be seen here */
419 default:
420 elog(ERROR, "unrecognized GrantStmt.targtype: %d",
421 (int) stmt->targtype);
422 }
423
424 /* all_privs to be filled below */
425 /* privileges to be filled below */
426 istmt.col_privs = NIL; /* may get filled below */
427 istmt.grantees = NIL; /* filled below */
428 istmt.grant_option = stmt->grant_option;
429 istmt.grantor = stmt->grantor;
430 istmt.behavior = stmt->behavior;
431
432 /*
433 * Convert the RoleSpec list into an Oid list. Note that at this point we
434 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
435 * there shouldn't be any additional work needed to support this case.
436 */
437 foreach(cell, stmt->grantees)
438 {
439 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
441
442 switch (grantee->roletype)
443 {
444 case ROLESPEC_PUBLIC:
446 break;
447 default:
449 break;
450 }
452 }
453
454 /*
455 * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
456 * bitmask. Note: objtype can't be OBJECT_COLUMN.
457 */
458 switch (stmt->objtype)
459 {
460 case OBJECT_TABLE:
461
462 /*
463 * Because this might be a sequence, we test both relation and
464 * sequence bits, and later do a more limited test when we know
465 * the object type.
466 */
468 errormsg = gettext_noop("invalid privilege type %s for relation");
469 break;
470 case OBJECT_SEQUENCE:
472 errormsg = gettext_noop("invalid privilege type %s for sequence");
473 break;
474 case OBJECT_DATABASE:
476 errormsg = gettext_noop("invalid privilege type %s for database");
477 break;
478 case OBJECT_DOMAIN:
480 errormsg = gettext_noop("invalid privilege type %s for domain");
481 break;
482 case OBJECT_FUNCTION:
484 errormsg = gettext_noop("invalid privilege type %s for function");
485 break;
486 case OBJECT_LANGUAGE:
488 errormsg = gettext_noop("invalid privilege type %s for language");
489 break;
492 errormsg = gettext_noop("invalid privilege type %s for large object");
493 break;
494 case OBJECT_SCHEMA:
496 errormsg = gettext_noop("invalid privilege type %s for schema");
497 break;
498 case OBJECT_PROCEDURE:
500 errormsg = gettext_noop("invalid privilege type %s for procedure");
501 break;
502 case OBJECT_ROUTINE:
504 errormsg = gettext_noop("invalid privilege type %s for routine");
505 break;
508 errormsg = gettext_noop("invalid privilege type %s for tablespace");
509 break;
510 case OBJECT_TYPE:
512 errormsg = gettext_noop("invalid privilege type %s for type");
513 break;
514 case OBJECT_FDW:
516 errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
517 break;
520 errormsg = gettext_noop("invalid privilege type %s for foreign server");
521 break;
524 errormsg = gettext_noop("invalid privilege type %s for parameter");
525 break;
526 case OBJECT_PROPGRAPH:
528 errormsg = gettext_noop("invalid privilege type %s for property graph");
529 break;
530 default:
531 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
532 (int) stmt->objtype);
533 /* keep compiler quiet */
535 errormsg = NULL;
536 }
537
538 if (stmt->privileges == NIL)
539 {
540 istmt.all_privs = true;
541
542 /*
543 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
544 * depending on the object type
545 */
547 }
548 else
549 {
550 istmt.all_privs = false;
552
553 foreach(cell, stmt->privileges)
554 {
556 AclMode priv;
557
558 /*
559 * If it's a column-level specification, we just set it aside in
560 * col_privs for the moment; but insist it's for a relation.
561 */
562 if (privnode->cols)
563 {
564 if (stmt->objtype != OBJECT_TABLE)
567 errmsg("column privileges are only valid for relations")));
568 istmt.col_privs = lappend(istmt.col_privs, privnode);
569 continue;
570 }
571
572 if (privnode->priv_name == NULL) /* parser mistake? */
573 elog(ERROR, "AccessPriv node must specify privilege or columns");
574 priv = string_to_privilege(privnode->priv_name);
575
576 if (priv & ~all_privileges)
579 errmsg(errormsg, privilege_to_string(priv))));
580
581 istmt.privileges |= priv;
582 }
583 }
584
585 ExecGrantStmt_oids(&istmt);
586}
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition aclchk.c:594
static List * objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
Definition aclchk.c:671
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition aclchk.c:784
List * lappend(List *list, void *datum)
Definition list.c:339
@ ACL_TARGET_OBJECT
@ ACL_TARGET_ALL_IN_SCHEMA
DropBehavior behavior
ObjectType objtype
RoleSpec * grantor

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_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, elog, ereport, errcode(), errmsg, ERROR, ExecGrantStmt_oids(), fb(), get_rolespec_oid(), gettext_noop, InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, 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_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, privilege_to_string(), InternalGrant::privileges, ROLESPEC_PUBLIC, stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char rolname,
bool  missing_ok 
)
extern

Definition at line 5605 of file acl.c.

5606{
5607 Oid oid;
5608
5611 if (!OidIsValid(oid) && !missing_ok)
5612 ereport(ERROR,
5614 errmsg("role \"%s\" does not exist", rolname)));
5615 return oid;
5616}
#define OidIsValid(objectId)
Definition c.h:858
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
#define GetSysCacheOid1(cacheId, oidcol, key1)
Definition syscache.h:109

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

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

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char * get_rolespec_name ( const RoleSpec role)
extern

Definition at line 5724 of file acl.c.

5725{
5726 HeapTuple tp;
5728 char *rolename;
5729
5730 tp = get_rolespec_tuple(role);
5732 rolename = pstrdup(NameStr(authForm->rolname));
5733 ReleaseSysCache(tp);
5734
5735 return rolename;
5736}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5678
#define NameStr(name)
Definition c.h:835
static void * GETSTRUCT(const HeapTupleData *tuple)
char * pstrdup(const char *in)
Definition mcxt.c:1910
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265

References fb(), Form_pg_authid, 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 
)
extern

Definition at line 5639 of file acl.c.

5640{
5641 Oid oid;
5642
5643 switch (role->roletype)
5644 {
5645 case ROLESPEC_CSTRING:
5646 Assert(role->rolename);
5647 oid = get_role_oid(role->rolename, missing_ok);
5648 break;
5649
5652 oid = GetUserId();
5653 break;
5654
5656 oid = GetSessionUserId();
5657 break;
5658
5659 case ROLESPEC_PUBLIC:
5660 ereport(ERROR,
5662 errmsg("role \"%s\" does not exist", "public")));
5663 oid = InvalidOid; /* make compiler happy */
5664 break;
5665
5666 default:
5667 elog(ERROR, "unexpected role type %d", role->roletype);
5668 }
5669
5670 return oid;
5671}
Oid GetSessionUserId(void)
Definition miscinit.c:509
@ ROLESPEC_CURRENT_USER
Definition parsenodes.h:424
@ ROLESPEC_SESSION_USER
Definition parsenodes.h:425
@ ROLESPEC_CURRENT_ROLE
Definition parsenodes.h:423
#define InvalidOid

References Assert, elog, ereport, errcode(), errmsg, ERROR, fb(), 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(), roleSpecsToIds(), and select_best_grantor().

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)
extern

Definition at line 5678 of file acl.c.

5679{
5680 HeapTuple tuple;
5681
5682 switch (role->roletype)
5683 {
5684 case ROLESPEC_CSTRING:
5685 Assert(role->rolename);
5687 if (!HeapTupleIsValid(tuple))
5688 ereport(ERROR,
5690 errmsg("role \"%s\" does not exist", role->rolename)));
5691 break;
5692
5696 if (!HeapTupleIsValid(tuple))
5697 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5698 break;
5699
5702 if (!HeapTupleIsValid(tuple))
5703 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5704 break;
5705
5706 case ROLESPEC_PUBLIC:
5707 ereport(ERROR,
5709 errmsg("role \"%s\" does not exist", "public")));
5710 tuple = NULL; /* make compiler happy */
5711 break;
5712
5713 default:
5714 elog(ERROR, "unexpected role type %d", role->roletype);
5715 }
5716
5717 return tuple;
5718}
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

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

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

◆ get_user_default_acl()

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

Definition at line 4291 of file aclchk.c.

4292{
4293 Acl *result;
4294 Acl *glob_acl;
4295 Acl *schema_acl;
4296 Acl *def_acl;
4297 char defaclobjtype;
4298
4299 /*
4300 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4301 * yet.
4302 */
4304 return NULL;
4305
4306 /* Check if object type is supported in pg_default_acl */
4307 switch (objtype)
4308 {
4309 case OBJECT_TABLE:
4310 defaclobjtype = DEFACLOBJ_RELATION;
4311 break;
4312
4313 case OBJECT_SEQUENCE:
4314 defaclobjtype = DEFACLOBJ_SEQUENCE;
4315 break;
4316
4317 case OBJECT_FUNCTION:
4318 defaclobjtype = DEFACLOBJ_FUNCTION;
4319 break;
4320
4321 case OBJECT_TYPE:
4322 defaclobjtype = DEFACLOBJ_TYPE;
4323 break;
4324
4325 case OBJECT_SCHEMA:
4326 defaclobjtype = DEFACLOBJ_NAMESPACE;
4327 break;
4328
4329 case OBJECT_LARGEOBJECT:
4330 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4331 break;
4332
4333 default:
4334 return NULL;
4335 }
4336
4337 /* Look up the relevant pg_default_acl entries */
4338 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4339 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4340
4341 /* Quick out if neither entry exists */
4342 if (glob_acl == NULL && schema_acl == NULL)
4343 return NULL;
4344
4345 /* We need to know the hard-wired default value, too */
4346 def_acl = acldefault(objtype, ownerId);
4347
4348 /* If there's no global entry, substitute the hard-wired default */
4349 if (glob_acl == NULL)
4350 glob_acl = def_acl;
4351
4352 /* Merge in any per-schema privileges */
4353 result = aclmerge(glob_acl, schema_acl, ownerId);
4354
4355 /*
4356 * For efficiency, we want to return NULL if the result equals default.
4357 * This requires sorting both arrays to get an accurate comparison.
4358 */
4361 if (aclequal(result, def_acl))
4362 result = NULL;
4363
4364 return result;
4365}
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition acl.c:515
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:573
void aclitemsort(Acl *acl)
Definition acl.c:559
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition aclchk.c:4256
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)
extern

Definition at line 4232 of file aclchk.c.

4233{
4234 bool result = false;
4236
4237 /* Superusers bypass all permission checking. */
4238 if (superuser_arg(roleid))
4239 return true;
4240
4243 {
4246 }
4247 return result;
4248}
bool rolbypassrls
Definition pg_authid.h:43
bool superuser_arg(Oid roleid)
Definition superuser.c:57

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

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

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)
extern

Definition at line 4213 of file aclchk.c.

4214{
4215 bool result = false;
4217
4218 /* Superusers bypass all permission checking. */
4219 if (superuser_arg(roleid))
4220 return true;
4221
4224 {
4227 }
4228 return result;
4229}
bool rolcreaterole
Definition pg_authid.h:39

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5314 of file acl.c.

5315{
5316 /* Fast path for simple case */
5317 if (member == role)
5318 return true;
5319
5320 /* Superusers have every privilege, so are part of every role */
5321 if (superuser_arg(member))
5322 return true;
5323
5324 /*
5325 * Find all the roles that member has the privileges of, including
5326 * multi-level recursion, then see if target role is any one of them.
5327 */
5329 InvalidOid, NULL),
5330 role);
5331}
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition acl.c:5182
@ ROLERECURSE_PRIVS
Definition acl.c:79
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722

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

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

◆ initialize_acl()

void initialize_acl ( void  )
extern

Definition at line 5069 of file acl.c.

5070{
5072 {
5076
5077 /*
5078 * In normal mode, set a callback on any syscache invalidation of rows
5079 * of pg_auth_members (for roles_is_member_of()) pg_database (for
5080 * roles_is_member_of())
5081 */
5084 (Datum) 0);
5087 (Datum) 0);
5090 (Datum) 0);
5091 }
5092}
static uint32 cached_db_hash
Definition acl.c:84
static void RoleMembershipCacheCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition acl.c:5099
Oid MyDatabaseId
Definition globals.c:96
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1813
uint64_t Datum
Definition postgres.h:70
#define GetSysCacheHashValue1(cacheId, key1)
Definition syscache.h:118

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5444 of file acl.c.

5445{
5447
5448 if (superuser_arg(member))
5449 return true;
5450
5451 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5452 if (member == role)
5453 return false;
5454
5456 return OidIsValid(admin_role);
5457}
@ ROLERECURSE_MEMBERS
Definition acl.c:78

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

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

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5394 of file acl.c.

5395{
5396 /* Fast path for simple case */
5397 if (member == role)
5398 return true;
5399
5400 /* Superusers have every privilege, so are part of every role */
5401 if (superuser_arg(member))
5402 return true;
5403
5404 /*
5405 * Find all the roles that member is a member of, including multi-level
5406 * recursion, then see if target role is any one of them.
5407 */
5409 InvalidOid, NULL),
5410 role);
5411}

References fb(), 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 
)
extern

Definition at line 5422 of file acl.c.

5423{
5424 /* Fast path for simple case */
5425 if (member == role)
5426 return true;
5427
5428 /*
5429 * Find all the roles that member is a member of, including multi-level
5430 * recursion, then see if target role is any one of them.
5431 */
5433 InvalidOid, NULL),
5434 role);
5435}

References fb(), 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  )
extern

Definition at line 462 of file acl.c.

463{
464 return allocacl(0);
465}

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5348 of file acl.c.

5349{
5350 /* Fast path for simple case */
5351 if (member == role)
5352 return true;
5353
5354 /* Superusers have every privilege, so can always SET ROLE */
5355 if (superuser_arg(member))
5356 return true;
5357
5358 /*
5359 * Find all the roles that member can access via SET ROLE, including
5360 * multi-level recursion, then see if target role is any one of them.
5361 */
5363 InvalidOid, NULL),
5364 role);
5365}
@ ROLERECURSE_SETROLE
Definition acl.c:80

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

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

◆ object_aclcheck()

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

Definition at line 3880 of file aclchk.c.

3881{
3882 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3883}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3890

References fb(), mode, and object_aclcheck_ext().

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

◆ object_aclcheck_ext()

◆ object_ownercheck()

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

Definition at line 4134 of file aclchk.c.

4135{
4137 Oid ownerId;
4138
4139 /* Superusers bypass all permission checking. */
4140 if (superuser_arg(roleid))
4141 return true;
4142
4143 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4144 if (classid == LargeObjectRelationId)
4146
4149 {
4150 /* we can get the object's tuple from the syscache */
4151 HeapTuple tuple;
4152
4154 if (!HeapTupleIsValid(tuple))
4155 elog(ERROR, "cache lookup failed for %s %u",
4157
4159 tuple,
4160 get_object_attnum_owner(classid)));
4161 ReleaseSysCache(tuple);
4162 }
4163 else
4164 {
4165 /* for catalogs without an appropriate syscache */
4166 Relation rel;
4167 ScanKeyData entry[1];
4168 SysScanDesc scan;
4169 HeapTuple tuple;
4170 bool isnull;
4171
4172 rel = table_open(classid, AccessShareLock);
4173
4174 ScanKeyInit(&entry[0],
4175 get_object_attnum_oid(classid),
4178
4179 scan = systable_beginscan(rel,
4180 get_object_oid_index(classid), true,
4181 NULL, 1, entry);
4182
4183 tuple = systable_getnext(scan);
4184 if (!HeapTupleIsValid(tuple))
4185 elog(ERROR, "could not find tuple for %s %u",
4187
4188 ownerId = DatumGetObjectId(heap_getattr(tuple,
4189 get_object_attnum_owner(classid),
4190 RelationGetDescr(rel),
4191 &isnull));
4192 Assert(!isnull);
4193
4194 systable_endscan(scan);
4196 }
4197
4198 return has_privs_of_role(roleid, ownerId);
4199}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define AccessShareLock
Definition lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
const char * get_object_class_descr(Oid class_id)
Oid get_object_oid_index(Oid class_id)
SysCacheIdentifier get_object_catcache_oid(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
#define RelationGetDescr(relation)
Definition rel.h:542
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

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

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

◆ pg_attribute_aclcheck()

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

Definition at line 3912 of file aclchk.c.

3914{
3916}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3924

References attnum, fb(), mode, and pg_attribute_aclcheck_ext().

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

◆ pg_attribute_aclcheck_all()

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

Definition at line 3954 of file aclchk.c.

3956{
3958}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3965

References fb(), mode, and pg_attribute_aclcheck_all_ext().

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

◆ pg_attribute_aclcheck_all_ext()

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

Definition at line 3965 of file aclchk.c.

3968{
3972 Oid ownerId;
3973 AttrNumber nattrs;
3975
3976 /*
3977 * Must fetch pg_class row to get owner ID and number of attributes.
3978 */
3981 {
3982 if (is_missing != NULL)
3983 {
3984 /* return "no privileges" instead of throwing an error */
3985 *is_missing = true;
3986 return ACLCHECK_NO_PRIV;
3987 }
3988 else
3989 ereport(ERROR,
3991 errmsg("relation with OID %u does not exist",
3992 table_oid)));
3993 }
3995
3996 ownerId = classForm->relowner;
3997 nattrs = classForm->relnatts;
3998
4000
4001 /*
4002 * Initialize result in case there are no non-dropped columns. We want to
4003 * report failure in such cases for either value of 'how'.
4004 */
4006
4007 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4008 {
4011 bool isNull;
4012 Acl *acl;
4014
4018
4019 /*
4020 * Lookup failure probably indicates that the table was just dropped,
4021 * but we'll treat it the same as a dropped column rather than
4022 * throwing error.
4023 */
4025 continue;
4026
4027 /* ignore dropped columns */
4028 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4029 {
4031 continue;
4032 }
4033
4035 &isNull);
4036
4037 /*
4038 * Here we hard-wire knowledge that the default ACL for a column
4039 * grants no privileges, so that we can fall out quickly in the very
4040 * common case where attacl is null.
4041 */
4042 if (isNull)
4043 attmask = 0;
4044 else
4045 {
4046 /* detoast column's ACL if necessary */
4047 acl = DatumGetAclP(aclDatum);
4048
4049 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4050
4051 /* if we have a detoasted copy, free it */
4052 if (acl != DatumGetPointer(aclDatum))
4053 pfree(acl);
4054 }
4055
4057
4058 if (attmask != 0)
4059 {
4061 if (how == ACLMASK_ANY)
4062 break; /* succeed on any success */
4063 }
4064 else
4065 {
4067 if (how == ACLMASK_ALL)
4068 break; /* fail on any failure */
4069 }
4070 }
4071
4072 return result;
4073}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1416
#define DatumGetAclP(X)
Definition acl.h:120
FormData_pg_attribute * Form_pg_attribute
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
#define ERRCODE_UNDEFINED_TABLE
Definition pgbench.c:79
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596

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

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

◆ pg_attribute_aclcheck_ext()

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

Definition at line 3924 of file aclchk.c.

3926{
3928 ACLMASK_ANY, is_missing) != 0)
3929 return ACLCHECK_OK;
3930 else
3931 return ACLCHECK_NO_PRIV;
3932}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3184

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, attnum, fb(), 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 
)
extern

◆ pg_class_aclcheck_ext()

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

◆ pg_class_aclmask()

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

Definition at line 3298 of file aclchk.c.

3300{
3301 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3302}

References fb(), and pg_class_aclmask_ext().

Referenced by ExecCheckOneRelPerms(), and pg_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4120 of file aclchk.c.

4122{
4124 ACLMASK_ANY, snapshot) != 0)
4125 return ACLCHECK_OK;
4126 else
4127 return ACLCHECK_NO_PRIV;
4128}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition aclchk.c:3561

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

Referenced by has_lo_priv_byid(), and inv_open().

◆ pg_parameter_aclcheck()

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

Definition at line 4108 of file aclchk.c.

4109{
4110 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4111 return ACLCHECK_OK;
4112 else
4113 return ACLCHECK_NO_PRIV;
4114}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3438

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

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

◆ recordDependencyOnNewAcl()

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

Definition at line 4371 of file aclchk.c.

4373{
4374 int nmembers;
4375 Oid *members;
4376
4377 /* Nothing to do if ACL is defaulted */
4378 if (acl == NULL)
4379 return;
4380
4381 /* Extract roles mentioned in ACL */
4382 nmembers = aclmembers(acl, &members);
4383
4384 /* Update the shared dependency ACL info */
4385 updateAclDependencies(classId, objectId, objsubId,
4386 ownerId,
4387 0, NULL,
4388 nmembers, members);
4389}
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1568
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)

References aclmembers(), fb(), and updateAclDependencies().

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)
extern

Definition at line 4398 of file aclchk.c.

4399{
4400 /*
4401 * pg_class / pg_attribute
4402 *
4403 * If this is a relation then we need to see if there are any sub-objects
4404 * (eg: columns) for it and, if so, be sure to call
4405 * recordExtensionInitPrivWorker() for each one.
4406 */
4407 if (classoid == RelationRelationId)
4408 {
4411 bool isNull;
4412 HeapTuple tuple;
4413
4414 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4415 if (!HeapTupleIsValid(tuple))
4416 elog(ERROR, "cache lookup failed for relation %u", objoid);
4418
4419 /*
4420 * Indexes don't have permissions, neither do the pg_class rows for
4421 * composite types. (These cases are unreachable given the
4422 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4423 */
4424 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4427 {
4428 ReleaseSysCache(tuple);
4429 return;
4430 }
4431
4432 /*
4433 * If this isn't a sequence then it's possibly going to have
4434 * column-level ACLs associated with it.
4435 */
4436 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4437 {
4439 AttrNumber nattrs = pg_class_tuple->relnatts;
4440
4441 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4442 {
4445
4447 ObjectIdGetDatum(objoid),
4449
4451 continue;
4452
4453 /* ignore dropped columns */
4454 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4455 {
4457 continue;
4458 }
4459
4462 &isNull);
4463
4464 /* no need to do anything for a NULL ACL */
4465 if (isNull)
4466 {
4468 continue;
4469 }
4470
4471 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4473
4475 }
4476 }
4477
4479 &isNull);
4480
4481 /* Add the record, if any, for the top-level object */
4482 if (!isNull)
4483 recordExtensionInitPrivWorker(objoid, classoid, 0,
4485
4486 ReleaseSysCache(tuple);
4487 }
4488 else if (classoid == LargeObjectRelationId)
4489 {
4490 /* For large objects, we must consult pg_largeobject_metadata */
4492 bool isNull;
4493 HeapTuple tuple;
4494 ScanKeyData entry[1];
4495 SysScanDesc scan;
4496 Relation relation;
4497
4498 /*
4499 * Note: this is dead code, given that we don't allow large objects to
4500 * be made extension members. But it seems worth carrying in case
4501 * some future caller of this function has need for it.
4502 */
4504
4505 /* There's no syscache for pg_largeobject_metadata */
4506 ScanKeyInit(&entry[0],
4509 ObjectIdGetDatum(objoid));
4510
4511 scan = systable_beginscan(relation,
4513 NULL, 1, entry);
4514
4515 tuple = systable_getnext(scan);
4516 if (!HeapTupleIsValid(tuple))
4517 elog(ERROR, "could not find tuple for large object %u", objoid);
4518
4519 aclDatum = heap_getattr(tuple,
4521 RelationGetDescr(relation), &isNull);
4522
4523 /* Add the record, if any, for the top-level object */
4524 if (!isNull)
4525 recordExtensionInitPrivWorker(objoid, classoid, 0,
4527
4528 systable_endscan(scan);
4529 }
4530 /* This will error on unsupported classoid. */
4531 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4532 {
4535 bool isNull;
4536 HeapTuple tuple;
4537
4538 cacheid = get_object_catcache_oid(classoid);
4539 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4540 if (!HeapTupleIsValid(tuple))
4541 elog(ERROR, "cache lookup failed for %s %u",
4542 get_object_class_descr(classoid), objoid);
4543
4545 get_object_attnum_acl(classoid),
4546 &isNull);
4547
4548 /* Add the record, if any, for the top-level object */
4549 if (!isNull)
4550 recordExtensionInitPrivWorker(objoid, classoid, 0,
4552
4553 ReleaseSysCache(tuple);
4554 }
4555}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4674
#define InvalidAttrNumber
Definition attnum.h:23
#define RowExclusiveLock
Definition lockdefs.h:38
AttrNumber get_object_attnum_acl(Oid class_id)

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)
extern

Definition at line 4562 of file aclchk.c.

4563{
4564 /*
4565 * If this is a relation then we need to see if there are any sub-objects
4566 * (eg: columns) for it and, if so, be sure to call
4567 * recordExtensionInitPrivWorker() for each one.
4568 */
4569 if (classoid == RelationRelationId)
4570 {
4572 HeapTuple tuple;
4573
4574 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4575 if (!HeapTupleIsValid(tuple))
4576 elog(ERROR, "cache lookup failed for relation %u", objoid);
4578
4579 /*
4580 * Indexes don't have permissions, neither do the pg_class rows for
4581 * composite types. (These cases are unreachable given the
4582 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4583 */
4584 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4587 {
4588 ReleaseSysCache(tuple);
4589 return;
4590 }
4591
4592 /*
4593 * If this isn't a sequence then it's possibly going to have
4594 * column-level ACLs associated with it.
4595 */
4596 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4597 {
4599 AttrNumber nattrs = pg_class_tuple->relnatts;
4600
4601 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4602 {
4604
4606 ObjectIdGetDatum(objoid),
4608
4610 continue;
4611
4612 /* when removing, remove all entries, even dropped columns */
4613
4614 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4615
4617 }
4618 }
4619
4620 ReleaseSysCache(tuple);
4621 }
4622
4623 /* Remove the record, if any, for the top-level object */
4624 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4625}

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

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

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

Definition at line 4911 of file aclchk.c.

4912{
4913 Relation rel;
4914 ScanKeyData key[3];
4915 SysScanDesc scan;
4916 HeapTuple oldtuple;
4919 Oid ownerId;
4921 bool isNull;
4922 Acl *old_acl;
4923 Acl *new_acl;
4924 HeapTuple newtuple;
4925 int noldmembers;
4926 int nnewmembers;
4927 Oid *oldmembers;
4928 Oid *newmembers;
4929
4930 /* Search for existing pg_init_privs entry for the target object. */
4932
4933 ScanKeyInit(&key[0],
4936 ObjectIdGetDatum(objid));
4937 ScanKeyInit(&key[1],
4940 ObjectIdGetDatum(classid));
4941 ScanKeyInit(&key[2],
4944 Int32GetDatum(objsubid));
4945
4946 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4947 NULL, 3, key);
4948
4949 /* There should exist only one entry or none. */
4950 oldtuple = systable_getnext(scan);
4951
4952 if (!HeapTupleIsValid(oldtuple))
4953 {
4954 /*
4955 * Hmm, why are we here if there's no entry? But pack up and go away
4956 * quietly.
4957 */
4958 systable_endscan(scan);
4960 return;
4961 }
4962
4963 /* Get a writable copy of the existing ACL. */
4965 RelationGetDescr(rel), &isNull);
4966 Assert(!isNull);
4968
4969 /*
4970 * We need the members of both old and new ACLs so we can correct the
4971 * shared dependency information. Collect data before
4972 * merge_acl_with_grant throws away old_acl.
4973 */
4975
4976 /* Must find out the owner's OID the hard way. */
4980 elog(ERROR, "cache lookup failed for %s %u",
4981 get_object_class_descr(classid), objid);
4982
4984 objtuple,
4985 get_object_attnum_owner(classid)));
4987
4988 /*
4989 * Generate new ACL. Grantor of rights is always the same as the owner.
4990 */
4991 if (old_acl != NULL)
4993 false, /* is_grant */
4994 false, /* grant_option */
4996 list_make1_oid(roleid),
4998 ownerId,
4999 ownerId);
5000 else
5001 new_acl = NULL; /* this case shouldn't happen, probably */
5002
5003 /* If we end with an empty ACL, delete the pg_init_privs entry. */
5004 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
5005 {
5006 CatalogTupleDelete(rel, &oldtuple->t_self);
5007 }
5008 else
5009 {
5011 bool nulls[Natts_pg_init_privs] = {0};
5012 bool replaces[Natts_pg_init_privs] = {0};
5013
5014 /* Update existing entry. */
5017
5018 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
5019 values, nulls, replaces);
5020 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
5021 }
5022
5023 /*
5024 * Update the shared dependency ACL info.
5025 */
5027
5028 updateInitAclDependencies(classid, objid, objsubid,
5031
5032 systable_endscan(scan);
5033
5034 /* prevent error when processing objects multiple times */
5036
5038}
#define ACLITEM_ALL_PRIV_BITS
Definition acl.h:87
#define DatumGetAclPCopy(X)
Definition acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition aclchk.c:182
static Datum values[MAXATTR]
Definition bootstrap.c:190
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1118
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define list_make1_oid(x1)
Definition pg_list.h:274
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define PointerGetDatum(X)
Definition postgres.h:354
ItemPointerData t_self
Definition htup.h:65
void CommandCounterIncrement(void)
Definition xact.c:1130

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

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1426 of file aclchk.c.

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

References AccessShareLock, ACL_NO_RIGHTS, InternalGrant::all_privs, InternalGrant::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DROP_CASCADE, elog, ERROR, ExecGrantStmt_oids(), fb(), Form_pg_default_acl, GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, HeapTupleIsValid, InternalGrant::is_grant, list_make1_oid, NIL, 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, InternalGrant::objtype, InternalGrant::privileges, ScanKeyInit(), SetDefaultACL(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

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

Definition at line 4802 of file aclchk.c.

4804{
4805 Relation rel;
4806 ScanKeyData key[3];
4807 SysScanDesc scan;
4808 HeapTuple oldtuple;
4810 bool isNull;
4811 Acl *old_acl;
4812 Acl *new_acl;
4813 HeapTuple newtuple;
4814 int noldmembers;
4815 int nnewmembers;
4816 Oid *oldmembers;
4817 Oid *newmembers;
4818
4819 /* Search for existing pg_init_privs entry for the target object. */
4821
4822 ScanKeyInit(&key[0],
4825 ObjectIdGetDatum(objid));
4826 ScanKeyInit(&key[1],
4829 ObjectIdGetDatum(classid));
4830 ScanKeyInit(&key[2],
4833 Int32GetDatum(objsubid));
4834
4835 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4836 NULL, 3, key);
4837
4838 /* There should exist only one entry or none. */
4839 oldtuple = systable_getnext(scan);
4840
4841 if (!HeapTupleIsValid(oldtuple))
4842 {
4843 /*
4844 * Hmm, why are we here if there's no entry? But pack up and go away
4845 * quietly.
4846 */
4847 systable_endscan(scan);
4849 return;
4850 }
4851
4852 /* Get a writable copy of the existing ACL. */
4854 RelationGetDescr(rel), &isNull);
4855 Assert(!isNull);
4857
4858 /*
4859 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4860 * oldroleid isn't the owner; but it does the job fine.
4861 */
4863
4864 /*
4865 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4866 * probably can't happen here, but we may as well cover the case.)
4867 */
4868 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4869 {
4870 CatalogTupleDelete(rel, &oldtuple->t_self);
4871 }
4872 else
4873 {
4875 bool nulls[Natts_pg_init_privs] = {0};
4876 bool replaces[Natts_pg_init_privs] = {0};
4877
4878 /* Update existing entry. */
4881
4882 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4883 values, nulls, replaces);
4884 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4885 }
4886
4887 /*
4888 * Update the shared dependency ACL info.
4889 */
4892
4893 updateInitAclDependencies(classid, objid, objsubid,
4896
4897 systable_endscan(scan);
4898
4899 /* prevent error when processing objects multiple times */
4901
4903}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1147

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

Referenced by shdepReassignOwned_InitAcl().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)
extern

Definition at line 5469 of file acl.c.

5470{
5472
5473 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5474 if (member == role)
5475 return InvalidOid;
5476
5478 return admin_role;
5479}

References fb(), InvalidOid, ROLERECURSE_PRIVS, and roles_is_member_of().

Referenced by check_role_grantor().

◆ select_best_grantor()

void select_best_grantor ( const RoleSpec grantedBy,
AclMode  privileges,
const Acl acl,
Oid  ownerId,
Oid grantorId,
AclMode grantOptions 
)
extern

Definition at line 5508 of file acl.c.

5511{
5512 Oid roleId = GetUserId();
5515 int nrights;
5516 ListCell *l;
5517
5518 /*
5519 * If we have GRANTED BY, resolve it and verify current user is allowed to
5520 * specify that role.
5521 */
5522 if (grantedBy)
5523 {
5524 Oid grantor = get_rolespec_oid(grantedBy, false);
5525
5526 if (!has_privs_of_role(roleId, grantor))
5527 ereport(ERROR,
5529 errmsg("must inherit privileges of role \"%s\"",
5530 GetUserNameFromId(grantor, false))));
5531 /* Use exactly that grantor, whether it has privileges or not */
5532 *grantorId = grantor;
5533 *grantOptions = aclmask_direct(acl, grantor, ownerId,
5535 return;
5536 }
5537
5538 /*
5539 * The object owner is always treated as having all grant options, so if
5540 * roleId is the owner it's easy. Also, if roleId is a superuser it's
5541 * easy: superusers are implicitly members of every role, so they act as
5542 * the object owner.
5543 */
5544 if (roleId == ownerId || superuser_arg(roleId))
5545 {
5546 *grantorId = ownerId;
5548 return;
5549 }
5550
5551 /*
5552 * Otherwise we have to do a careful search to see if roleId has the
5553 * privileges of any suitable role. Note: we can hang onto the result of
5554 * roles_is_member_of() throughout this loop, because aclmask_direct()
5555 * doesn't query any role memberships.
5556 */
5558 InvalidOid, NULL);
5559
5560 /* initialize candidate result as default */
5561 *grantorId = roleId;
5563 nrights = 0;
5564
5565 foreach(l, roles_list)
5566 {
5569
5570 otherprivs = aclmask_direct(acl, otherrole, ownerId,
5573 {
5574 /* Found a suitable grantor */
5577 return;
5578 }
5579
5580 /*
5581 * If it has just some of the needed privileges, remember best
5582 * candidate.
5583 */
5585 {
5587
5588 if (nnewrights > nrights)
5589 {
5593 }
5594 }
5595 }
5596}
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1505
#define ACL_GRANT_OPTION_FOR(privs)
Definition acl.h:70
static int pg_popcount64(uint64 word)
#define lfirst_oid(lc)
Definition pg_list.h:174

References ACL_GRANT_OPTION_FOR, ACL_NO_RIGHTS, ACLMASK_ALL, aclmask_direct(), ereport, errcode(), errmsg, ERROR, fb(), get_rolespec_oid(), GetUserId(), GetUserNameFromId(), has_privs_of_role(), InvalidOid, lfirst_oid, pg_popcount64(), ROLERECURSE_PRIVS, roles_is_member_of(), and superuser_arg().

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