]> granicus.if.org Git - postgresql/blob - src/include/utils/acl.h
0b560e062c13836b98847e747740f2329124d42a
[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-2005, 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.80 2005/06/29 20:34:15 tgl 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) and IdList
82  * (array of Oid).  These are standard PostgreSQL arrays, but are restricted
83  * to have one dimension.  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(1) + ((N) * sizeof(AclItem)))
101 #define ACL_SIZE(ACL)                   ARR_SIZE(ACL)
102
103 /*
104  * IdList               a one-dimensional array of Oid
105  */
106 typedef ArrayType IdList;
107
108 #define IDLIST_NUM(IDL)                 (ARR_DIMS(IDL)[0])
109 #define IDLIST_DAT(IDL)                 ((Oid *) ARR_DATA_PTR(IDL))
110 #define IDLIST_N_SIZE(N)                (ARR_OVERHEAD(1) + ((N) * sizeof(Oid)))
111 #define IDLIST_SIZE(IDL)                ARR_SIZE(IDL)
112
113 /*
114  * fmgr macros for these types
115  */
116 #define DatumGetAclItemP(X)                ((AclItem *) DatumGetPointer(X))
117 #define PG_GETARG_ACLITEM_P(n)     DatumGetAclItemP(PG_GETARG_DATUM(n))
118 #define PG_RETURN_ACLITEM_P(x)     PG_RETURN_POINTER(x)
119
120 #define DatumGetAclP(X)                    ((Acl *) PG_DETOAST_DATUM(X))
121 #define DatumGetAclPCopy(X)                ((Acl *) PG_DETOAST_DATUM_COPY(X))
122 #define PG_GETARG_ACL_P(n)                 DatumGetAclP(PG_GETARG_DATUM(n))
123 #define PG_GETARG_ACL_P_COPY(n)    DatumGetAclPCopy(PG_GETARG_DATUM(n))
124 #define PG_RETURN_ACL_P(x)                 PG_RETURN_POINTER(x)
125
126 #define DatumGetIdListP(X)                 ((IdList *) PG_DETOAST_DATUM(X))
127 #define DatumGetIdListPCopy(X)     ((IdList *) PG_DETOAST_DATUM_COPY(X))
128 #define PG_GETARG_IDLIST_P(n)      DatumGetIdListP(PG_GETARG_DATUM(n))
129 #define PG_GETARG_IDLIST_P_COPY(n) DatumGetIdListPCopy(PG_GETARG_DATUM(n))
130 #define PG_RETURN_IDLIST_P(x)      PG_RETURN_POINTER(x)
131
132
133 /*
134  * ACL modification opcodes for aclupdate
135  */
136 #define ACL_MODECHG_ADD                 1
137 #define ACL_MODECHG_DEL                 2
138 #define ACL_MODECHG_EQL                 3
139
140 /*
141  * External representations of the privilege bits --- aclitemin/aclitemout
142  * represent each possible privilege bit with a distinct 1-character code
143  */
144 #define ACL_INSERT_CHR                  'a'             /* formerly known as "append" */
145 #define ACL_SELECT_CHR                  'r'             /* formerly known as "read" */
146 #define ACL_UPDATE_CHR                  'w'             /* formerly known as "write" */
147 #define ACL_DELETE_CHR                  'd'
148 #define ACL_RULE_CHR                    'R'
149 #define ACL_REFERENCES_CHR              'x'
150 #define ACL_TRIGGER_CHR                 't'
151 #define ACL_EXECUTE_CHR                 'X'
152 #define ACL_USAGE_CHR                   'U'
153 #define ACL_CREATE_CHR                  'C'
154 #define ACL_CREATE_TEMP_CHR             'T'
155
156 /* string holding all privilege code chars, in order by bitmask position */
157 #define ACL_ALL_RIGHTS_STR      "arwdRxtXUCT"
158
159 /*
160  * Bitmasks defining "all rights" for each supported object type
161  */
162 #define ACL_ALL_RIGHTS_RELATION         (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
163 #define ACL_ALL_RIGHTS_DATABASE         (ACL_CREATE|ACL_CREATE_TEMP)
164 #define ACL_ALL_RIGHTS_FUNCTION         (ACL_EXECUTE)
165 #define ACL_ALL_RIGHTS_LANGUAGE         (ACL_USAGE)
166 #define ACL_ALL_RIGHTS_NAMESPACE        (ACL_USAGE|ACL_CREATE)
167 #define ACL_ALL_RIGHTS_TABLESPACE       (ACL_CREATE)
168
169 /* operation codes for pg_*_aclmask */
170 typedef enum
171 {
172         ACLMASK_ALL,                            /* normal case: compute all bits */
173         ACLMASK_ANY                                     /* return when result is known nonzero */
174 } AclMaskHow;
175
176 /* result codes for pg_*_aclcheck */
177 typedef enum
178 {
179         ACLCHECK_OK = 0,
180         ACLCHECK_NO_PRIV,
181         ACLCHECK_NOT_OWNER
182 } AclResult;
183
184 /* this enum covers all object types that can have privilege errors */
185 /* currently it's only used to tell aclcheck_error what to say */
186 typedef enum AclObjectKind
187 {
188         ACL_KIND_CLASS,                         /* pg_class */
189         ACL_KIND_DATABASE,                      /* pg_database */
190         ACL_KIND_PROC,                          /* pg_proc */
191         ACL_KIND_OPER,                          /* pg_operator */
192         ACL_KIND_TYPE,                          /* pg_type */
193         ACL_KIND_LANGUAGE,                      /* pg_language */
194         ACL_KIND_NAMESPACE,                     /* pg_namespace */
195         ACL_KIND_OPCLASS,                       /* pg_opclass */
196         ACL_KIND_CONVERSION,            /* pg_conversion */
197         ACL_KIND_TABLESPACE,            /* pg_tablespace */
198         MAX_ACL_KIND                            /* MUST BE LAST */
199 } AclObjectKind;
200
201 /*
202  * routines used internally
203  */
204 extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
205 extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
206                   int modechg, Oid ownerId, DropBehavior behavior);
207 extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
208
209 extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
210                 AclMode mask, AclMaskHow how);
211
212 extern bool is_member_of_role(Oid member, Oid role);
213 extern bool is_admin_of_role(Oid member, Oid role);
214
215 extern void initialize_acl(void);
216
217 /*
218  * SQL functions (from acl.c)
219  */
220 extern Datum aclitemin(PG_FUNCTION_ARGS);
221 extern Datum aclitemout(PG_FUNCTION_ARGS);
222 extern Datum aclinsert(PG_FUNCTION_ARGS);
223 extern Datum aclremove(PG_FUNCTION_ARGS);
224 extern Datum aclcontains(PG_FUNCTION_ARGS);
225 extern Datum makeaclitem(PG_FUNCTION_ARGS);
226 extern Datum aclitem_eq(PG_FUNCTION_ARGS);
227 extern Datum hash_aclitem(PG_FUNCTION_ARGS);
228
229 /*
230  * prototypes for functions in aclchk.c
231  */
232 extern void ExecuteGrantStmt(GrantStmt *stmt);
233
234 extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
235                                  AclMode mask, AclMaskHow how);
236 extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
237                                         AclMode mask, AclMaskHow how);
238 extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
239                                 AclMode mask, AclMaskHow how);
240 extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
241                                         AclMode mask, AclMaskHow how);
242 extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
243                                          AclMode mask, AclMaskHow how);
244 extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
245                                           AclMode mask, AclMaskHow how);
246
247 extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
248 extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
249 extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
250 extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
251 extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
252 extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
253
254 extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
255                            const char *objectname);
256
257 /* ownercheck routines just return true (owner) or false (not) */
258 extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
259 extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
260 extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
261 extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
262 extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
263 extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
264 extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
265 extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
266 extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
267
268 #endif   /* ACL_H */