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:3912
void initialize_acl(void)
Definition acl.c:5072
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:4142
void RemoveRoleFromInitPriv(Oid roleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4933
bool is_admin_of_role(Oid member, Oid role)
Definition acl.c:5447
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:4254
AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:4115
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:3987
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4393
Oid select_best_admin(Oid member, Oid role)
Definition acl.c:5472
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
Oid get_role_oid_or_public(const char *rolname)
Definition acl.c:5626
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:3976
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1023
bool is_member_of_role(Oid member, Oid role)
Definition acl.c:5397
AclResult pg_parameter_aclcheck(const char *name, Oid roleid, AclMode mode)
Definition aclchk.c:4130
void ReplaceRoleInInitPriv(Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
Definition aclchk.c:4824
bool is_member_of_role_nosuper(Oid member, Oid role)
Definition acl.c:5425
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5317
Acl * make_empty_acl(void)
Definition acl.c:462
void recordExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4420
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1571
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1150
bool member_can_set_role(Oid member, Oid role)
Definition acl.c:5351
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:1419
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:3934
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition acl.c:5608
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3902
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4156
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3946
char * get_rolespec_name(const RoleSpec *role)
Definition acl.c:5727
void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5511
void check_can_set_role(Oid member, Oid role)
Definition acl.c:5374
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3298
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Definition acl.c:5749
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition aclchk.c:2997
bool has_createrole_privilege(Oid roleid)
Definition aclchk.c:4235
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:5642
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4313
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:4105
HeapTuple get_rolespec_tuple(const RoleSpec *role)
Definition acl.c:5681
void removeExtObjInitPriv(Oid objoid, Oid classoid)
Definition aclchk.c:4584
int16 AttrNumber
Definition attnum.h:21
int32_t int32
Definition c.h:679
#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:1344
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
static char * errmsg
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ OBJECT_PROPGRAPH
@ OBJECT_ACCESS_METHOD
@ OBJECT_OPCLASS
@ OBJECT_DEFACL
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_SCHEMA
@ OBJECT_POLICY
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_COLUMN
@ OBJECT_TABLESPACE
@ OBJECT_ROLE
@ OBJECT_ROUTINE
@ OBJECT_LARGEOBJECT
@ OBJECT_PUBLICATION_NAMESPACE
@ OBJECT_PROCEDURE
@ OBJECT_EXTENSION
@ OBJECT_INDEX
@ OBJECT_DEFAULT
@ OBJECT_DATABASE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_LANGUAGE
@ OBJECT_AMOP
@ OBJECT_PUBLICATION_REL
@ OBJECT_FOREIGN_SERVER
@ OBJECT_TSDICTIONARY
@ OBJECT_ATTRIBUTE
@ OBJECT_PUBLICATION
@ OBJECT_RULE
@ OBJECT_CONVERSION
@ OBJECT_AMPROC
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_PARAMETER_ACL
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_SUBSCRIPTION
@ OBJECT_STATISTIC_EXT
@ OBJECT_CAST
@ OBJECT_TRIGGER
@ OBJECT_TRANSFORM

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

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

◆ aclcheck_error_col()

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

Definition at line 2967 of file aclchk.c.

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

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

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

◆ aclconcat()

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

Definition at line 491 of file acl.c.

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

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

Referenced by ExecGrant_Attribute().

◆ aclcopy()

Acl * aclcopy ( const Acl orig_acl)
extern

Definition at line 471 of file acl.c.

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

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

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

◆ acldefault()

Acl * acldefault ( ObjectType  objtype,
Oid  ownerId 
)
extern

Definition at line 827 of file acl.c.

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

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

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

◆ aclequal()

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

Definition at line 573 of file acl.c.

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

References ACL_DAT, ACL_NUM, and fb().

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

◆ aclitemsort()

void aclitemsort ( Acl acl)
extern

Definition at line 559 of file acl.c.

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

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

Referenced by get_user_default_acl(), and SetDefaultACL().

◆ aclmask()

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

Definition at line 1419 of file acl.c.

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

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

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

◆ aclmembers()

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

Definition at line 1571 of file acl.c.

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

References ACL_DAT, ACL_ID_PUBLIC, ACL_NUM, check_acl(), fb(), i, j, oid_cmp(), palloc(), qsort, and qunique().

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

◆ aclmerge()

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

Definition at line 515 of file acl.c.

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

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

Referenced by get_user_default_acl().

◆ aclnewowner()

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

Definition at line 1150 of file acl.c.

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

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

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

◆ aclupdate()

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

Definition at line 1023 of file acl.c.

1025{
1026 Acl *new_acl = NULL;
1028 *new_aip = NULL;
1031 new_rights,
1033 int dst,
1034 num;
1035
1036 /* Caller probably already checked old_acl, but be safe */
1038
1039 /* If granting grant options, check for circularity */
1040 if (modechg != ACL_MODECHG_DEL &&
1043
1044 num = ACL_NUM(old_acl);
1046
1047 /*
1048 * Search the ACL for an existing entry for this grantee and grantor. If
1049 * one exists, just modify the entry in-place (well, in the same position,
1050 * since we actually return a copy); otherwise, insert the new entry at
1051 * the end.
1052 */
1053
1054 for (dst = 0; dst < num; ++dst)
1055 {
1057 {
1058 /* found a match, so modify existing item */
1059 new_acl = allocacl(num);
1062 break;
1063 }
1064 }
1065
1066 if (dst == num)
1067 {
1068 /* need to append a new item */
1069 new_acl = allocacl(num + 1);
1071 memcpy(new_aip, old_aip, num * sizeof(AclItem));
1072
1073 /* initialize the new entry with no permissions */
1074 new_aip[dst].ai_grantee = mod_aip->ai_grantee;
1075 new_aip[dst].ai_grantor = mod_aip->ai_grantor;
1078 num++; /* set num to the size of new_acl */
1079 }
1080
1083
1084 /* apply the specified permissions change */
1085 switch (modechg)
1086 {
1087 case ACL_MODECHG_ADD:
1090 break;
1091 case ACL_MODECHG_DEL:
1094 break;
1095 case ACL_MODECHG_EQL:
1098 break;
1099 }
1100
1103
1104 /*
1105 * If the adjusted entry has no permissions, delete it from the list.
1106 */
1108 {
1110 new_aip + dst + 1,
1111 (num - dst - 1) * sizeof(AclItem));
1112 /* Adjust array size to be 'num - 1' items */
1113 ARR_DIMS(new_acl)[0] = num - 1;
1114 SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1));
1115 }
1116
1117 /*
1118 * Remove abandoned privileges (cascading revoke). Currently we can only
1119 * handle this when the grantee is not PUBLIC.
1120 */
1121 if ((old_goptions & ~new_goptions) != 0)
1122 {
1123 Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC);
1124 new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
1126 ownerId, behavior);
1127 }
1128
1129 return new_acl;
1130}
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
Definition acl.c:1333
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
Definition acl.c:1253
#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:1002

References ACL_DAT, ACL_ID_PUBLIC, ACL_MODECHG_ADD, ACL_MODECHG_DEL, ACL_MODECHG_EQL, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACL_SIZE, ACLITEM_GET_GOPTIONS, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_PRIVS_GOPTIONS, ACLITEM_SET_RIGHTS, allocacl(), ARR_DIMS, Assert, check_acl(), check_circularity(), fb(), memcpy(), recursive_revoke(), and SET_VARSIZE().

Referenced by aclmerge(), check_circularity(), merge_acl_with_grant(), and recursive_revoke().

◆ check_can_set_role()

void check_can_set_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5374 of file acl.c.

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

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

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

◆ check_rolespec_name()

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

Definition at line 5749 of file acl.c.

5750{
5751 if (!role)
5752 return;
5753
5754 if (role->roletype != ROLESPEC_CSTRING)
5755 return;
5756
5757 if (IsReservedName(role->rolename))
5758 {
5759 if (detail_msg)
5760 ereport(ERROR,
5762 errmsg("role name \"%s\" is reserved",
5763 role->rolename),
5765 else
5766 ereport(ERROR,
5768 errmsg("role name \"%s\" is reserved",
5769 role->rolename)));
5770 }
5771}
bool IsReservedName(const char *name)
Definition catalog.c:305
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
@ ROLESPEC_CSTRING
Definition parsenodes.h:424
RoleSpecType roletype
Definition parsenodes.h:434
char * rolename
Definition parsenodes.h:435

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:5642
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:428
#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 5608 of file acl.c.

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

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

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

◆ get_role_oid_or_public()

◆ get_rolespec_name()

char * get_rolespec_name ( const RoleSpec role)
extern

Definition at line 5727 of file acl.c.

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

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

Referenced by AddRoleMems(), and DelRoleMems().

◆ get_rolespec_oid()

Oid get_rolespec_oid ( const RoleSpec role,
bool  missing_ok 
)
extern

Definition at line 5642 of file acl.c.

5643{
5644 Oid oid;
5645
5646 switch (role->roletype)
5647 {
5648 case ROLESPEC_CSTRING:
5649 Assert(role->rolename);
5650 oid = get_role_oid(role->rolename, missing_ok);
5651 break;
5652
5655 oid = GetUserId();
5656 break;
5657
5659 oid = GetSessionUserId();
5660 break;
5661
5662 case ROLESPEC_PUBLIC:
5663 ereport(ERROR,
5665 errmsg("role \"%s\" does not exist", "public")));
5666 oid = InvalidOid; /* make compiler happy */
5667 break;
5668
5669 default:
5670 elog(ERROR, "unexpected role type %d", role->roletype);
5671 }
5672
5673 return oid;
5674}
Oid GetSessionUserId(void)
Definition miscinit.c:509
@ ROLESPEC_CURRENT_USER
Definition parsenodes.h:426
@ ROLESPEC_SESSION_USER
Definition parsenodes.h:427
@ ROLESPEC_CURRENT_ROLE
Definition parsenodes.h:425
#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 5681 of file acl.c.

5682{
5683 HeapTuple tuple;
5684
5685 switch (role->roletype)
5686 {
5687 case ROLESPEC_CSTRING:
5688 Assert(role->rolename);
5690 if (!HeapTupleIsValid(tuple))
5691 ereport(ERROR,
5693 errmsg("role \"%s\" does not exist", role->rolename)));
5694 break;
5695
5699 if (!HeapTupleIsValid(tuple))
5700 elog(ERROR, "cache lookup failed for role %u", GetUserId());
5701 break;
5702
5705 if (!HeapTupleIsValid(tuple))
5706 elog(ERROR, "cache lookup failed for role %u", GetSessionUserId());
5707 break;
5708
5709 case ROLESPEC_PUBLIC:
5710 ereport(ERROR,
5712 errmsg("role \"%s\" does not exist", "public")));
5713 tuple = NULL; /* make compiler happy */
5714 break;
5715
5716 default:
5717 elog(ERROR, "unexpected role type %d", role->roletype);
5718 }
5719
5720 return tuple;
5721}
#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 4313 of file aclchk.c.

4314{
4315 Acl *result;
4316 Acl *glob_acl;
4317 Acl *schema_acl;
4318 Acl *def_acl;
4319 char defaclobjtype;
4320
4321 /*
4322 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4323 * yet.
4324 */
4326 return NULL;
4327
4328 /* Check if object type is supported in pg_default_acl */
4329 switch (objtype)
4330 {
4331 case OBJECT_TABLE:
4332 defaclobjtype = DEFACLOBJ_RELATION;
4333 break;
4334
4335 case OBJECT_SEQUENCE:
4336 defaclobjtype = DEFACLOBJ_SEQUENCE;
4337 break;
4338
4339 case OBJECT_FUNCTION:
4340 defaclobjtype = DEFACLOBJ_FUNCTION;
4341 break;
4342
4343 case OBJECT_TYPE:
4344 defaclobjtype = DEFACLOBJ_TYPE;
4345 break;
4346
4347 case OBJECT_SCHEMA:
4348 defaclobjtype = DEFACLOBJ_NAMESPACE;
4349 break;
4350
4351 case OBJECT_LARGEOBJECT:
4352 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4353 break;
4354
4355 default:
4356 return NULL;
4357 }
4358
4359 /* Look up the relevant pg_default_acl entries */
4360 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4361 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4362
4363 /* Quick out if neither entry exists */
4364 if (glob_acl == NULL && schema_acl == NULL)
4365 return NULL;
4366
4367 /* We need to know the hard-wired default value, too */
4368 def_acl = acldefault(objtype, ownerId);
4369
4370 /* If there's no global entry, substitute the hard-wired default */
4371 if (glob_acl == NULL)
4372 glob_acl = def_acl;
4373
4374 /* Merge in any per-schema privileges */
4375 result = aclmerge(glob_acl, schema_acl, ownerId);
4376
4377 /*
4378 * For efficiency, we want to return NULL if the result equals default.
4379 * This requires sorting both arrays to get an accurate comparison.
4380 */
4383 if (aclequal(result, def_acl))
4384 result = NULL;
4385
4386 return result;
4387}
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:4278
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486

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

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

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)
extern

Definition at line 4254 of file aclchk.c.

4255{
4256 bool result = false;
4258
4259 /* Superusers bypass all permission checking. */
4260 if (superuser_arg(roleid))
4261 return true;
4262
4265 {
4268 }
4269 return result;
4270}
bool rolbypassrls
Definition pg_authid.h:43
bool superuser_arg(Oid roleid)
Definition superuser.c:57

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

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

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)
extern

Definition at line 4235 of file aclchk.c.

4236{
4237 bool result = false;
4239
4240 /* Superusers bypass all permission checking. */
4241 if (superuser_arg(roleid))
4242 return true;
4243
4246 {
4249 }
4250 return result;
4251}
bool rolcreaterole
Definition pg_authid.h:39

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

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

◆ has_privs_of_role()

bool has_privs_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5317 of file acl.c.

5318{
5319 /* Fast path for simple case */
5320 if (member == role)
5321 return true;
5322
5323 /* Superusers have every privilege, so are part of every role */
5324 if (superuser_arg(member))
5325 return true;
5326
5327 /*
5328 * Find all the roles that member has the privileges of, including
5329 * multi-level recursion, then see if target role is any one of them.
5330 */
5332 InvalidOid, NULL),
5333 role);
5334}
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, Oid *admin_role)
Definition acl.c:5185
@ 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(), 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 5072 of file acl.c.

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

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

Referenced by InitPostgres().

◆ is_admin_of_role()

bool is_admin_of_role ( Oid  member,
Oid  role 
)
extern

Definition at line 5447 of file acl.c.

5448{
5450
5451 if (superuser_arg(member))
5452 return true;
5453
5454 /* By policy, a role cannot have WITH ADMIN OPTION on itself. */
5455 if (member == role)
5456 return false;
5457
5459 return OidIsValid(admin_role);
5460}
@ 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 5397 of file acl.c.

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

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

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

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

5352{
5353 /* Fast path for simple case */
5354 if (member == role)
5355 return true;
5356
5357 /* Superusers have every privilege, so can always SET ROLE */
5358 if (superuser_arg(member))
5359 return true;
5360
5361 /*
5362 * Find all the roles that member can access via SET ROLE, including
5363 * multi-level recursion, then see if target role is any one of them.
5364 */
5366 InvalidOid, NULL),
5367 role);
5368}
@ 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 3902 of file aclchk.c.

3903{
3904 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3905}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3912

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(), construct_subserver_conninfo(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), createPartitionTable(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), extension_is_trusted(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), GetSubscription(), HandleFunctionRequest(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_name(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_name(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_name(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_name(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_name(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_name(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), InitTempTableNamespace(), inline_function(), inline_function_in_from(), interpret_function_parameter_list(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), movedb(), pg_get_database_ddl_internal(), PrepareTempTablespaces(), preprocessNamespacePath(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), RenameSchema(), ri_CheckPermissions(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_aclcheck_ext()

◆ object_ownercheck()

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

Definition at line 4156 of file aclchk.c.

4157{
4159 Oid ownerId;
4160
4161 /* Superusers bypass all permission checking. */
4162 if (superuser_arg(roleid))
4163 return true;
4164
4165 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4166 if (classid == LargeObjectRelationId)
4168
4171 {
4172 /* we can get the object's tuple from the syscache */
4173 HeapTuple tuple;
4174
4176 if (!HeapTupleIsValid(tuple))
4177 elog(ERROR, "cache lookup failed for %s %u",
4179
4181 tuple,
4182 get_object_attnum_owner(classid)));
4183 ReleaseSysCache(tuple);
4184 }
4185 else
4186 {
4187 /* for catalogs without an appropriate syscache */
4188 Relation rel;
4189 ScanKeyData entry[1];
4190 SysScanDesc scan;
4191 HeapTuple tuple;
4192 bool isnull;
4193
4194 rel = table_open(classid, AccessShareLock);
4195
4196 ScanKeyInit(&entry[0],
4197 get_object_attnum_oid(classid),
4200
4201 scan = systable_beginscan(rel,
4202 get_object_oid_index(classid), true,
4203 NULL, 1, entry);
4204
4205 tuple = systable_getnext(scan);
4206 if (!HeapTupleIsValid(tuple))
4207 elog(ERROR, "could not find tuple for %s %u",
4209
4210 ownerId = DatumGetObjectId(heap_getattr(tuple,
4211 get_object_attnum_owner(classid),
4212 RelationGetDescr(rel),
4213 &isnull));
4214 Assert(!isnull);
4215
4216 systable_endscan(scan);
4218 }
4219
4220 return has_privs_of_role(roleid, ownerId);
4221}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define AccessShareLock
Definition lockdefs.h:36
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_oid(Oid class_id)
const char * get_object_class_descr(Oid class_id)
Oid get_object_oid_index(Oid class_id)
SysCacheIdentifier get_object_catcache_oid(Oid class_id)
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
#define RelationGetDescr(relation)
Definition rel.h:542
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

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

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

◆ pg_attribute_aclcheck()

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

Definition at line 3934 of file aclchk.c.

3936{
3938}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3946

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

3978{
3980}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3987

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

3990{
3994 Oid ownerId;
3995 AttrNumber nattrs;
3997
3998 /*
3999 * Must fetch pg_class row to get owner ID and number of attributes.
4000 */
4003 {
4004 if (is_missing != NULL)
4005 {
4006 /* return "no privileges" instead of throwing an error */
4007 *is_missing = true;
4008 return ACLCHECK_NO_PRIV;
4009 }
4010 else
4011 ereport(ERROR,
4013 errmsg("relation with OID %u does not exist",
4014 table_oid)));
4015 }
4017
4018 ownerId = classForm->relowner;
4019 nattrs = classForm->relnatts;
4020
4022
4023 /*
4024 * Initialize result in case there are no non-dropped columns. We want to
4025 * report failure in such cases for either value of 'how'.
4026 */
4028
4029 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4030 {
4033 bool isNull;
4034 Acl *acl;
4036
4040
4041 /*
4042 * Lookup failure probably indicates that the table was just dropped,
4043 * but we'll treat it the same as a dropped column rather than
4044 * throwing error.
4045 */
4047 continue;
4048
4049 /* ignore dropped columns */
4050 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4051 {
4053 continue;
4054 }
4055
4057 &isNull);
4058
4059 /*
4060 * Here we hard-wire knowledge that the default ACL for a column
4061 * grants no privileges, so that we can fall out quickly in the very
4062 * common case where attacl is null.
4063 */
4064 if (isNull)
4065 attmask = 0;
4066 else
4067 {
4068 /* detoast column's ACL if necessary */
4069 acl = DatumGetAclP(aclDatum);
4070
4071 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4072
4073 /* if we have a detoasted copy, free it */
4074 if (acl != DatumGetPointer(aclDatum))
4075 pfree(acl);
4076 }
4077
4079
4080 if (attmask != 0)
4081 {
4083 if (how == ACLMASK_ANY)
4084 break; /* succeed on any success */
4085 }
4086 else
4087 {
4089 if (how == ACLMASK_ALL)
4090 break; /* fail on any failure */
4091 }
4092 }
4093
4094 return result;
4095}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1419
#define DatumGetAclP(X)
Definition acl.h:120
FormData_pg_attribute * Form_pg_attribute
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
#define ERRCODE_UNDEFINED_TABLE
Definition pgbench.c:79
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596

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

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

◆ pg_attribute_aclcheck_ext()

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

Definition at line 3946 of file aclchk.c.

3948{
3950 ACLMASK_ANY, is_missing) != 0)
3951 return ACLCHECK_OK;
3952 else
3953 return ACLCHECK_NO_PRIV;
3954}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3184

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, attnum, fb(), mode, and pg_attribute_aclmask_ext().

Referenced by column_privilege_check(), and pg_attribute_aclcheck().

◆ pg_class_aclcheck()

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

◆ pg_class_aclcheck_ext()

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

◆ pg_class_aclmask()

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

Definition at line 3298 of file aclchk.c.

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

References fb(), and pg_class_aclmask_ext().

Referenced by ExecCheckOneRelPerms(), and pg_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

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

Definition at line 4142 of file aclchk.c.

4144{
4146 ACLMASK_ANY, snapshot) != 0)
4147 return ACLCHECK_OK;
4148 else
4149 return ACLCHECK_NO_PRIV;
4150}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition aclchk.c:3575

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

4131{
4132 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4133 return ACLCHECK_OK;
4134 else
4135 return ACLCHECK_NO_PRIV;
4136}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3452

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

4395{
4396 int nmembers;
4397 Oid *members;
4398
4399 /* Nothing to do if ACL is defaulted */
4400 if (acl == NULL)
4401 return;
4402
4403 /* Extract roles mentioned in ACL */
4404 nmembers = aclmembers(acl, &members);
4405
4406 /* Update the shared dependency ACL info */
4407 updateAclDependencies(classId, objectId, objsubId,
4408 ownerId,
4409 0, NULL,
4410 nmembers, members);
4411}
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1571
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 4420 of file aclchk.c.

4421{
4422 /*
4423 * pg_class / pg_attribute
4424 *
4425 * If this is a relation then we need to see if there are any sub-objects
4426 * (eg: columns) for it and, if so, be sure to call
4427 * recordExtensionInitPrivWorker() for each one.
4428 */
4429 if (classoid == RelationRelationId)
4430 {
4433 bool isNull;
4434 HeapTuple tuple;
4435
4436 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4437 if (!HeapTupleIsValid(tuple))
4438 elog(ERROR, "cache lookup failed for relation %u", objoid);
4440
4441 /*
4442 * Indexes don't have permissions, neither do the pg_class rows for
4443 * composite types. (These cases are unreachable given the
4444 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4445 */
4446 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4449 {
4450 ReleaseSysCache(tuple);
4451 return;
4452 }
4453
4454 /*
4455 * If this isn't a sequence then it's possibly going to have
4456 * column-level ACLs associated with it.
4457 */
4458 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4459 {
4461 AttrNumber nattrs = pg_class_tuple->relnatts;
4462
4463 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4464 {
4467
4469 ObjectIdGetDatum(objoid),
4471
4473 continue;
4474
4475 /* ignore dropped columns */
4476 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4477 {
4479 continue;
4480 }
4481
4484 &isNull);
4485
4486 /* no need to do anything for a NULL ACL */
4487 if (isNull)
4488 {
4490 continue;
4491 }
4492
4493 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4495
4497 }
4498 }
4499
4501 &isNull);
4502
4503 /* Add the record, if any, for the top-level object */
4504 if (!isNull)
4505 recordExtensionInitPrivWorker(objoid, classoid, 0,
4507
4508 ReleaseSysCache(tuple);
4509 }
4510 else if (classoid == LargeObjectRelationId)
4511 {
4512 /* For large objects, we must consult pg_largeobject_metadata */
4514 bool isNull;
4515 HeapTuple tuple;
4516 ScanKeyData entry[1];
4517 SysScanDesc scan;
4518 Relation relation;
4519
4520 /*
4521 * Note: this is dead code, given that we don't allow large objects to
4522 * be made extension members. But it seems worth carrying in case
4523 * some future caller of this function has need for it.
4524 */
4526
4527 /* There's no syscache for pg_largeobject_metadata */
4528 ScanKeyInit(&entry[0],
4531 ObjectIdGetDatum(objoid));
4532
4533 scan = systable_beginscan(relation,
4535 NULL, 1, entry);
4536
4537 tuple = systable_getnext(scan);
4538 if (!HeapTupleIsValid(tuple))
4539 elog(ERROR, "could not find tuple for large object %u", objoid);
4540
4541 aclDatum = heap_getattr(tuple,
4543 RelationGetDescr(relation), &isNull);
4544
4545 /* Add the record, if any, for the top-level object */
4546 if (!isNull)
4547 recordExtensionInitPrivWorker(objoid, classoid, 0,
4549
4550 systable_endscan(scan);
4551 }
4552 /* This will error on unsupported classoid. */
4553 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4554 {
4557 bool isNull;
4558 HeapTuple tuple;
4559
4560 cacheid = get_object_catcache_oid(classoid);
4561 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4562 if (!HeapTupleIsValid(tuple))
4563 elog(ERROR, "cache lookup failed for %s %u",
4564 get_object_class_descr(classoid), objoid);
4565
4567 get_object_attnum_acl(classoid),
4568 &isNull);
4569
4570 /* Add the record, if any, for the top-level object */
4571 if (!isNull)
4572 recordExtensionInitPrivWorker(objoid, classoid, 0,
4574
4575 ReleaseSysCache(tuple);
4576 }
4577}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4696
#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 4584 of file aclchk.c.

4585{
4586 /*
4587 * If this is a relation then we need to see if there are any sub-objects
4588 * (eg: columns) for it and, if so, be sure to call
4589 * recordExtensionInitPrivWorker() for each one.
4590 */
4591 if (classoid == RelationRelationId)
4592 {
4594 HeapTuple tuple;
4595
4596 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4597 if (!HeapTupleIsValid(tuple))
4598 elog(ERROR, "cache lookup failed for relation %u", objoid);
4600
4601 /*
4602 * Indexes don't have permissions, neither do the pg_class rows for
4603 * composite types. (These cases are unreachable given the
4604 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4605 */
4606 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4609 {
4610 ReleaseSysCache(tuple);
4611 return;
4612 }
4613
4614 /*
4615 * If this isn't a sequence then it's possibly going to have
4616 * column-level ACLs associated with it.
4617 */
4618 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4619 {
4621 AttrNumber nattrs = pg_class_tuple->relnatts;
4622
4623 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4624 {
4626
4628 ObjectIdGetDatum(objoid),
4630
4632 continue;
4633
4634 /* when removing, remove all entries, even dropped columns */
4635
4636 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4637
4639 }
4640 }
4641
4642 ReleaseSysCache(tuple);
4643 }
4644
4645 /* Remove the record, if any, for the top-level object */
4646 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4647}

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

4934{
4935 Relation rel;
4936 ScanKeyData key[3];
4937 SysScanDesc scan;
4938 HeapTuple oldtuple;
4941 Oid ownerId;
4943 bool isNull;
4944 Acl *old_acl;
4945 Acl *new_acl;
4946 HeapTuple newtuple;
4947 int noldmembers;
4948 int nnewmembers;
4949 Oid *oldmembers;
4950 Oid *newmembers;
4951
4952 /* Search for existing pg_init_privs entry for the target object. */
4954
4955 ScanKeyInit(&key[0],
4958 ObjectIdGetDatum(objid));
4959 ScanKeyInit(&key[1],
4962 ObjectIdGetDatum(classid));
4963 ScanKeyInit(&key[2],
4966 Int32GetDatum(objsubid));
4967
4968 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4969 NULL, 3, key);
4970
4971 /* There should exist only one entry or none. */
4972 oldtuple = systable_getnext(scan);
4973
4974 if (!HeapTupleIsValid(oldtuple))
4975 {
4976 /*
4977 * Hmm, why are we here if there's no entry? But pack up and go away
4978 * quietly.
4979 */
4980 systable_endscan(scan);
4982 return;
4983 }
4984
4985 /* Get a writable copy of the existing ACL. */
4987 RelationGetDescr(rel), &isNull);
4988 Assert(!isNull);
4990
4991 /*
4992 * We need the members of both old and new ACLs so we can correct the
4993 * shared dependency information. Collect data before
4994 * merge_acl_with_grant throws away old_acl.
4995 */
4997
4998 /* Must find out the owner's OID the hard way. */
5002 elog(ERROR, "cache lookup failed for %s %u",
5003 get_object_class_descr(classid), objid);
5004
5006 objtuple,
5007 get_object_attnum_owner(classid)));
5009
5010 /*
5011 * Generate new ACL. Grantor of rights is always the same as the owner.
5012 */
5013 if (old_acl != NULL)
5015 false, /* is_grant */
5016 false, /* grant_option */
5018 list_make1_oid(roleid),
5020 ownerId,
5021 ownerId);
5022 else
5023 new_acl = NULL; /* this case shouldn't happen, probably */
5024
5025 /* If we end with an empty ACL, delete the pg_init_privs entry. */
5026 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
5027 {
5028 CatalogTupleDelete(rel, &oldtuple->t_self);
5029 }
5030 else
5031 {
5033 bool nulls[Natts_pg_init_privs] = {0};
5034 bool replaces[Natts_pg_init_privs] = {0};
5035
5036 /* Update existing entry. */
5039
5040 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
5041 values, nulls, replaces);
5042 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
5043 }
5044
5045 /*
5046 * Update the shared dependency ACL info.
5047 */
5049
5050 updateInitAclDependencies(classid, objid, objsubid,
5053
5054 systable_endscan(scan);
5055
5056 /* prevent error when processing objects multiple times */
5058
5060}
#define ACLITEM_ALL_PRIV_BITS
Definition acl.h:87
#define DatumGetAclPCopy(X)
Definition acl.h:121
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition aclchk.c:182
static Datum values[MAXATTR]
Definition bootstrap.c:190
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1118
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define list_make1_oid(x1)
Definition pg_list.h:274
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define PointerGetDatum(X)
Definition postgres.h:354
ItemPointerData t_self
Definition htup.h:65
void CommandCounterIncrement(void)
Definition xact.c:1130

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

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

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

Definition at line 1426 of file aclchk.c.

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

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

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

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

Definition at line 4824 of file aclchk.c.

4826{
4827 Relation rel;
4828 ScanKeyData key[3];
4829 SysScanDesc scan;
4830 HeapTuple oldtuple;
4832 bool isNull;
4833 Acl *old_acl;
4834 Acl *new_acl;
4835 HeapTuple newtuple;
4836 int noldmembers;
4837 int nnewmembers;
4838 Oid *oldmembers;
4839 Oid *newmembers;
4840
4841 /* Search for existing pg_init_privs entry for the target object. */
4843
4844 ScanKeyInit(&key[0],
4847 ObjectIdGetDatum(objid));
4848 ScanKeyInit(&key[1],
4851 ObjectIdGetDatum(classid));
4852 ScanKeyInit(&key[2],
4855 Int32GetDatum(objsubid));
4856
4857 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4858 NULL, 3, key);
4859
4860 /* There should exist only one entry or none. */
4861 oldtuple = systable_getnext(scan);
4862
4863 if (!HeapTupleIsValid(oldtuple))
4864 {
4865 /*
4866 * Hmm, why are we here if there's no entry? But pack up and go away
4867 * quietly.
4868 */
4869 systable_endscan(scan);
4871 return;
4872 }
4873
4874 /* Get a writable copy of the existing ACL. */
4876 RelationGetDescr(rel), &isNull);
4877 Assert(!isNull);
4879
4880 /*
4881 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4882 * oldroleid isn't the owner; but it does the job fine.
4883 */
4885
4886 /*
4887 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4888 * probably can't happen here, but we may as well cover the case.)
4889 */
4890 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4891 {
4892 CatalogTupleDelete(rel, &oldtuple->t_self);
4893 }
4894 else
4895 {
4897 bool nulls[Natts_pg_init_privs] = {0};
4898 bool replaces[Natts_pg_init_privs] = {0};
4899
4900 /* Update existing entry. */
4903
4904 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4905 values, nulls, replaces);
4906 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4907 }
4908
4909 /*
4910 * Update the shared dependency ACL info.
4911 */
4914
4915 updateInitAclDependencies(classid, objid, objsubid,
4918
4919 systable_endscan(scan);
4920
4921 /* prevent error when processing objects multiple times */
4923
4925}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1150

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

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

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

5514{
5515 Oid roleId = GetUserId();
5518 int nrights;
5519 ListCell *l;
5520
5521 /*
5522 * If we have GRANTED BY, resolve it and verify current user is allowed to
5523 * specify that role.
5524 */
5525 if (grantedBy)
5526 {
5527 Oid grantor = get_rolespec_oid(grantedBy, false);
5528
5529 if (!has_privs_of_role(roleId, grantor))
5530 ereport(ERROR,
5532 errmsg("must inherit privileges of role \"%s\"",
5533 GetUserNameFromId(grantor, false))));
5534 /* Use exactly that grantor, whether it has privileges or not */
5535 *grantorId = grantor;
5536 *grantOptions = aclmask_direct(acl, grantor, ownerId,
5538 return;
5539 }
5540
5541 /*
5542 * The object owner is always treated as having all grant options, so if
5543 * roleId is the owner it's easy. Also, if roleId is a superuser it's
5544 * easy: superusers are implicitly members of every role, so they act as
5545 * the object owner.
5546 */
5547 if (roleId == ownerId || superuser_arg(roleId))
5548 {
5549 *grantorId = ownerId;
5551 return;
5552 }
5553
5554 /*
5555 * Otherwise we have to do a careful search to see if roleId has the
5556 * privileges of any suitable role. Note: we can hang onto the result of
5557 * roles_is_member_of() throughout this loop, because aclmask_direct()
5558 * doesn't query any role memberships.
5559 */
5561 InvalidOid, NULL);
5562
5563 /* initialize candidate result as default */
5564 *grantorId = roleId;
5566 nrights = 0;
5567
5568 foreach(l, roles_list)
5569 {
5572
5573 otherprivs = aclmask_direct(acl, otherrole, ownerId,
5576 {
5577 /* Found a suitable grantor */
5580 return;
5581 }
5582
5583 /*
5584 * If it has just some of the needed privileges, remember best
5585 * candidate.
5586 */
5588 {
5590
5591 if (nnewrights > nrights)
5592 {
5596 }
5597 }
5598 }
5599}
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1508
#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().