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_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 (Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
 
void initialize_acl (void)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult object_aclcheck (Oid classid, Oid objectid, Oid roleid, AclMode mode)
 
AclResult object_aclcheck_ext (Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_attribute_aclcheck_all_ext (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_parameter_aclcheck (const char *name, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
void ReplaceRoleInInitPriv (Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
 
void RemoveRoleFromInitPriv (Oid roleid, Oid classid, Oid objid, int32 objsubid)
 
bool object_ownercheck (Oid classid, Oid objectid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 171 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

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

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

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

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

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

Definition at line 76 of file acl.h.

175{
176 ACLMASK_ALL, /* normal case: compute all bits */
177 ACLMASK_ANY, /* return when result is known nonzero */
178} AclMaskHow;
179
180/* result codes for pg_*_aclcheck */
181typedef enum
182{
183 ACLCHECK_OK = 0,
186} AclResult;
187
188
189/*
190 * routines used internally
191 */
192extern Acl *acldefault(ObjectType objtype, Oid ownerId);
193extern Acl *get_user_default_acl(ObjectType objtype, Oid ownerId,
194 Oid nsp_oid);
195extern void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId,
196 Oid ownerId, Acl *acl);
197
198extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
199 int modechg, Oid ownerId, DropBehavior behavior);
201extern Acl *make_empty_acl(void);
202extern Acl *aclcopy(const Acl *orig_acl);
203extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl);
204extern Acl *aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId);
205extern void aclitemsort(Acl *acl);
206extern bool aclequal(const Acl *left_acl, const Acl *right_acl);
207
208extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
209 AclMode mask, AclMaskHow how);
210extern int aclmembers(const Acl *acl, Oid **roleids);
211
212extern bool has_privs_of_role(Oid member, Oid role);
213extern bool member_can_set_role(Oid member, Oid role);
214extern void check_can_set_role(Oid member, Oid role);
215extern bool is_member_of_role(Oid member, Oid role);
216extern bool is_member_of_role_nosuper(Oid member, Oid role);
217extern bool is_admin_of_role(Oid member, Oid role);
218extern Oid select_best_admin(Oid member, Oid role);
219extern Oid get_role_oid(const char *rolname, bool missing_ok);
220extern Oid get_role_oid_or_public(const char *rolname);
221extern Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok);
222extern void check_rolespec_name(const RoleSpec *role, const char *detail_msg);
223extern HeapTuple get_rolespec_tuple(const RoleSpec *role);
224extern char *get_rolespec_name(const RoleSpec *role);
225
226extern void select_best_grantor(Oid roleId, AclMode privileges,
227 const Acl *acl, Oid ownerId,
229
230extern void initialize_acl(void);
231
232/*
233 * prototypes for functions in aclchk.c
234 */
235extern void ExecuteGrantStmt(GrantStmt *stmt);
237
238extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
239
241 AclMode mask, AclMaskHow how);
242
243/* generic functions */
245 Oid roleid, AclMode mode);
247 Oid roleid, AclMode mode,
248 bool *is_missing);
249
250/* special cases */
252 Oid roleid, AclMode mode);
254 Oid roleid, AclMode mode,
255 bool *is_missing);
260 bool *is_missing);
263 AclMode mode, bool *is_missing);
264extern AclResult pg_parameter_aclcheck(const char *name, Oid roleid,
265 AclMode mode);
267 AclMode mode, Snapshot snapshot);
268
269extern void aclcheck_error(AclResult aclerr, ObjectType objtype,
270 const char *objectname);
271
272extern void aclcheck_error_col(AclResult aclerr, ObjectType objtype,
273 const char *objectname, const char *colname);
274
275extern void aclcheck_error_type(AclResult aclerr, Oid typeOid);
276
277extern void recordExtObjInitPriv(Oid objoid, Oid classoid);
278extern void removeExtObjInitPriv(Oid objoid, Oid classoid);
280 Oid classid, Oid objid, int32 objsubid);
281extern void RemoveRoleFromInitPriv(Oid roleid,
282 Oid classid, Oid objid, int32 objsubid);
283
284
285/* ownercheck routines just return true (owner) or false (not) */
286extern bool object_ownercheck(Oid classid, Oid objectid, Oid roleid);
287extern bool has_createrole_privilege(Oid roleid);
288extern bool has_bypassrls_privilege(Oid roleid);
289
290#endif /* ACL_H */
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3864
void initialize_acl(void)
Definition acl.c:5053
void ExecuteGrantStmt(GrantStmt *stmt)
Definition aclchk.c:391
AclResult pg_largeobject_aclcheck_snapshot(Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
Definition aclchk.c:4094
void RemoveRoleFromInitPriv(Oid roleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4885
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5428
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:490
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition acl.c:514
bool has_bypassrls_privilege(Oid roleid)
Definition aclchk.c:4206
AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:4067
void aclcheck_error_col(AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
Definition aclchk.c:2943
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3939
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4345
Oid select_best_admin(Oid member, Oid role)
Definition acl.c:5453
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:816
Oid get_role_oid_or_public(const char *rolname)
Definition acl.c:5584
void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
Definition aclchk.c:916
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:572
AclResult
Definition acl.h:182
@ ACLCHECK_NO_PRIV
Definition acl.h:184
@ ACLCHECK_OK
Definition acl.h:183
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
Definition aclchk.c:3928
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1005
bool is_member_of_role(Oid member, Oid role)
Definition acl.c:5378
AclResult pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
Definition aclchk.c:4082
void ReplaceRoleInInitPriv(Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4776
void select_best_grantor(Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5490
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition acl.c:5406
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5298
Acl * make_empty_acl(void)
Definition acl.c:461
void recordExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4372
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1553
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1132
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5332
Acl * aclcopy(const Acl *orig_acl)
Definition acl.c:470
void aclitemsort(Acl *acl)
Definition acl.c:558
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1401
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
Definition aclchk.c:3886
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5566
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3854
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4108
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3898
char * get_rolespec_name(const RoleSpec *role)
Definition acl.c:5685
void check_can_set_role(Oid member, Oid role)
Definition acl.c:5355
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3272
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5707
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition aclchk.c:2973
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4187
AclMaskHow
Definition acl.h:175
@ ACLMASK_ANY
Definition acl.h:177
@ ACLMASK_ALL
Definition acl.h:176
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5600
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4265
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition aclchk.c:1422
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
Definition aclchk.c:4057
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5639
void removeExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4536
int16 AttrNumber
Definition attnum.h:21
int32_t int32
Definition c.h:575
#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 174 of file acl.h.

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

◆ AclResult

Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 181 of file acl.h.

Function Documentation

◆ aclcheck_error()

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

Definition at line 2654 of file aclchk.c.

2656{
2657 switch (aclerr)
2658 {
2659 case ACLCHECK_OK:
2660 /* no error, so return to caller */
2661 break;
2662 case ACLCHECK_NO_PRIV:
2663 {
2664 const char *msg = "???";
2665
2666 switch (objtype)
2667 {
2668 case OBJECT_AGGREGATE:
2669 msg = gettext_noop("permission denied for aggregate %s");
2670 break;
2671 case OBJECT_COLLATION:
2672 msg = gettext_noop("permission denied for collation %s");
2673 break;
2674 case OBJECT_COLUMN:
2675 msg = gettext_noop("permission denied for column %s");
2676 break;
2677 case OBJECT_CONVERSION:
2678 msg = gettext_noop("permission denied for conversion %s");
2679 break;
2680 case OBJECT_DATABASE:
2681 msg = gettext_noop("permission denied for database %s");
2682 break;
2683 case OBJECT_DOMAIN:
2684 msg = gettext_noop("permission denied for domain %s");
2685 break;
2687 msg = gettext_noop("permission denied for event trigger %s");
2688 break;
2689 case OBJECT_EXTENSION:
2690 msg = gettext_noop("permission denied for extension %s");
2691 break;
2692 case OBJECT_FDW:
2693 msg = gettext_noop("permission denied for foreign-data wrapper %s");
2694 break;
2696 msg = gettext_noop("permission denied for foreign server %s");
2697 break;
2699 msg = gettext_noop("permission denied for foreign table %s");
2700 break;
2701 case OBJECT_FUNCTION:
2702 msg = gettext_noop("permission denied for function %s");
2703 break;
2704 case OBJECT_INDEX:
2705 msg = gettext_noop("permission denied for index %s");
2706 break;
2707 case OBJECT_LANGUAGE:
2708 msg = gettext_noop("permission denied for language %s");
2709 break;
2710 case OBJECT_LARGEOBJECT:
2711 msg = gettext_noop("permission denied for large object %s");
2712 break;
2713 case OBJECT_MATVIEW:
2714 msg = gettext_noop("permission denied for materialized view %s");
2715 break;
2716 case OBJECT_OPCLASS:
2717 msg = gettext_noop("permission denied for operator class %s");
2718 break;
2719 case OBJECT_OPERATOR:
2720 msg = gettext_noop("permission denied for operator %s");
2721 break;
2722 case OBJECT_OPFAMILY:
2723 msg = gettext_noop("permission denied for operator family %s");
2724 break;
2726 msg = gettext_noop("permission denied for parameter %s");
2727 break;
2728 case OBJECT_POLICY:
2729 msg = gettext_noop("permission denied for policy %s");
2730 break;
2731 case OBJECT_PROCEDURE:
2732 msg = gettext_noop("permission denied for procedure %s");
2733 break;
2734 case OBJECT_PUBLICATION:
2735 msg = gettext_noop("permission denied for publication %s");
2736 break;
2737 case OBJECT_ROUTINE:
2738 msg = gettext_noop("permission denied for routine %s");
2739 break;
2740 case OBJECT_SCHEMA:
2741 msg = gettext_noop("permission denied for schema %s");
2742 break;
2743 case OBJECT_SEQUENCE:
2744 msg = gettext_noop("permission denied for sequence %s");
2745 break;
2747 msg = gettext_noop("permission denied for statistics object %s");
2748 break;
2750 msg = gettext_noop("permission denied for subscription %s");
2751 break;
2752 case OBJECT_TABLE:
2753 msg = gettext_noop("permission denied for table %s");
2754 break;
2755 case OBJECT_TABLESPACE:
2756 msg = gettext_noop("permission denied for tablespace %s");
2757 break;
2759 msg = gettext_noop("permission denied for text search configuration %s");
2760 break;
2762 msg = gettext_noop("permission denied for text search dictionary %s");
2763 break;
2764 case OBJECT_TYPE:
2765 msg = gettext_noop("permission denied for type %s");
2766 break;
2767 case OBJECT_VIEW:
2768 msg = gettext_noop("permission denied for view %s");
2769 break;
2770 /* these currently aren't used */
2772 case OBJECT_AMOP:
2773 case OBJECT_AMPROC:
2774 case OBJECT_ATTRIBUTE:
2775 case OBJECT_CAST:
2776 case OBJECT_DEFAULT:
2777 case OBJECT_DEFACL:
2781 case OBJECT_ROLE:
2782 case OBJECT_RULE:
2784 case OBJECT_TRANSFORM:
2785 case OBJECT_TRIGGER:
2786 case OBJECT_TSPARSER:
2787 case OBJECT_TSTEMPLATE:
2789 elog(ERROR, "unsupported object type: %d", objtype);
2790 }
2791
2792 ereport(ERROR,
2794 errmsg(msg, objectname)));
2795 break;
2796 }
2797 case ACLCHECK_NOT_OWNER:
2798 {
2799 const char *msg = "???";
2800
2801 switch (objtype)
2802 {
2803 case OBJECT_AGGREGATE:
2804 msg = gettext_noop("must be owner of aggregate %s");
2805 break;
2806 case OBJECT_COLLATION:
2807 msg = gettext_noop("must be owner of collation %s");
2808 break;
2809 case OBJECT_CONVERSION:
2810 msg = gettext_noop("must be owner of conversion %s");
2811 break;
2812 case OBJECT_DATABASE:
2813 msg = gettext_noop("must be owner of database %s");
2814 break;
2815 case OBJECT_DOMAIN:
2816 msg = gettext_noop("must be owner of domain %s");
2817 break;
2819 msg = gettext_noop("must be owner of event trigger %s");
2820 break;
2821 case OBJECT_EXTENSION:
2822 msg = gettext_noop("must be owner of extension %s");
2823 break;
2824 case OBJECT_FDW:
2825 msg = gettext_noop("must be owner of foreign-data wrapper %s");
2826 break;
2828 msg = gettext_noop("must be owner of foreign server %s");
2829 break;
2831 msg = gettext_noop("must be owner of foreign table %s");
2832 break;
2833 case OBJECT_FUNCTION:
2834 msg = gettext_noop("must be owner of function %s");
2835 break;
2836 case OBJECT_INDEX:
2837 msg = gettext_noop("must be owner of index %s");
2838 break;
2839 case OBJECT_LANGUAGE:
2840 msg = gettext_noop("must be owner of language %s");
2841 break;
2842 case OBJECT_LARGEOBJECT:
2843 msg = gettext_noop("must be owner of large object %s");
2844 break;
2845 case OBJECT_MATVIEW:
2846 msg = gettext_noop("must be owner of materialized view %s");
2847 break;
2848 case OBJECT_OPCLASS:
2849 msg = gettext_noop("must be owner of operator class %s");
2850 break;
2851 case OBJECT_OPERATOR:
2852 msg = gettext_noop("must be owner of operator %s");
2853 break;
2854 case OBJECT_OPFAMILY:
2855 msg = gettext_noop("must be owner of operator family %s");
2856 break;
2857 case OBJECT_PROCEDURE:
2858 msg = gettext_noop("must be owner of procedure %s");
2859 break;
2860 case OBJECT_PUBLICATION:
2861 msg = gettext_noop("must be owner of publication %s");
2862 break;
2863 case OBJECT_ROUTINE:
2864 msg = gettext_noop("must be owner of routine %s");
2865 break;
2866 case OBJECT_SEQUENCE:
2867 msg = gettext_noop("must be owner of sequence %s");
2868 break;
2870 msg = gettext_noop("must be owner of subscription %s");
2871 break;
2872 case OBJECT_TABLE:
2873 msg = gettext_noop("must be owner of table %s");
2874 break;
2875 case OBJECT_TYPE:
2876 msg = gettext_noop("must be owner of type %s");
2877 break;
2878 case OBJECT_VIEW:
2879 msg = gettext_noop("must be owner of view %s");
2880 break;
2881 case OBJECT_SCHEMA:
2882 msg = gettext_noop("must be owner of schema %s");
2883 break;
2885 msg = gettext_noop("must be owner of statistics object %s");
2886 break;
2887 case OBJECT_TABLESPACE:
2888 msg = gettext_noop("must be owner of tablespace %s");
2889 break;
2891 msg = gettext_noop("must be owner of text search configuration %s");
2892 break;
2894 msg = gettext_noop("must be owner of text search dictionary %s");
2895 break;
2896
2897 /*
2898 * Special cases: For these, the error message talks
2899 * about "relation", because that's where the
2900 * ownership is attached. See also
2901 * check_object_ownership().
2902 */
2903 case OBJECT_COLUMN:
2904 case OBJECT_POLICY:
2905 case OBJECT_RULE:
2907 case OBJECT_TRIGGER:
2908 msg = gettext_noop("must be owner of relation %s");
2909 break;
2910 /* these currently aren't used */
2912 case OBJECT_AMOP:
2913 case OBJECT_AMPROC:
2914 case OBJECT_ATTRIBUTE:
2915 case OBJECT_CAST:
2916 case OBJECT_DEFAULT:
2917 case OBJECT_DEFACL:
2922 case OBJECT_ROLE:
2923 case OBJECT_TRANSFORM:
2924 case OBJECT_TSPARSER:
2925 case OBJECT_TSTEMPLATE:
2927 elog(ERROR, "unsupported object type: %d", objtype);
2928 }
2929
2930 ereport(ERROR,
2932 errmsg(msg, objectname)));
2933 break;
2934 }
2935 default:
2936 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2937 break;
2938 }
2939}
#define gettext_noop(x)
Definition c.h:1248
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
static char * errmsg
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ 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_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_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(), 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 2943 of file aclchk.c.

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

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

491{
493
495
498 ACL_NUM(left_acl) * sizeof(AclItem));
499
502 ACL_NUM(right_acl) * sizeof(AclItem));
503
504 return result_acl;
505}
static Acl * allocacl(int n)
Definition acl.c:439
#define ACL_DAT(ACL)
Definition acl.h:109
#define ACL_NUM(ACL)
Definition acl.h:108

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

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl * aclcopy ( const Acl orig_acl)
extern

Definition at line 470 of file acl.c.

471{
473
475
478 ACL_NUM(orig_acl) * sizeof(AclItem));
479
480 return result_acl;
481}

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

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)
extern

Definition at line 816 of file acl.c.

817{
820 int nacl;
821 Acl *acl;
822 AclItem *aip;
823
824 switch (objtype)
825 {
826 case OBJECT_COLUMN:
827 /* by default, columns have no extra privileges */
830 break;
831 case OBJECT_TABLE:
834 break;
835 case OBJECT_SEQUENCE:
838 break;
839 case OBJECT_DATABASE:
840 /* for backwards compatibility, grant some rights by default */
843 break;
844 case OBJECT_FUNCTION:
845 /* Grant EXECUTE by default, for now */
848 break;
849 case OBJECT_LANGUAGE:
850 /* Grant USAGE by default, for now */
853 break;
857 break;
858 case OBJECT_SCHEMA:
861 break;
865 break;
866 case OBJECT_FDW:
869 break;
873 break;
874 case OBJECT_DOMAIN:
875 case OBJECT_TYPE:
878 break;
882 break;
883 default:
884 elog(ERROR, "unrecognized object type: %d", (int) objtype);
885 world_default = ACL_NO_RIGHTS; /* keep compiler quiet */
887 break;
888 }
889
890 nacl = 0;
892 nacl++;
894 nacl++;
895
896 acl = allocacl(nacl);
897 aip = ACL_DAT(acl);
898
900 {
901 aip->ai_grantee = ACL_ID_PUBLIC;
902 aip->ai_grantor = ownerId;
904 aip++;
905 }
906
907 /*
908 * Note that the owner's entry shows all ordinary privileges but no grant
909 * options. This is because his grant options come "from the system" and
910 * not from his own efforts. (The SQL spec says that the owner's rights
911 * come from a "_SYSTEM" authid.) However, we do consider that the
912 * owner's ordinary privileges are self-granted; this lets him revoke
913 * them. We implement the owner's grant options without any explicit
914 * "_SYSTEM"-like ACL entry, by internally special-casing the owner
915 * wherever we are testing grant options.
916 */
918 {
919 aip->ai_grantee = ownerId;
920 aip->ai_grantor = ownerId;
922 }
923
924 return acl;
925}
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition acl.h:164
#define ACL_ALL_RIGHTS_TABLESPACE
Definition acl.h:170
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition acl.h:168
#define ACL_ALL_RIGHTS_SCHEMA
Definition acl.h:169
#define ACL_ALL_RIGHTS_SEQUENCE
Definition acl.h:161
#define ACL_ALL_RIGHTS_DATABASE
Definition acl.h:162
#define ACL_ALL_RIGHTS_FUNCTION
Definition acl.h:165
#define ACL_ALL_RIGHTS_LANGUAGE
Definition acl.h:166
#define ACL_ALL_RIGHTS_TYPE
Definition acl.h:171
#define ACL_ALL_RIGHTS_FDW
Definition acl.h:163
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition acl.h:82
#define ACL_ALL_RIGHTS_RELATION
Definition acl.h:160
#define ACL_ID_PUBLIC
Definition acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition acl.h:167
#define ACL_CREATE_TEMP
Definition parsenodes.h:86
#define ACL_USAGE
Definition parsenodes.h:84
#define ACL_NO_RIGHTS
Definition parsenodes.h:92
#define ACL_CONNECT
Definition parsenodes.h:87
#define ACL_EXECUTE
Definition parsenodes.h:83

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, 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_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 572 of file acl.c.

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

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

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

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

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

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

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

◆ aclmembers()

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

Definition at line 1553 of file acl.c.

1554{
1555 Oid *list;
1556 const AclItem *acldat;
1557 int i,
1558 j;
1559
1560 if (acl == NULL || ACL_NUM(acl) == 0)
1561 {
1562 *roleids = NULL;
1563 return 0;
1564 }
1565
1566 check_acl(acl);
1567
1568 /* Allocate the worst-case space requirement */
1569 list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
1570 acldat = ACL_DAT(acl);
1571
1572 /*
1573 * Walk the ACL collecting mentioned RoleIds.
1574 */
1575 j = 0;
1576 for (i = 0; i < ACL_NUM(acl); i++)
1577 {
1578 const AclItem *ai = &acldat[i];
1579
1580 if (ai->ai_grantee != ACL_ID_PUBLIC)
1581 list[j++] = ai->ai_grantee;
1582 /* grantor is currently never PUBLIC, but let's check anyway */
1583 if (ai->ai_grantor != ACL_ID_PUBLIC)
1584 list[j++] = ai->ai_grantor;
1585 }
1586
1587 /* Sort the array */
1588 qsort(list, j, sizeof(Oid), oid_cmp);
1589
1590 /*
1591 * We could repalloc the array down to minimum size, but it's hardly worth
1592 * it since it's only transient memory.
1593 */
1594 *roleids = list;
1595
1596 /* Remove duplicates from the array */
1597 return qunique(list, j, sizeof(Oid), oid_cmp);
1598}
int j
Definition isn.c:78
void * palloc(Size size)
Definition mcxt.c:1387
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 514 of file acl.c.

515{
517 AclItem *aip;
518 int i,
519 num;
520
521 /* Check for cases where one or both are empty/null */
522 if (left_acl == NULL || ACL_NUM(left_acl) == 0)
523 {
524 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
525 return NULL;
526 else
527 return aclcopy(right_acl);
528 }
529 else
530 {
531 if (right_acl == NULL || ACL_NUM(right_acl) == 0)
532 return aclcopy(left_acl);
533 }
534
535 /* Merge them the hard way, one item at a time */
537
539 num = ACL_NUM(right_acl);
540
541 for (i = 0; i < num; i++, aip++)
542 {
543 Acl *tmp_acl;
544
546 ownerId, DROP_RESTRICT);
549 }
550
551 return result_acl;
552}
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1005
Acl * aclcopy(const Acl *orig_acl)
Definition acl.c:470
#define ACL_MODECHG_ADD
Definition acl.h:129
void pfree(void *pointer)
Definition mcxt.c:1616
@ 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 1132 of file acl.c.

1133{
1134 Acl *new_acl;
1140 bool newpresent = false;
1141 int dst,
1142 src,
1143 targ,
1144 num;
1145
1147
1148 /*
1149 * Make a copy of the given ACL, substituting new owner ID for old
1150 * wherever it appears as either grantor or grantee. Also note if the new
1151 * owner ID is already present.
1152 */
1153 num = ACL_NUM(old_acl);
1155 new_acl = allocacl(num);
1157 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1158 for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1159 {
1160 if (dst_aip->ai_grantor == oldOwnerId)
1161 dst_aip->ai_grantor = newOwnerId;
1162 else if (dst_aip->ai_grantor == newOwnerId)
1163 newpresent = true;
1164 if (dst_aip->ai_grantee == oldOwnerId)
1165 dst_aip->ai_grantee = newOwnerId;
1166 else if (dst_aip->ai_grantee == newOwnerId)
1167 newpresent = true;
1168 }
1169
1170 /*
1171 * If the old ACL contained any references to the new owner, then we may
1172 * now have generated an ACL containing duplicate entries. Find them and
1173 * merge them so that there are not duplicates. (This is relatively
1174 * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to
1175 * be the normal case.)
1176 *
1177 * To simplify deletion of duplicate entries, we temporarily leave them in
1178 * the array but set their privilege masks to zero; when we reach such an
1179 * entry it's just skipped. (Thus, a side effect of this code will be to
1180 * remove privilege-free entries, should there be any in the input.) dst
1181 * is the next output slot, targ is the currently considered input slot
1182 * (always >= dst), and src scans entries to the right of targ looking for
1183 * duplicates. Once an entry has been emitted to dst it is known
1184 * duplicate-free and need not be considered anymore.
1185 */
1186 if (newpresent)
1187 {
1188 dst = 0;
1189 for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1190 {
1191 /* ignore if deleted in an earlier pass */
1193 continue;
1194 /* find and merge any duplicates */
1195 for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1196 src++, src_aip++)
1197 {
1199 continue;
1201 {
1205 /* mark the duplicate deleted */
1207 }
1208 }
1209 /* and emit to output */
1210 new_aip[dst] = *targ_aip;
1211 dst++;
1212 }
1213 /* Adjust array size to be 'dst' items */
1214 ARR_DIMS(new_acl)[0] = dst;
1216 }
1217
1218 return new_acl;
1219}
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Definition acl.c:726
#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(), 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 1005 of file acl.c.

1007{
1008 Acl *new_acl = NULL;
1010 *new_aip = NULL;
1013 new_rights,
1015 int dst,
1016 num;
1017
1018 /* Caller probably already checked old_acl, but be safe */
1020
1021 /* If granting grant options, check for circularity */
1022 if (modechg != ACL_MODECHG_DEL &&
1025
1026 num = ACL_NUM(old_acl);
1028
1029 /*
1030 * Search the ACL for an existing entry for this grantee and grantor. If
1031 * one exists, just modify the entry in-place (well, in the same position,
1032 * since we actually return a copy); otherwise, insert the new entry at
1033 * the end.
1034 */
1035
1036 for (dst = 0; dst < num; ++dst)
1037 {
1039 {
1040 /* found a match, so modify existing item */
1041 new_acl = allocacl(num);
1044 break;
1045 }
1046 }
1047
1048 if (dst == num)
1049 {
1050 /* need to append a new item */
1051 new_acl = allocacl(num + 1);
1053 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1054
1055 /* initialize the new entry with no permissions */
1056 new_aip[dst].ai_grantee = mod_aip->ai_grantee;
1057 new_aip[dst].ai_grantor = mod_aip->ai_grantor;
1060 num++; /* set num to the size of new_acl */
1061 }
1062
1065
1066 /* apply the specified permissions change */
1067 switch (modechg)
1068 {
1069 case ACL_MODECHG_ADD:
1072 break;
1073 case ACL_MODECHG_DEL:
1076 break;
1077 case ACL_MODECHG_EQL:
1080 break;
1081 }
1082
1085
1086 /*
1087 * If the adjusted entry has no permissions, delete it from the list.
1088 */
1090 {
1092 new_aip + dst + 1,
1093 (num - dst - 1) * sizeof(AclItem));
1094 /* Adjust array size to be 'num - 1' items */
1095 ARR_DIMS(new_acl)[0] = num - 1;
1096 SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1097 }
1098
1099 /*
1100 * Remove abandoned privileges (cascading revoke). Currently we can only
1101 * handle this when the grantee is not PUBLIC.
1102 */
1103 if ((old_goptions & ~new_goptions) != 0)
1104 {
1105 Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1106 new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1108 ownerId, behavior);
1109 }
1110
1111 return new_acl;
1112}
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition acl.c:1315
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition acl.c:1235
#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:906

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(), 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 5355 of file acl.c.

5356{
5357 if (!member_can_set_role(member, role))
5358 ereport(ERROR,
5360 errmsg("must be able to SET ROLE \"%s\"",
5361 GetUserNameFromId(role, false))));
5362}
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5332
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c:989

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

5708{
5709 if (!role)
5710 return;
5711
5712 if (role->roletype != ROLESPEC_CSTRING)
5713 return;
5714
5715 if (IsReservedName(role->rolename))
5716 {
5717 if (detail_msg)
5718 ereport(ERROR,
5720 errmsg("role name \"%s\" is reserved",
5721 role->rolename),
5723 else
5724 ereport(ERROR,
5726 errmsg("role name \"%s\" is reserved",
5727 role->rolename)));
5728 }
5729}
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:419
RoleSpecType roletype
Definition parsenodes.h:429
char * rolename
Definition parsenodes.h:430

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

917{
918 GrantStmt *action = stmt->action;
920 ListCell *cell;
921 List *rolespecs = NIL;
922 List *nspnames = NIL;
926 const char *errormsg;
927
928 /* Deconstruct the "options" part of the statement */
929 foreach(cell, stmt->options)
930 {
931 DefElem *defel = (DefElem *) lfirst(cell);
932
933 if (strcmp(defel->defname, "schemas") == 0)
934 {
935 if (dnspnames)
938 }
939 else if (strcmp(defel->defname, "roles") == 0)
940 {
941 if (drolespecs)
944 }
945 else
946 elog(ERROR, "option \"%s\" not recognized", defel->defname);
947 }
948
949 if (dnspnames)
950 nspnames = (List *) dnspnames->arg;
951 if (drolespecs)
952 rolespecs = (List *) drolespecs->arg;
953
954 /* Prepare the InternalDefaultACL representation of the statement */
955 /* roleid to be filled below */
956 /* nspid to be filled in SetDefaultACLsInSchemas */
957 iacls.is_grant = action->is_grant;
958 iacls.objtype = action->objtype;
959 /* all_privs to be filled below */
960 /* privileges to be filled below */
961 iacls.grantees = NIL; /* filled below */
962 iacls.grant_option = action->grant_option;
963 iacls.behavior = action->behavior;
964
965 /*
966 * Convert the RoleSpec list into an Oid list. Note that at this point we
967 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
968 * there shouldn't be any additional work needed to support this case.
969 */
970 foreach(cell, action->grantees)
971 {
972 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
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 default:
1026 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1027 (int) action->objtype);
1028 /* keep compiler quiet */
1030 errormsg = NULL;
1031 }
1032
1033 if (action->privileges == NIL)
1034 {
1035 iacls.all_privs = true;
1036
1037 /*
1038 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1039 * depending on the object type
1040 */
1041 iacls.privileges = ACL_NO_RIGHTS;
1042 }
1043 else
1044 {
1045 iacls.all_privs = false;
1046 iacls.privileges = ACL_NO_RIGHTS;
1047
1048 foreach(cell, action->privileges)
1049 {
1050 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1051 AclMode priv;
1052
1053 if (privnode->cols)
1054 ereport(ERROR,
1056 errmsg("default privileges cannot be set for columns")));
1057
1058 if (privnode->priv_name == NULL) /* parser mistake? */
1059 elog(ERROR, "AccessPriv node must specify privilege");
1060 priv = string_to_privilege(privnode->priv_name);
1061
1062 if (priv & ~all_privileges)
1063 ereport(ERROR,
1065 errmsg(errormsg, privilege_to_string(priv))));
1066
1067 iacls.privileges |= priv;
1068 }
1069 }
1070
1071 if (rolespecs == NIL)
1072 {
1073 /* Set permissions for myself */
1074 iacls.roleid = GetUserId();
1075
1077 }
1078 else
1079 {
1080 /* Look up the role OIDs and do permissions checks */
1082
1083 foreach(rolecell, rolespecs)
1084 {
1086
1087 iacls.roleid = get_rolespec_oid(rolespec, false);
1088
1089 if (!has_privs_of_role(GetUserId(), iacls.roleid))
1090 ereport(ERROR,
1092 errmsg("permission denied to change default privileges")));
1093
1095 }
1096 }
1097}
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5600
static AclMode string_to_privilege(const char *privname)
Definition aclchk.c:2566
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition aclchk.c:1105
static const char * privilege_to_string(AclMode privilege)
Definition aclchk.c:2607
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:423
#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_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_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 391 of file aclchk.c.

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

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, elog, ereport, errcode(), errmsg, ERROR, ExecGrantStmt_oids(), fb(), get_rolespec_oid(), gettext_noop, GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, 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 5566 of file acl.c.

5567{
5568 Oid oid;
5569
5572 if (!OidIsValid(oid) && !missing_ok)
5573 ereport(ERROR,
5575 errmsg("role \"%s\" does not exist", rolname)));
5576 return oid;
5577}
#define OidIsValid(objectId)
Definition c.h:821
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
#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 5685 of file acl.c.

5686{
5687 HeapTuple tp;
5689 char *rolename;
5690
5691 tp = get_rolespec_tuple(role);
5693 rolename = pstrdup(NameStr(authForm->rolname));
5694 ReleaseSysCache(tp);
5695
5696 return rolename;
5697}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5639
#define NameStr(name)
Definition c.h:798
static void * GETSTRUCT(const HeapTupleData *tuple)
char * pstrdup(const char *in)
Definition mcxt.c:1781
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264

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

5601{
5602 Oid oid;
5603
5604 switch (role->roletype)
5605 {
5606 case ROLESPEC_CSTRING:
5607 Assert(role->rolename);
5608 oid = get_role_oid(role->rolename, missing_ok);
5609 break;
5610
5613 oid = GetUserId();
5614 break;
5615
5617 oid = GetSessionUserId();
5618 break;
5619
5620 case ROLESPEC_PUBLIC:
5621 ereport(ERROR,
5623 errmsg("role \"%s\" does not exist", "public")));
5624 oid = InvalidOid; /* make compiler happy */
5625 break;
5626
5627 default:
5628 elog(ERROR, "unexpected role type %d", role->roletype);
5629 }
5630
5631 return oid;
5632}
Oid GetSessionUserId(void)
Definition miscinit.c:509
@ ROLESPEC_CURRENT_USER
Definition parsenodes.h:421
@ ROLESPEC_SESSION_USER
Definition parsenodes.h:422
@ ROLESPEC_CURRENT_ROLE
Definition parsenodes.h:420
#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(), and roleSpecsToIds().

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)
extern

Definition at line 5639 of file acl.c.

5640{
5641 HeapTuple tuple;
5642
5643 switch (role->roletype)
5644 {
5645 case ROLESPEC_CSTRING:
5646 Assert(role->rolename);
5648 if (!HeapTupleIsValid(tuple))
5649 ereport(ERROR,
5651 errmsg("role \"%s\" does not exist", role->rolename)));
5652 break;
5653
5657 if (!HeapTupleIsValid(tuple))
5658 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5659 break;
5660
5663 if (!HeapTupleIsValid(tuple))
5664 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5665 break;
5666
5667 case ROLESPEC_PUBLIC:
5668 ereport(ERROR,
5670 errmsg("role \"%s\" does not exist", "public")));
5671 tuple = NULL; /* make compiler happy */
5672 break;
5673
5674 default:
5675 elog(ERROR, "unexpected role type %d", role->roletype);
5676 }
5677
5678 return tuple;
5679}
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220

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

4266{
4267 Acl *result;
4268 Acl *glob_acl;
4269 Acl *schema_acl;
4270 Acl *def_acl;
4271 char defaclobjtype;
4272
4273 /*
4274 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4275 * yet.
4276 */
4278 return NULL;
4279
4280 /* Check if object type is supported in pg_default_acl */
4281 switch (objtype)
4282 {
4283 case OBJECT_TABLE:
4284 defaclobjtype = DEFACLOBJ_RELATION;
4285 break;
4286
4287 case OBJECT_SEQUENCE:
4288 defaclobjtype = DEFACLOBJ_SEQUENCE;
4289 break;
4290
4291 case OBJECT_FUNCTION:
4292 defaclobjtype = DEFACLOBJ_FUNCTION;
4293 break;
4294
4295 case OBJECT_TYPE:
4296 defaclobjtype = DEFACLOBJ_TYPE;
4297 break;
4298
4299 case OBJECT_SCHEMA:
4300 defaclobjtype = DEFACLOBJ_NAMESPACE;
4301 break;
4302
4303 case OBJECT_LARGEOBJECT:
4304 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4305 break;
4306
4307 default:
4308 return NULL;
4309 }
4310
4311 /* Look up the relevant pg_default_acl entries */
4312 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4313 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4314
4315 /* Quick out if neither entry exists */
4316 if (glob_acl == NULL && schema_acl == NULL)
4317 return NULL;
4318
4319 /* We need to know the hard-wired default value, too */
4320 def_acl = acldefault(objtype, ownerId);
4321
4322 /* If there's no global entry, substitute the hard-wired default */
4323 if (glob_acl == NULL)
4324 glob_acl = def_acl;
4325
4326 /* Merge in any per-schema privileges */
4327 result = aclmerge(glob_acl, schema_acl, ownerId);
4328
4329 /*
4330 * For efficiency, we want to return NULL if the result equals default.
4331 * This requires sorting both arrays to get an accurate comparison.
4332 */
4333 aclitemsort(result);
4335 if (aclequal(result, def_acl))
4336 result = NULL;
4337
4338 return result;
4339}
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition acl.c:514
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:816
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:572
void aclitemsort(Acl *acl)
Definition acl.c:558
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition aclchk.c:4230
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)
extern

Definition at line 4206 of file aclchk.c.

4207{
4208 bool result = false;
4210
4211 /* Superusers bypass all permission checking. */
4212 if (superuser_arg(roleid))
4213 return true;
4214
4217 {
4220 }
4221 return result;
4222}
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(), 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 4187 of file aclchk.c.

4188{
4189 bool result = false;
4191
4192 /* Superusers bypass all permission checking. */
4193 if (superuser_arg(roleid))
4194 return true;
4195
4198 {
4201 }
4202 return result;
4203}
bool rolcreaterole
Definition pg_authid.h:39

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5298 of file acl.c.

5299{
5300 /* Fast path for simple case */
5301 if (member == role)
5302 return true;
5303
5304 /* Superusers have every privilege, so are part of every role */
5305 if (superuser_arg(member))
5306 return true;
5307
5308 /*
5309 * Find all the roles that member has the privileges of, including
5310 * multi-level recursion, then see if target role is any one of them.
5311 */
5313 InvalidOid, NULL),
5314 role);
5315}
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition acl.c:5166
@ ROLERECURSE_PRIVS
Definition acl.c:78
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(), shell_check_detail(), and TerminateOtherDBBackends().

◆ initialize_acl()

void initialize_acl ( void  )
extern

Definition at line 5053 of file acl.c.

5054{
5056 {
5060
5061 /*
5062 * In normal mode, set a callback on any syscache invalidation of rows
5063 * of pg_auth_members (for roles_is_member_of()) pg_database (for
5064 * roles_is_member_of())
5065 */
5068 (Datum) 0);
5071 (Datum) 0);
5074 (Datum) 0);
5075 }
5076}
static uint32 cached_db_hash
Definition acl.c:83
static void RoleMembershipCacheCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition acl.c:5083
Oid MyDatabaseId
Definition globals.c:94
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
Definition inval.c:1816
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 5428 of file acl.c.

5429{
5431
5432 if (superuser_arg(member))
5433 return true;
5434
5435 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5436 if (member == role)
5437 return false;
5438
5440 return OidIsValid(admin_role);
5441}
@ ROLERECURSE_MEMBERS
Definition acl.c:77

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

5379{
5380 /* Fast path for simple case */
5381 if (member == role)
5382 return true;
5383
5384 /* Superusers have every privilege, so are part of every role */
5385 if (superuser_arg(member))
5386 return true;
5387
5388 /*
5389 * Find all the roles that member is a member of, including multi-level
5390 * recursion, then see if target role is any one of them.
5391 */
5393 InvalidOid, NULL),
5394 role);
5395}

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

5407{
5408 /* Fast path for simple case */
5409 if (member == role)
5410 return true;
5411
5412 /*
5413 * Find all the roles that member is a member of, including multi-level
5414 * recursion, then see if target role is any one of them.
5415 */
5417 InvalidOid, NULL),
5418 role);
5419}

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

462{
463 return allocacl(0);
464}

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5332 of file acl.c.

5333{
5334 /* Fast path for simple case */
5335 if (member == role)
5336 return true;
5337
5338 /* Superusers have every privilege, so can always SET ROLE */
5339 if (superuser_arg(member))
5340 return true;
5341
5342 /*
5343 * Find all the roles that member can access via SET ROLE, including
5344 * multi-level recursion, then see if target role is any one of them.
5345 */
5347 InvalidOid, NULL),
5348 role);
5349}
@ ROLERECURSE_SETROLE
Definition acl.c:79

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

3855{
3856 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3857}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3864

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(), PrepareTempTablespaces(), preprocessNamespacePath(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), RenameSchema(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_aclcheck_ext()

◆ object_ownercheck()

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

Definition at line 4108 of file aclchk.c.

4109{
4111 Oid ownerId;
4112
4113 /* Superusers bypass all permission checking. */
4114 if (superuser_arg(roleid))
4115 return true;
4116
4117 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4118 if (classid == LargeObjectRelationId)
4120
4123 {
4124 /* we can get the object's tuple from the syscache */
4125 HeapTuple tuple;
4126
4128 if (!HeapTupleIsValid(tuple))
4129 elog(ERROR, "cache lookup failed for %s %u",
4131
4133 tuple,
4134 get_object_attnum_owner(classid)));
4135 ReleaseSysCache(tuple);
4136 }
4137 else
4138 {
4139 /* for catalogs without an appropriate syscache */
4140 Relation rel;
4141 ScanKeyData entry[1];
4142 SysScanDesc scan;
4143 HeapTuple tuple;
4144 bool isnull;
4145
4146 rel = table_open(classid, AccessShareLock);
4147
4148 ScanKeyInit(&entry[0],
4149 get_object_attnum_oid(classid),
4152
4153 scan = systable_beginscan(rel,
4154 get_object_oid_index(classid), true,
4155 NULL, 1, entry);
4156
4157 tuple = systable_getnext(scan);
4158 if (!HeapTupleIsValid(tuple))
4159 elog(ERROR, "could not find tuple for %s %u",
4161
4162 ownerId = DatumGetObjectId(heap_getattr(tuple,
4163 get_object_attnum_owner(classid),
4164 RelationGetDescr(rel),
4165 &isnull));
4166 Assert(!isnull);
4167
4168 systable_endscan(scan);
4170 }
4171
4172 return has_privs_of_role(roleid, ownerId);
4173}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#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:252
#define RelationGetDescr(relation)
Definition rel.h:540
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References AccessShareLock, Assert, BTEqualStrategyNumber, DatumGetObjectId(), elog, ERROR, 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 3886 of file aclchk.c.

3888{
3890}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3898

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

3930{
3932}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3939

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

3942{
3943 AclResult result;
3946 Oid ownerId;
3947 AttrNumber nattrs;
3949
3950 /*
3951 * Must fetch pg_class row to get owner ID and number of attributes.
3952 */
3955 {
3956 if (is_missing != NULL)
3957 {
3958 /* return "no privileges" instead of throwing an error */
3959 *is_missing = true;
3960 return ACLCHECK_NO_PRIV;
3961 }
3962 else
3963 ereport(ERROR,
3965 errmsg("relation with OID %u does not exist",
3966 table_oid)));
3967 }
3969
3970 ownerId = classForm->relowner;
3971 nattrs = classForm->relnatts;
3972
3974
3975 /*
3976 * Initialize result in case there are no non-dropped columns. We want to
3977 * report failure in such cases for either value of 'how'.
3978 */
3979 result = ACLCHECK_NO_PRIV;
3980
3981 for (curr_att = 1; curr_att <= nattrs; curr_att++)
3982 {
3985 bool isNull;
3986 Acl *acl;
3988
3992
3993 /*
3994 * Lookup failure probably indicates that the table was just dropped,
3995 * but we'll treat it the same as a dropped column rather than
3996 * throwing error.
3997 */
3999 continue;
4000
4001 /* ignore dropped columns */
4002 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4003 {
4005 continue;
4006 }
4007
4009 &isNull);
4010
4011 /*
4012 * Here we hard-wire knowledge that the default ACL for a column
4013 * grants no privileges, so that we can fall out quickly in the very
4014 * common case where attacl is null.
4015 */
4016 if (isNull)
4017 attmask = 0;
4018 else
4019 {
4020 /* detoast column's ACL if necessary */
4021 acl = DatumGetAclP(aclDatum);
4022
4023 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4024
4025 /* if we have a detoasted copy, free it */
4026 if (acl != DatumGetPointer(aclDatum))
4027 pfree(acl);
4028 }
4029
4031
4032 if (attmask != 0)
4033 {
4034 result = ACLCHECK_OK;
4035 if (how == ACLMASK_ANY)
4036 break; /* succeed on any success */
4037 }
4038 else
4039 {
4040 result = ACLCHECK_NO_PRIV;
4041 if (how == ACLMASK_ALL)
4042 break; /* fail on any failure */
4043 }
4044 }
4045
4046 return result;
4047}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1401
#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:182
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595

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

3900{
3902 ACLMASK_ANY, is_missing) != 0)
3903 return ACLCHECK_OK;
3904 else
3905 return ACLCHECK_NO_PRIV;
3906}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3158

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

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

3274{
3275 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3276}

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

4096{
4098 ACLMASK_ANY, snapshot) != 0)
4099 return ACLCHECK_OK;
4100 else
4101 return ACLCHECK_NO_PRIV;
4102}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition aclchk.c:3535

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

4083{
4084 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4085 return ACLCHECK_OK;
4086 else
4087 return ACLCHECK_NO_PRIV;
4088}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3412

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

4347{
4348 int nmembers;
4349 Oid *members;
4350
4351 /* Nothing to do if ACL is defaulted */
4352 if (acl == NULL)
4353 return;
4354
4355 /* Extract roles mentioned in ACL */
4356 nmembers = aclmembers(acl, &members);
4357
4358 /* Update the shared dependency ACL info */
4359 updateAclDependencies(classId, objectId, objsubId,
4360 ownerId,
4361 0, NULL,
4362 nmembers, members);
4363}
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1553
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 4372 of file aclchk.c.

4373{
4374 /*
4375 * pg_class / pg_attribute
4376 *
4377 * If this is a relation then we need to see if there are any sub-objects
4378 * (eg: columns) for it and, if so, be sure to call
4379 * recordExtensionInitPrivWorker() for each one.
4380 */
4381 if (classoid == RelationRelationId)
4382 {
4385 bool isNull;
4386 HeapTuple tuple;
4387
4388 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4389 if (!HeapTupleIsValid(tuple))
4390 elog(ERROR, "cache lookup failed for relation %u", objoid);
4392
4393 /*
4394 * Indexes don't have permissions, neither do the pg_class rows for
4395 * composite types. (These cases are unreachable given the
4396 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4397 */
4398 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4401 {
4402 ReleaseSysCache(tuple);
4403 return;
4404 }
4405
4406 /*
4407 * If this isn't a sequence then it's possibly going to have
4408 * column-level ACLs associated with it.
4409 */
4410 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4411 {
4413 AttrNumber nattrs = pg_class_tuple->relnatts;
4414
4415 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4416 {
4419
4421 ObjectIdGetDatum(objoid),
4423
4425 continue;
4426
4427 /* ignore dropped columns */
4428 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4429 {
4431 continue;
4432 }
4433
4436 &isNull);
4437
4438 /* no need to do anything for a NULL ACL */
4439 if (isNull)
4440 {
4442 continue;
4443 }
4444
4445 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4447
4449 }
4450 }
4451
4453 &isNull);
4454
4455 /* Add the record, if any, for the top-level object */
4456 if (!isNull)
4457 recordExtensionInitPrivWorker(objoid, classoid, 0,
4459
4460 ReleaseSysCache(tuple);
4461 }
4462 else if (classoid == LargeObjectRelationId)
4463 {
4464 /* For large objects, we must consult pg_largeobject_metadata */
4466 bool isNull;
4467 HeapTuple tuple;
4468 ScanKeyData entry[1];
4469 SysScanDesc scan;
4470 Relation relation;
4471
4472 /*
4473 * Note: this is dead code, given that we don't allow large objects to
4474 * be made extension members. But it seems worth carrying in case
4475 * some future caller of this function has need for it.
4476 */
4478
4479 /* There's no syscache for pg_largeobject_metadata */
4480 ScanKeyInit(&entry[0],
4483 ObjectIdGetDatum(objoid));
4484
4485 scan = systable_beginscan(relation,
4487 NULL, 1, entry);
4488
4489 tuple = systable_getnext(scan);
4490 if (!HeapTupleIsValid(tuple))
4491 elog(ERROR, "could not find tuple for large object %u", objoid);
4492
4493 aclDatum = heap_getattr(tuple,
4495 RelationGetDescr(relation), &isNull);
4496
4497 /* Add the record, if any, for the top-level object */
4498 if (!isNull)
4499 recordExtensionInitPrivWorker(objoid, classoid, 0,
4501
4502 systable_endscan(scan);
4503 }
4504 /* This will error on unsupported classoid. */
4505 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4506 {
4509 bool isNull;
4510 HeapTuple tuple;
4511
4512 cacheid = get_object_catcache_oid(classoid);
4513 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4514 if (!HeapTupleIsValid(tuple))
4515 elog(ERROR, "cache lookup failed for %s %u",
4516 get_object_class_descr(classoid), objoid);
4517
4519 get_object_attnum_acl(classoid),
4520 &isNull);
4521
4522 /* Add the record, if any, for the top-level object */
4523 if (!isNull)
4524 recordExtensionInitPrivWorker(objoid, classoid, 0,
4526
4527 ReleaseSysCache(tuple);
4528 }
4529}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4648
#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 4536 of file aclchk.c.

4537{
4538 /*
4539 * If this is a relation then we need to see if there are any sub-objects
4540 * (eg: columns) for it and, if so, be sure to call
4541 * recordExtensionInitPrivWorker() for each one.
4542 */
4543 if (classoid == RelationRelationId)
4544 {
4546 HeapTuple tuple;
4547
4548 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4549 if (!HeapTupleIsValid(tuple))
4550 elog(ERROR, "cache lookup failed for relation %u", objoid);
4552
4553 /*
4554 * Indexes don't have permissions, neither do the pg_class rows for
4555 * composite types. (These cases are unreachable given the
4556 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4557 */
4558 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4561 {
4562 ReleaseSysCache(tuple);
4563 return;
4564 }
4565
4566 /*
4567 * If this isn't a sequence then it's possibly going to have
4568 * column-level ACLs associated with it.
4569 */
4570 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4571 {
4573 AttrNumber nattrs = pg_class_tuple->relnatts;
4574
4575 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4576 {
4578
4580 ObjectIdGetDatum(objoid),
4582
4584 continue;
4585
4586 /* when removing, remove all entries, even dropped columns */
4587
4588 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4589
4591 }
4592 }
4593
4594 ReleaseSysCache(tuple);
4595 }
4596
4597 /* Remove the record, if any, for the top-level object */
4598 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4599}

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

4886{
4887 Relation rel;
4888 ScanKeyData key[3];
4889 SysScanDesc scan;
4890 HeapTuple oldtuple;
4893 Oid ownerId;
4895 bool isNull;
4896 Acl *old_acl;
4897 Acl *new_acl;
4898 HeapTuple newtuple;
4899 int noldmembers;
4900 int nnewmembers;
4901 Oid *oldmembers;
4902 Oid *newmembers;
4903
4904 /* Search for existing pg_init_privs entry for the target object. */
4906
4907 ScanKeyInit(&key[0],
4910 ObjectIdGetDatum(objid));
4911 ScanKeyInit(&key[1],
4914 ObjectIdGetDatum(classid));
4915 ScanKeyInit(&key[2],
4918 Int32GetDatum(objsubid));
4919
4920 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4921 NULL, 3, key);
4922
4923 /* There should exist only one entry or none. */
4924 oldtuple = systable_getnext(scan);
4925
4926 if (!HeapTupleIsValid(oldtuple))
4927 {
4928 /*
4929 * Hmm, why are we here if there's no entry? But pack up and go away
4930 * quietly.
4931 */
4932 systable_endscan(scan);
4934 return;
4935 }
4936
4937 /* Get a writable copy of the existing ACL. */
4939 RelationGetDescr(rel), &isNull);
4940 Assert(!isNull);
4942
4943 /*
4944 * We need the members of both old and new ACLs so we can correct the
4945 * shared dependency information. Collect data before
4946 * merge_acl_with_grant throws away old_acl.
4947 */
4949
4950 /* Must find out the owner's OID the hard way. */
4954 elog(ERROR, "cache lookup failed for %s %u",
4955 get_object_class_descr(classid), objid);
4956
4958 objtuple,
4959 get_object_attnum_owner(classid)));
4961
4962 /*
4963 * Generate new ACL. Grantor of rights is always the same as the owner.
4964 */
4965 if (old_acl != NULL)
4967 false, /* is_grant */
4968 false, /* grant_option */
4970 list_make1_oid(roleid),
4972 ownerId,
4973 ownerId);
4974 else
4975 new_acl = NULL; /* this case shouldn't happen, probably */
4976
4977 /* If we end with an empty ACL, delete the pg_init_privs entry. */
4978 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4979 {
4980 CatalogTupleDelete(rel, &oldtuple->t_self);
4981 }
4982 else
4983 {
4985 bool nulls[Natts_pg_init_privs] = {0};
4986 bool replaces[Natts_pg_init_privs] = {0};
4987
4988 /* Update existing entry. */
4991
4992 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4993 values, nulls, replaces);
4994 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4995 }
4996
4997 /*
4998 * Update the shared dependency ACL info.
4999 */
5001
5002 updateInitAclDependencies(classid, objid, objsubid,
5005
5006 systable_endscan(scan);
5007
5008 /* prevent error when processing objects multiple times */
5010
5012}
#define ACLITEM_ALL_PRIV_BITS
Definition acl.h:87
#define DatumGetAclPCopy(X)
Definition acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition aclchk.c:181
static Datum values[MAXATTR]
Definition bootstrap.c:187
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
void CatalogTupleUpdate(Relation heapRel, 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:242
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
ItemPointerData t_self
Definition htup.h:65
void CommandCounterIncrement(void)
Definition xact.c:1102

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

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

4778{
4779 Relation rel;
4780 ScanKeyData key[3];
4781 SysScanDesc scan;
4782 HeapTuple oldtuple;
4784 bool isNull;
4785 Acl *old_acl;
4786 Acl *new_acl;
4787 HeapTuple newtuple;
4788 int noldmembers;
4789 int nnewmembers;
4790 Oid *oldmembers;
4791 Oid *newmembers;
4792
4793 /* Search for existing pg_init_privs entry for the target object. */
4795
4796 ScanKeyInit(&key[0],
4799 ObjectIdGetDatum(objid));
4800 ScanKeyInit(&key[1],
4803 ObjectIdGetDatum(classid));
4804 ScanKeyInit(&key[2],
4807 Int32GetDatum(objsubid));
4808
4809 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4810 NULL, 3, key);
4811
4812 /* There should exist only one entry or none. */
4813 oldtuple = systable_getnext(scan);
4814
4815 if (!HeapTupleIsValid(oldtuple))
4816 {
4817 /*
4818 * Hmm, why are we here if there's no entry? But pack up and go away
4819 * quietly.
4820 */
4821 systable_endscan(scan);
4823 return;
4824 }
4825
4826 /* Get a writable copy of the existing ACL. */
4828 RelationGetDescr(rel), &isNull);
4829 Assert(!isNull);
4831
4832 /*
4833 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4834 * oldroleid isn't the owner; but it does the job fine.
4835 */
4837
4838 /*
4839 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4840 * probably can't happen here, but we may as well cover the case.)
4841 */
4842 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4843 {
4844 CatalogTupleDelete(rel, &oldtuple->t_self);
4845 }
4846 else
4847 {
4849 bool nulls[Natts_pg_init_privs] = {0};
4850 bool replaces[Natts_pg_init_privs] = {0};
4851
4852 /* Update existing entry. */
4855
4856 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4857 values, nulls, replaces);
4858 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4859 }
4860
4861 /*
4862 * Update the shared dependency ACL info.
4863 */
4866
4867 updateInitAclDependencies(classid, objid, objsubid,
4870
4871 systable_endscan(scan);
4872
4873 /* prevent error when processing objects multiple times */
4875
4877}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1132

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

5454{
5456
5457 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5458 if (member == role)
5459 return InvalidOid;
5460
5462 return admin_role;
5463}

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

Referenced by check_role_grantor().

◆ select_best_grantor()

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

Definition at line 5490 of file acl.c.

5493{
5496 int nrights;
5497 ListCell *l;
5498
5499 /*
5500 * The object owner is always treated as having all grant options, so if
5501 * roleId is the owner it's easy. Also, if roleId is a superuser it's
5502 * easy: superusers are implicitly members of every role, so they act as
5503 * the object owner.
5504 */
5505 if (roleId == ownerId || superuser_arg(roleId))
5506 {
5507 *grantorId = ownerId;
5509 return;
5510 }
5511
5512 /*
5513 * Otherwise we have to do a careful search to see if roleId has the
5514 * privileges of any suitable role. Note: we can hang onto the result of
5515 * roles_is_member_of() throughout this loop, because aclmask_direct()
5516 * doesn't query any role memberships.
5517 */
5519 InvalidOid, NULL);
5520
5521 /* initialize candidate result as default */
5522 *grantorId = roleId;
5524 nrights = 0;
5525
5526 foreach(l, roles_list)
5527 {
5530
5531 otherprivs = aclmask_direct(acl, otherrole, ownerId,
5534 {
5535 /* Found a suitable grantor */
5538 return;
5539 }
5540
5541 /*
5542 * If it has just some of the needed privileges, remember best
5543 * candidate.
5544 */
5546 {
5548
5549 if (nnewrights > nrights)
5550 {
5554 }
5555 }
5556 }
5557}
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1490
#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(), fb(), 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().