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

Go to the source code of this file.

Data Structures

struct  AclItem
 

Macros

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

Typedefs

typedef struct AclItem AclItem
 
typedef struct ArrayType Acl
 

Enumerations

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

Functions

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

Macro Definition Documentation

◆ ACL_ALL_RIGHTS_COLUMN

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

Definition at line 159 of file acl.h.

◆ ACL_ALL_RIGHTS_DATABASE

#define ACL_ALL_RIGHTS_DATABASE   (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)

Definition at line 162 of file acl.h.

◆ ACL_ALL_RIGHTS_FDW

#define ACL_ALL_RIGHTS_FDW   (ACL_USAGE)

Definition at line 163 of file acl.h.

◆ ACL_ALL_RIGHTS_FOREIGN_SERVER

#define ACL_ALL_RIGHTS_FOREIGN_SERVER   (ACL_USAGE)

Definition at line 164 of file acl.h.

◆ ACL_ALL_RIGHTS_FUNCTION

#define ACL_ALL_RIGHTS_FUNCTION   (ACL_EXECUTE)

Definition at line 165 of file acl.h.

◆ ACL_ALL_RIGHTS_LANGUAGE

#define ACL_ALL_RIGHTS_LANGUAGE   (ACL_USAGE)

Definition at line 166 of file acl.h.

◆ ACL_ALL_RIGHTS_LARGEOBJECT

#define ACL_ALL_RIGHTS_LARGEOBJECT   (ACL_SELECT|ACL_UPDATE)

Definition at line 167 of file acl.h.

◆ ACL_ALL_RIGHTS_PARAMETER_ACL

#define ACL_ALL_RIGHTS_PARAMETER_ACL   (ACL_SET|ACL_ALTER_SYSTEM)

Definition at line 168 of file acl.h.

◆ ACL_ALL_RIGHTS_PROPGRAPH

#define ACL_ALL_RIGHTS_PROPGRAPH   (ACL_SELECT)

Definition at line 169 of file acl.h.

◆ ACL_ALL_RIGHTS_RELATION

Definition at line 160 of file acl.h.

◆ ACL_ALL_RIGHTS_SCHEMA

#define ACL_ALL_RIGHTS_SCHEMA   (ACL_USAGE|ACL_CREATE)

Definition at line 170 of file acl.h.

◆ ACL_ALL_RIGHTS_SEQUENCE

#define ACL_ALL_RIGHTS_SEQUENCE   (ACL_USAGE|ACL_SELECT|ACL_UPDATE)

Definition at line 161 of file acl.h.

◆ ACL_ALL_RIGHTS_STR

#define ACL_ALL_RIGHTS_STR   "arwdDxtXUCTcsAm"

Definition at line 154 of file acl.h.

◆ ACL_ALL_RIGHTS_TABLESPACE

#define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)

Definition at line 171 of file acl.h.

◆ ACL_ALL_RIGHTS_TYPE

#define ACL_ALL_RIGHTS_TYPE   (ACL_USAGE)

Definition at line 172 of file acl.h.

◆ ACL_ALTER_SYSTEM_CHR

#define ACL_ALTER_SYSTEM_CHR   'A'

Definition at line 150 of file acl.h.

◆ ACL_CONNECT_CHR

#define ACL_CONNECT_CHR   'c'

Definition at line 148 of file acl.h.

◆ ACL_CREATE_CHR

#define ACL_CREATE_CHR   'C'

Definition at line 146 of file acl.h.

◆ ACL_CREATE_TEMP_CHR

#define ACL_CREATE_TEMP_CHR   'T'

Definition at line 147 of file acl.h.

◆ ACL_DAT

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

Definition at line 109 of file acl.h.

◆ ACL_DELETE_CHR

#define ACL_DELETE_CHR   'd'

Definition at line 140 of file acl.h.

◆ ACL_EXECUTE_CHR

#define ACL_EXECUTE_CHR   'X'

Definition at line 144 of file acl.h.

◆ ACL_GRANT_OPTION_FOR

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

Definition at line 70 of file acl.h.

◆ ACL_ID_PUBLIC

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

Definition at line 46 of file acl.h.

◆ ACL_INSERT_CHR

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

Definition at line 137 of file acl.h.

◆ ACL_MAINTAIN_CHR

#define ACL_MAINTAIN_CHR   'm'

Definition at line 151 of file acl.h.

◆ ACL_MODECHG_ADD

#define ACL_MODECHG_ADD   1

Definition at line 129 of file acl.h.

◆ ACL_MODECHG_DEL

#define ACL_MODECHG_DEL   2

Definition at line 130 of file acl.h.

◆ ACL_MODECHG_EQL

#define ACL_MODECHG_EQL   3

Definition at line 131 of file acl.h.

◆ ACL_N_SIZE

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

Definition at line 110 of file acl.h.

◆ ACL_NUM

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

Definition at line 108 of file acl.h.

◆ ACL_OPTION_TO_PRIVS

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

Definition at line 71 of file acl.h.

◆ ACL_REFERENCES_CHR

#define ACL_REFERENCES_CHR   'x'

Definition at line 142 of file acl.h.

◆ ACL_SELECT_CHR

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

Definition at line 138 of file acl.h.

◆ ACL_SET_CHR

#define ACL_SET_CHR   's'

Definition at line 149 of file acl.h.

◆ ACL_SIZE

#define ACL_SIZE (   ACL)    ARR_SIZE(ACL)

Definition at line 111 of file acl.h.

◆ ACL_TRIGGER_CHR

#define ACL_TRIGGER_CHR   't'

Definition at line 143 of file acl.h.

◆ ACL_TRUNCATE_CHR

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

Definition at line 141 of file acl.h.

◆ ACL_UPDATE_CHR

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

Definition at line 139 of file acl.h.

◆ ACL_USAGE_CHR

#define ACL_USAGE_CHR   'U'

Definition at line 145 of file acl.h.

◆ ACLITEM_ALL_GOPTION_BITS

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

Definition at line 88 of file acl.h.

◆ ACLITEM_ALL_PRIV_BITS

#define ACLITEM_ALL_PRIV_BITS   ((AclMode) 0xFFFFFFFF)

Definition at line 87 of file acl.h.

◆ ACLITEM_GET_GOPTIONS

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

Definition at line 67 of file acl.h.

◆ ACLITEM_GET_PRIVS

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

Definition at line 66 of file acl.h.

◆ ACLITEM_GET_RIGHTS

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

Definition at line 68 of file acl.h.

◆ ACLITEM_SET_GOPTIONS

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

Definition at line 76 of file acl.h.

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

◆ ACLITEM_SET_PRIVS

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

Definition at line 73 of file acl.h.

◆ ACLITEM_SET_PRIVS_GOPTIONS

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

Definition at line 82 of file acl.h.

◆ ACLITEM_SET_RIGHTS

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

Definition at line 79 of file acl.h.

◆ DatumGetAclItemP

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

Definition at line 116 of file acl.h.

◆ DatumGetAclP

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

Definition at line 120 of file acl.h.

◆ DatumGetAclPCopy

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

Definition at line 121 of file acl.h.

◆ PG_GETARG_ACL_P

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

Definition at line 122 of file acl.h.

◆ PG_GETARG_ACL_P_COPY

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

Definition at line 123 of file acl.h.

◆ PG_GETARG_ACLITEM_P

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

Definition at line 117 of file acl.h.

◆ PG_RETURN_ACL_P

#define PG_RETURN_ACL_P (   x)    PG_RETURN_POINTER(x)

Definition at line 124 of file acl.h.

◆ PG_RETURN_ACLITEM_P

#define PG_RETURN_ACLITEM_P (   x)    PG_RETURN_POINTER(x)

Definition at line 118 of file acl.h.

Typedef Documentation

◆ Acl

Definition at line 106 of file acl.h.

◆ AclItem

Enumeration Type Documentation

◆ AclMaskHow

Enumerator
ACLMASK_ALL 
ACLMASK_ANY 

Definition at line 175 of file acl.h.

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

◆ AclResult

Enumerator
ACLCHECK_OK 
ACLCHECK_NO_PRIV 
ACLCHECK_NOT_OWNER 

Definition at line 182 of file acl.h.

Function Documentation

◆ aclcheck_error()

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

Definition at line 2672 of file aclchk.c.

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

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg, ERROR, fb(), gettext_noop, OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), currtid_internal(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecCheckPermissions(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_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 2967 of file aclchk.c.

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

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

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

◆ aclconcat()

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

Definition at line 491 of file acl.c.

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

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

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl * aclcopy ( const Acl orig_acl)
extern

Definition at line 471 of file acl.c.

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

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

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)
extern

Definition at line 827 of file acl.c.

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

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_CONNECT, ACL_CREATE_TEMP, ACL_DAT, ACL_EXECUTE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_USAGE, ACLITEM_SET_PRIVS_GOPTIONS, allocacl(), elog, ERROR, fb(), OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROPGRAPH, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, and OBJECT_TYPE.

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

◆ aclequal()

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

Definition at line 573 of file acl.c.

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

References ACL_DAT, ACL_NUM, and fb().

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

◆ aclitemsort()

void aclitemsort ( Acl acl)
extern

Definition at line 559 of file acl.c.

560{
561 if (acl != NULL && ACL_NUM(acl) > 1)
562 qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
563}
static int aclitemComparator(const void *arg1, const void *arg2)
Definition acl.c:748
#define qsort(a, b, c, d)
Definition port.h: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 1416 of file acl.c.

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

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

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

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

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

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

◆ aclupdate()

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

Definition at line 1020 of file acl.c.

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

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

5372{
5373 if (!member_can_set_role(member, role))
5374 ereport(ERROR,
5376 errmsg("must be able to SET ROLE \"%s\"",
5377 GetUserNameFromId(role, false))));
5378}
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5348
char * GetUserNameFromId(Oid roleid, bool noerr)
Definition miscinit.c: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 5746 of file acl.c.

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

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

Referenced by ProcessUtilitySlow().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)
extern

Definition at line 395 of file aclchk.c.

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

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, elog, ereport, errcode(), errmsg, ERROR, ExecGrantStmt_oids(), fb(), get_rolespec_oid(), gettext_noop, InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, privilege_to_string(), InternalGrant::privileges, ROLESPEC_PUBLIC, stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ get_role_oid()

Oid get_role_oid ( const char rolname,
bool  missing_ok 
)
extern

Definition at line 5605 of file acl.c.

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

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

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

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char * get_rolespec_name ( const RoleSpec role)
extern

Definition at line 5724 of file acl.c.

5725{
5726 HeapTuple tp;
5728 char *rolename;
5729
5730 tp = get_rolespec_tuple(role);
5732 rolename = pstrdup(NameStr(authForm->rolname));
5733 ReleaseSysCache(tp);
5734
5735 return rolename;
5736}
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5678
#define NameStr(name)
Definition c.h:837
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:265

References fb(), Form_pg_authid, get_rolespec_tuple(), GETSTRUCT(), NameStr, pstrdup(), and ReleaseSysCache().

Referenced by AddRoleMems(), and DelRoleMems().

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)
extern

Definition at line 5639 of file acl.c.

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

◆ get_rolespec_tuple()

HeapTuple get_rolespec_tuple ( const RoleSpec role)
extern

Definition at line 5678 of file acl.c.

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

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

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

◆ get_user_default_acl()

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

Definition at line 4290 of file aclchk.c.

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

4232{
4233 bool result = false;
4235
4236 /* Superusers bypass all permission checking. */
4237 if (superuser_arg(roleid))
4238 return true;
4239
4242 {
4245 }
4246 return result;
4247}
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 4212 of file aclchk.c.

4213{
4214 bool result = false;
4216
4217 /* Superusers bypass all permission checking. */
4218 if (superuser_arg(roleid))
4219 return true;
4220
4223 {
4226 }
4227 return result;
4228}
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 5314 of file acl.c.

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

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

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

◆ initialize_acl()

void initialize_acl ( void  )
extern

Definition at line 5069 of file acl.c.

5070{
5072 {
5076
5077 /*
5078 * In normal mode, set a callback on any syscache invalidation of rows
5079 * of pg_auth_members (for roles_is_member_of()) pg_database (for
5080 * roles_is_member_of())
5081 */
5084 (Datum) 0);
5087 (Datum) 0);
5090 (Datum) 0);
5091 }
5092}
static uint32 cached_db_hash
Definition acl.c:84
static void RoleMembershipCacheCallback(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
Definition acl.c:5099
Oid MyDatabaseId
Definition globals.c: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 5444 of file acl.c.

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

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

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

◆ is_member_of_role()

bool is_member_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5394 of file acl.c.

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

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

Referenced by pg_role_aclcheck().

◆ is_member_of_role_nosuper()

bool is_member_of_role_nosuper ( Oid  member,
Oid  role 
)
extern

Definition at line 5422 of file acl.c.

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

References fb(), InvalidOid, list_member_oid(), ROLERECURSE_MEMBERS, and roles_is_member_of().

Referenced by AddRoleMems(), and is_member().

◆ make_empty_acl()

Acl * make_empty_acl ( void  )
extern

Definition at line 462 of file acl.c.

463{
464 return allocacl(0);
465}

References allocacl().

Referenced by SetDefaultACL().

◆ member_can_set_role()

bool member_can_set_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5348 of file acl.c.

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

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

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

◆ object_aclcheck()

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

Definition at line 3879 of file aclchk.c.

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

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

4134{
4136 Oid ownerId;
4137
4138 /* Superusers bypass all permission checking. */
4139 if (superuser_arg(roleid))
4140 return true;
4141
4142 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4143 if (classid == LargeObjectRelationId)
4145
4148 {
4149 /* we can get the object's tuple from the syscache */
4150 HeapTuple tuple;
4151
4153 if (!HeapTupleIsValid(tuple))
4154 elog(ERROR, "cache lookup failed for %s %u",
4156
4158 tuple,
4159 get_object_attnum_owner(classid)));
4160 ReleaseSysCache(tuple);
4161 }
4162 else
4163 {
4164 /* for catalogs without an appropriate syscache */
4165 Relation rel;
4166 ScanKeyData entry[1];
4167 SysScanDesc scan;
4168 HeapTuple tuple;
4169 bool isnull;
4170
4171 rel = table_open(classid, AccessShareLock);
4172
4173 ScanKeyInit(&entry[0],
4174 get_object_attnum_oid(classid),
4177
4178 scan = systable_beginscan(rel,
4179 get_object_oid_index(classid), true,
4180 NULL, 1, entry);
4181
4182 tuple = systable_getnext(scan);
4183 if (!HeapTupleIsValid(tuple))
4184 elog(ERROR, "could not find tuple for %s %u",
4186
4187 ownerId = DatumGetObjectId(heap_getattr(tuple,
4188 get_object_attnum_owner(classid),
4189 RelationGetDescr(rel),
4190 &isnull));
4191 Assert(!isnull);
4192
4193 systable_endscan(scan);
4195 }
4196
4197 return has_privs_of_role(roleid, ownerId);
4198}
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:242
#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:626
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

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

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

◆ pg_attribute_aclcheck()

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

Definition at line 3911 of file aclchk.c.

3913{
3915}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3923

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

3955{
3957}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3964

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

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

References ACLCHECK_NO_PRIV, ACLCHECK_OK, aclmask(), ACLMASK_ALL, ACLMASK_ANY, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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 3923 of file aclchk.c.

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

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

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

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

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

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

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

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

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

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

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

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)
extern

Definition at line 4397 of file aclchk.c.

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

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

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

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

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

References AccessShareLock, ACL_NO_RIGHTS, InternalGrant::all_privs, InternalGrant::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DROP_CASCADE, elog, ERROR, ExecGrantStmt_oids(), fb(), Form_pg_default_acl, GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, HeapTupleIsValid, InternalGrant::is_grant, list_make1_oid, NIL, OBJECT_DATABASE, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, ObjectIdGetDatum(), InternalGrant::objects, InternalGrant::objtype, InternalGrant::privileges, ScanKeyInit(), SetDefaultACL(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

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

Definition at line 4801 of file aclchk.c.

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

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

Referenced by shdepReassignOwned_InitAcl().

◆ select_best_admin()

Oid select_best_admin ( Oid  member,
Oid  role 
)
extern

Definition at line 5469 of file acl.c.

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

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

Referenced by check_role_grantor().

◆ select_best_grantor()

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

Definition at line 5508 of file acl.c.

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

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

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