~ubuntu-branches/ubuntu/hardy/postgresql-8.4/hardy-backports

« back to all changes in this revision

Viewing changes to src/include/utils/acl.h

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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$
 
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
 * The information about one Grant/Revoke statement, in internal format: object
 
198
 * and grantees names have been turned into Oids, the privilege list is an
 
199
 * AclMode bitmask.  If 'privileges' is ACL_NO_RIGHTS (the 0 value) and
 
200
 * all_privs is true, 'privileges' will be internally set to the right kind of
 
201
 * ACL_ALL_RIGHTS_*, depending on the object type (NB - this will modify the
 
202
 * InternalGrant struct!)
 
203
 *
 
204
 * Note: 'all_privs' and 'privileges' represent object-level privileges only.
 
205
 * There might also be column-level privilege specifications, which are
 
206
 * represented in col_privs (this is a list of untransformed AccessPriv nodes).
 
207
 * Column privileges are only valid for objtype ACL_OBJECT_RELATION.
 
208
 */
 
209
typedef struct
 
210
{
 
211
        bool            is_grant;
 
212
        GrantObjectType objtype;
 
213
        List       *objects;
 
214
        bool            all_privs;
 
215
        AclMode         privileges;
 
216
        List       *col_privs;
 
217
        List       *grantees;
 
218
        bool            grant_option;
 
219
        DropBehavior behavior;
 
220
} InternalGrant;
 
221
 
 
222
/*
 
223
 * routines used internally
 
224
 */
 
225
extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
 
226
extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
 
227
                  int modechg, Oid ownerId, DropBehavior behavior);
 
228
extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
 
229
extern Acl *aclcopy(const Acl *orig_acl);
 
230
extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl);
 
231
 
 
232
extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
 
233
                AclMode mask, AclMaskHow how);
 
234
extern int      aclmembers(const Acl *acl, Oid **roleids);
 
235
 
 
236
extern bool has_privs_of_role(Oid member, Oid role);
 
237
extern bool is_member_of_role(Oid member, Oid role);
 
238
extern bool is_member_of_role_nosuper(Oid member, Oid role);
 
239
extern bool is_admin_of_role(Oid member, Oid role);
 
240
extern void check_is_member_of_role(Oid member, Oid role);
 
241
 
 
242
extern void select_best_grantor(Oid roleId, AclMode privileges,
 
243
                                        const Acl *acl, Oid ownerId,
 
244
                                        Oid *grantorId, AclMode *grantOptions);
 
245
 
 
246
extern void initialize_acl(void);
 
247
 
 
248
/*
 
249
 * SQL functions (from acl.c)
 
250
 */
 
251
extern Datum aclitemin(PG_FUNCTION_ARGS);
 
252
extern Datum aclitemout(PG_FUNCTION_ARGS);
 
253
extern Datum aclinsert(PG_FUNCTION_ARGS);
 
254
extern Datum aclremove(PG_FUNCTION_ARGS);
 
255
extern Datum aclcontains(PG_FUNCTION_ARGS);
 
256
extern Datum makeaclitem(PG_FUNCTION_ARGS);
 
257
extern Datum aclitem_eq(PG_FUNCTION_ARGS);
 
258
extern Datum hash_aclitem(PG_FUNCTION_ARGS);
 
259
 
 
260
/*
 
261
 * prototypes for functions in aclchk.c
 
262
 */
 
263
extern void ExecuteGrantStmt(GrantStmt *stmt);
 
264
extern void ExecGrantStmt_oids(InternalGrant *istmt);
 
265
 
 
266
extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
 
267
                                Oid roleid, AclMode mask, AclMaskHow how);
 
268
extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
 
269
                                 AclMode mask, AclMaskHow how);
 
270
extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
 
271
                                        AclMode mask, AclMaskHow how);
 
272
extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
 
273
                                AclMode mask, AclMaskHow how);
 
274
extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
 
275
                                        AclMode mask, AclMaskHow how);
 
276
extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
 
277
                                         AclMode mask, AclMaskHow how);
 
278
extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
 
279
                                          AclMode mask, AclMaskHow how);
 
280
extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
 
281
                                          AclMode mask, AclMaskHow how);
 
282
extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
 
283
                                          AclMode mask, AclMaskHow how);
 
284
 
 
285
extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
 
286
                                                                           Oid roleid, AclMode mode);
 
287
extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
 
288
                                                                                   AclMode mode, AclMaskHow how);
 
289
extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
 
290
extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
 
291
extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
 
292
extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
 
293
extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
 
294
extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
 
295
extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode);
 
296
extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode);
 
297
 
 
298
extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
 
299
                           const char *objectname);
 
300
 
 
301
extern void aclcheck_error_col(AclResult aclerr, AclObjectKind objectkind,
 
302
                           const char *objectname, const char *colname);
 
303
 
 
304
/* ownercheck routines just return true (owner) or false (not) */
 
305
extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
 
306
extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
 
307
extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
 
308
extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
 
309
extern bool pg_language_ownercheck(Oid lan_oid, Oid roleid);
 
310
extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
 
311
extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
 
312
extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
 
313
extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid);
 
314
extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
 
315
extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
 
316
extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid);
 
317
extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid);
 
318
extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid);
 
319
 
 
320
#endif   /* ACL_H */