]> granicus.if.org Git - postgresql/blob - src/include/utils/acl.h
Speed up information schema privilege views
[postgresql] / src / include / utils / acl.h
1 /*-------------------------------------------------------------------------
2  *
3  * acl.h
4  *        Definition of (and support for) access control list data structures.
5  *
6  *
7  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.110 2009/12/05 21:43:36 petere Exp $
11  *
12  * NOTES
13  *        An ACL array is simply an array of AclItems, representing the union
14  *        of the privileges represented by the individual items.  A zero-length
15  *        array represents "no privileges".  There are no assumptions about the
16  *        ordering of the items, but we do expect that there are no two entries
17  *        in the array with the same grantor and grantee.
18  *
19  *        For backward-compatibility purposes we have to allow null ACL entries
20  *        in system catalogs.  A null ACL will be treated as meaning "default
21  *        protection" (i.e., whatever acldefault() returns).
22  *-------------------------------------------------------------------------
23  */
24 #ifndef ACL_H
25 #define ACL_H
26
27 #include "nodes/parsenodes.h"
28 #include "utils/array.h"
29
30
31 /*
32  * typedef AclMode is declared in parsenodes.h, also the individual privilege
33  * bit meanings are defined there
34  */
35
36 #define ACL_ID_PUBLIC   0               /* placeholder for id in a PUBLIC acl item */
37
38 /*
39  * AclItem
40  *
41  * Note: must be same size on all platforms, because the size is hardcoded
42  * in the pg_type.h entry for aclitem.
43  */
44 typedef struct AclItem
45 {
46         Oid                     ai_grantee;             /* ID that this item grants privs to */
47         Oid                     ai_grantor;             /* grantor of privs */
48         AclMode         ai_privs;               /* privilege bits */
49 } AclItem;
50
51 /*
52  * The upper 16 bits of the ai_privs field of an AclItem are the grant option
53  * bits, and the lower 16 bits are the actual privileges.  We use "rights"
54  * to mean the combined grant option and privilege bits fields.
55  */
56 #define ACLITEM_GET_PRIVS(item)    ((item).ai_privs & 0xFFFF)
57 #define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF)
58 #define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
59
60 #define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16)
61 #define ACL_OPTION_TO_PRIVS(privs)      (((AclMode) (privs) >> 16) & 0xFFFF)
62
63 #define ACLITEM_SET_PRIVS(item,privs) \
64   ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \
65                                          ((AclMode) (privs) & 0xFFFF))
66 #define ACLITEM_SET_GOPTIONS(item,goptions) \
67   ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16)) | \
68                                          (((AclMode) (goptions) & 0xFFFF) << 16))
69 #define ACLITEM_SET_RIGHTS(item,rights) \
70   ((item).ai_privs = (AclMode) (rights))
71
72 #define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \
73   ((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \
74                                          (((AclMode) (goptions) & 0xFFFF) << 16))
75
76
77 #define ACLITEM_ALL_PRIV_BITS           ((AclMode) 0xFFFF)
78 #define ACLITEM_ALL_GOPTION_BITS        ((AclMode) 0xFFFF << 16)
79
80 /*
81  * Definitions for convenient access to Acl (array of AclItem).
82  * These are standard PostgreSQL arrays, but are restricted to have one
83  * dimension and no nulls.      We also ignore the lower bound when reading,
84  * and set it to one when writing.
85  *
86  * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
87  * other array types).  Therefore, be careful to detoast them with the
88  * macros provided, unless you know for certain that a particular array
89  * can't have been toasted.
90  */
91
92
93 /*
94  * Acl                  a one-dimensional array of AclItem
95  */
96 typedef ArrayType Acl;
97
98 #define ACL_NUM(ACL)                    (ARR_DIMS(ACL)[0])
99 #define ACL_DAT(ACL)                    ((AclItem *) ARR_DATA_PTR(ACL))
100 #define ACL_N_SIZE(N)                   (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
101 #define ACL_SIZE(ACL)                   ARR_SIZE(ACL)
102
103 /*
104  * fmgr macros for these types
105  */
106 #define DatumGetAclItemP(X)                ((AclItem *) DatumGetPointer(X))
107 #define PG_GETARG_ACLITEM_P(n)     DatumGetAclItemP(PG_GETARG_DATUM(n))
108 #define PG_RETURN_ACLITEM_P(x)     PG_RETURN_POINTER(x)
109
110 #define DatumGetAclP(X)                    ((Acl *) PG_DETOAST_DATUM(X))
111 #define DatumGetAclPCopy(X)                ((Acl *) PG_DETOAST_DATUM_COPY(X))
112 #define PG_GETARG_ACL_P(n)                 DatumGetAclP(PG_GETARG_DATUM(n))
113 #define PG_GETARG_ACL_P_COPY(n)    DatumGetAclPCopy(PG_GETARG_DATUM(n))
114 #define PG_RETURN_ACL_P(x)                 PG_RETURN_POINTER(x)
115
116 /*
117  * ACL modification opcodes for aclupdate
118  */
119 #define ACL_MODECHG_ADD                 1
120 #define ACL_MODECHG_DEL                 2
121 #define ACL_MODECHG_EQL                 3
122
123 /*
124  * External representations of the privilege bits --- aclitemin/aclitemout
125  * represent each possible privilege bit with a distinct 1-character code
126  */
127 #define ACL_INSERT_CHR                  'a'             /* formerly known as "append" */
128 #define ACL_SELECT_CHR                  'r'             /* formerly known as "read" */
129 #define ACL_UPDATE_CHR                  'w'             /* formerly known as "write" */
130 #define ACL_DELETE_CHR                  'd'
131 #define ACL_TRUNCATE_CHR                'D'             /* super-delete, as it were */
132 #define ACL_REFERENCES_CHR              'x'
133 #define ACL_TRIGGER_CHR                 't'
134 #define ACL_EXECUTE_CHR                 'X'
135 #define ACL_USAGE_CHR                   'U'
136 #define ACL_CREATE_CHR                  'C'
137 #define ACL_CREATE_TEMP_CHR             'T'
138 #define ACL_CONNECT_CHR                 'c'
139
140 /* string holding all privilege code chars, in order by bitmask position */
141 #define ACL_ALL_RIGHTS_STR      "arwdDxtXUCTc"
142
143 /*
144  * Bitmasks defining "all rights" for each supported object type
145  */
146 #define ACL_ALL_RIGHTS_COLUMN           (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
147 #define ACL_ALL_RIGHTS_RELATION         (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER)
148 #define ACL_ALL_RIGHTS_SEQUENCE         (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
149 #define ACL_ALL_RIGHTS_DATABASE         (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
150 #define ACL_ALL_RIGHTS_FDW                      (ACL_USAGE)
151 #define ACL_ALL_RIGHTS_FOREIGN_SERVER (ACL_USAGE)
152 #define ACL_ALL_RIGHTS_FUNCTION         (ACL_EXECUTE)
153 #define ACL_ALL_RIGHTS_LANGUAGE         (ACL_USAGE)
154 #define ACL_ALL_RIGHTS_NAMESPACE        (ACL_USAGE|ACL_CREATE)
155 #define ACL_ALL_RIGHTS_TABLESPACE       (ACL_CREATE)
156
157 /* operation codes for pg_*_aclmask */
158 typedef enum
159 {
160         ACLMASK_ALL,                            /* normal case: compute all bits */
161         ACLMASK_ANY                                     /* return when result is known nonzero */
162 } AclMaskHow;
163
164 /* result codes for pg_*_aclcheck */
165 typedef enum
166 {
167         ACLCHECK_OK = 0,
168         ACLCHECK_NO_PRIV,
169         ACLCHECK_NOT_OWNER
170 } AclResult;
171
172 /* this enum covers all object types that can have privilege errors */
173 /* currently it's only used to tell aclcheck_error what to say */
174 typedef enum AclObjectKind
175 {
176         ACL_KIND_COLUMN,                        /* pg_attribute */
177         ACL_KIND_CLASS,                         /* pg_class */
178         ACL_KIND_SEQUENCE,                      /* pg_sequence */
179         ACL_KIND_DATABASE,                      /* pg_database */
180         ACL_KIND_PROC,                          /* pg_proc */
181         ACL_KIND_OPER,                          /* pg_operator */
182         ACL_KIND_TYPE,                          /* pg_type */
183         ACL_KIND_LANGUAGE,                      /* pg_language */
184         ACL_KIND_NAMESPACE,                     /* pg_namespace */
185         ACL_KIND_OPCLASS,                       /* pg_opclass */
186         ACL_KIND_OPFAMILY,                      /* pg_opfamily */
187         ACL_KIND_CONVERSION,            /* pg_conversion */
188         ACL_KIND_TABLESPACE,            /* pg_tablespace */
189         ACL_KIND_TSDICTIONARY,          /* pg_ts_dict */
190         ACL_KIND_TSCONFIGURATION,       /* pg_ts_config */
191         ACL_KIND_FDW,                           /* pg_foreign_data_wrapper */
192         ACL_KIND_FOREIGN_SERVER,        /* pg_foreign_server */
193         MAX_ACL_KIND                            /* MUST BE LAST */
194 } AclObjectKind;
195
196
197 /*
198  * routines used internally
199  */
200 extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
201 extern Acl *get_user_default_acl(GrantObjectType objtype, Oid ownerId,
202                                                                  Oid nsp_oid);
203
204 extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
205                   int modechg, Oid ownerId, DropBehavior behavior);
206 extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
207 extern Acl *make_empty_acl(void);
208 extern Acl *aclcopy(const Acl *orig_acl);
209 extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl);
210 extern Acl *aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId);
211 extern void aclitemsort(Acl *acl);
212 extern bool aclequal(const Acl *left_acl, const Acl *right_acl);
213
214 extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
215                 AclMode mask, AclMaskHow how);
216 extern int      aclmembers(const Acl *acl, Oid **roleids);
217
218 extern bool has_privs_of_role(Oid member, Oid role);
219 extern bool is_member_of_role(Oid member, Oid role);
220 extern bool is_member_of_role_nosuper(Oid member, Oid role);
221 extern bool is_admin_of_role(Oid member, Oid role);
222 extern void check_is_member_of_role(Oid member, Oid role);
223
224 extern void select_best_grantor(Oid roleId, AclMode privileges,
225                                         const Acl *acl, Oid ownerId,
226                                         Oid *grantorId, AclMode *grantOptions);
227
228 extern void initialize_acl(void);
229
230 /*
231  * SQL functions (from acl.c)
232  */
233 extern Datum aclitemin(PG_FUNCTION_ARGS);
234 extern Datum aclitemout(PG_FUNCTION_ARGS);
235 extern Datum aclinsert(PG_FUNCTION_ARGS);
236 extern Datum aclremove(PG_FUNCTION_ARGS);
237 extern Datum aclcontains(PG_FUNCTION_ARGS);
238 extern Datum makeaclitem(PG_FUNCTION_ARGS);
239 extern Datum aclitem_eq(PG_FUNCTION_ARGS);
240 extern Datum hash_aclitem(PG_FUNCTION_ARGS);
241 extern Datum aclexplode(PG_FUNCTION_ARGS);
242
243 /*
244  * prototypes for functions in aclchk.c
245  */
246 extern void ExecuteGrantStmt(GrantStmt *stmt);
247 extern void ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt);
248
249 extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
250 extern void RemoveDefaultACLById(Oid defaclOid);
251
252 extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
253                                          Oid roleid, AclMode mask, AclMaskHow how);
254 extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
255                                  AclMode mask, AclMaskHow how);
256 extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
257                                         AclMode mask, AclMaskHow how);
258 extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
259                                 AclMode mask, AclMaskHow how);
260 extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
261                                         AclMode mask, AclMaskHow how);
262 extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
263                                          AclMode mask, AclMaskHow how);
264 extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
265                                           AclMode mask, AclMaskHow how);
266 extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
267                                                                 AclMode mask, AclMaskHow how);
268 extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
269                                                   AclMode mask, AclMaskHow how);
270
271 extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
272                                           Oid roleid, AclMode mode);
273 extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
274                                                   AclMode mode, AclMaskHow how);
275 extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
276 extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
277 extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
278 extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
279 extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
280 extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
281 extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode);
282 extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode);
283
284 extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
285                            const char *objectname);
286
287 extern void aclcheck_error_col(AclResult aclerr, AclObjectKind objectkind,
288                                    const char *objectname, const char *colname);
289
290 /* ownercheck routines just return true (owner) or false (not) */
291 extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
292 extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
293 extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
294 extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
295 extern bool pg_language_ownercheck(Oid lan_oid, Oid roleid);
296 extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
297 extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
298 extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
299 extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid);
300 extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
301 extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
302 extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid);
303 extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid);
304 extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid);
305
306 #endif   /* ACL_H */