Header And Logo

PostgreSQL
| The world's most advanced open source database.

acl.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * acl.h
00004  *    Definition of (and support for) access control list data structures.
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/include/utils/acl.h
00011  *
00012  * NOTES
00013  *    An ACL array is simply an array of AclItems, representing the union
00014  *    of the privileges represented by the individual items.  A zero-length
00015  *    array represents "no privileges".  There are no assumptions about the
00016  *    ordering of the items, but we do expect that there are no two entries
00017  *    in the array with the same grantor and grantee.
00018  *
00019  *    For backward-compatibility purposes we have to allow null ACL entries
00020  *    in system catalogs.  A null ACL will be treated as meaning "default
00021  *    protection" (i.e., whatever acldefault() returns).
00022  *-------------------------------------------------------------------------
00023  */
00024 #ifndef ACL_H
00025 #define ACL_H
00026 
00027 #include "nodes/parsenodes.h"
00028 #include "utils/array.h"
00029 #include "utils/snapshot.h"
00030 
00031 
00032 /*
00033  * typedef AclMode is declared in parsenodes.h, also the individual privilege
00034  * bit meanings are defined there
00035  */
00036 
00037 #define ACL_ID_PUBLIC   0       /* placeholder for id in a PUBLIC acl item */
00038 
00039 /*
00040  * AclItem
00041  *
00042  * Note: must be same size on all platforms, because the size is hardcoded
00043  * in the pg_type.h entry for aclitem.
00044  */
00045 typedef struct AclItem
00046 {
00047     Oid         ai_grantee;     /* ID that this item grants privs to */
00048     Oid         ai_grantor;     /* grantor of privs */
00049     AclMode     ai_privs;       /* privilege bits */
00050 } AclItem;
00051 
00052 /*
00053  * The upper 16 bits of the ai_privs field of an AclItem are the grant option
00054  * bits, and the lower 16 bits are the actual privileges.  We use "rights"
00055  * to mean the combined grant option and privilege bits fields.
00056  */
00057 #define ACLITEM_GET_PRIVS(item)    ((item).ai_privs & 0xFFFF)
00058 #define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF)
00059 #define ACLITEM_GET_RIGHTS(item)   ((item).ai_privs)
00060 
00061 #define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16)
00062 #define ACL_OPTION_TO_PRIVS(privs)  (((AclMode) (privs) >> 16) & 0xFFFF)
00063 
00064 #define ACLITEM_SET_PRIVS(item,privs) \
00065   ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \
00066                      ((AclMode) (privs) & 0xFFFF))
00067 #define ACLITEM_SET_GOPTIONS(item,goptions) \
00068   ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16)) | \
00069                      (((AclMode) (goptions) & 0xFFFF) << 16))
00070 #define ACLITEM_SET_RIGHTS(item,rights) \
00071   ((item).ai_privs = (AclMode) (rights))
00072 
00073 #define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \
00074   ((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \
00075                      (((AclMode) (goptions) & 0xFFFF) << 16))
00076 
00077 
00078 #define ACLITEM_ALL_PRIV_BITS       ((AclMode) 0xFFFF)
00079 #define ACLITEM_ALL_GOPTION_BITS    ((AclMode) 0xFFFF << 16)
00080 
00081 /*
00082  * Definitions for convenient access to Acl (array of AclItem).
00083  * These are standard PostgreSQL arrays, but are restricted to have one
00084  * dimension and no nulls.  We also ignore the lower bound when reading,
00085  * and set it to one when writing.
00086  *
00087  * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
00088  * other array types).  Therefore, be careful to detoast them with the
00089  * macros provided, unless you know for certain that a particular array
00090  * can't have been toasted.
00091  */
00092 
00093 
00094 /*
00095  * Acl          a one-dimensional array of AclItem
00096  */
00097 typedef ArrayType Acl;
00098 
00099 #define ACL_NUM(ACL)            (ARR_DIMS(ACL)[0])
00100 #define ACL_DAT(ACL)            ((AclItem *) ARR_DATA_PTR(ACL))
00101 #define ACL_N_SIZE(N)           (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
00102 #define ACL_SIZE(ACL)           ARR_SIZE(ACL)
00103 
00104 /*
00105  * fmgr macros for these types
00106  */
00107 #define DatumGetAclItemP(X)        ((AclItem *) DatumGetPointer(X))
00108 #define PG_GETARG_ACLITEM_P(n)     DatumGetAclItemP(PG_GETARG_DATUM(n))
00109 #define PG_RETURN_ACLITEM_P(x)     PG_RETURN_POINTER(x)
00110 
00111 #define DatumGetAclP(X)            ((Acl *) PG_DETOAST_DATUM(X))
00112 #define DatumGetAclPCopy(X)        ((Acl *) PG_DETOAST_DATUM_COPY(X))
00113 #define PG_GETARG_ACL_P(n)         DatumGetAclP(PG_GETARG_DATUM(n))
00114 #define PG_GETARG_ACL_P_COPY(n)    DatumGetAclPCopy(PG_GETARG_DATUM(n))
00115 #define PG_RETURN_ACL_P(x)         PG_RETURN_POINTER(x)
00116 
00117 /*
00118  * ACL modification opcodes for aclupdate
00119  */
00120 #define ACL_MODECHG_ADD         1
00121 #define ACL_MODECHG_DEL         2
00122 #define ACL_MODECHG_EQL         3
00123 
00124 /*
00125  * External representations of the privilege bits --- aclitemin/aclitemout
00126  * represent each possible privilege bit with a distinct 1-character code
00127  */
00128 #define ACL_INSERT_CHR          'a'     /* formerly known as "append" */
00129 #define ACL_SELECT_CHR          'r'     /* formerly known as "read" */
00130 #define ACL_UPDATE_CHR          'w'     /* formerly known as "write" */
00131 #define ACL_DELETE_CHR          'd'
00132 #define ACL_TRUNCATE_CHR        'D'     /* super-delete, as it were */
00133 #define ACL_REFERENCES_CHR      'x'
00134 #define ACL_TRIGGER_CHR         't'
00135 #define ACL_EXECUTE_CHR         'X'
00136 #define ACL_USAGE_CHR           'U'
00137 #define ACL_CREATE_CHR          'C'
00138 #define ACL_CREATE_TEMP_CHR     'T'
00139 #define ACL_CONNECT_CHR         'c'
00140 
00141 /* string holding all privilege code chars, in order by bitmask position */
00142 #define ACL_ALL_RIGHTS_STR  "arwdDxtXUCTc"
00143 
00144 /*
00145  * Bitmasks defining "all rights" for each supported object type
00146  */
00147 #define ACL_ALL_RIGHTS_COLUMN       (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
00148 #define ACL_ALL_RIGHTS_RELATION     (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER)
00149 #define ACL_ALL_RIGHTS_SEQUENCE     (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
00150 #define ACL_ALL_RIGHTS_DATABASE     (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
00151 #define ACL_ALL_RIGHTS_FDW          (ACL_USAGE)
00152 #define ACL_ALL_RIGHTS_FOREIGN_SERVER (ACL_USAGE)
00153 #define ACL_ALL_RIGHTS_FUNCTION     (ACL_EXECUTE)
00154 #define ACL_ALL_RIGHTS_LANGUAGE     (ACL_USAGE)
00155 #define ACL_ALL_RIGHTS_LARGEOBJECT  (ACL_SELECT|ACL_UPDATE)
00156 #define ACL_ALL_RIGHTS_NAMESPACE    (ACL_USAGE|ACL_CREATE)
00157 #define ACL_ALL_RIGHTS_TABLESPACE   (ACL_CREATE)
00158 #define ACL_ALL_RIGHTS_TYPE         (ACL_USAGE)
00159 
00160 /* operation codes for pg_*_aclmask */
00161 typedef enum
00162 {
00163     ACLMASK_ALL,                /* normal case: compute all bits */
00164     ACLMASK_ANY                 /* return when result is known nonzero */
00165 } AclMaskHow;
00166 
00167 /* result codes for pg_*_aclcheck */
00168 typedef enum
00169 {
00170     ACLCHECK_OK = 0,
00171     ACLCHECK_NO_PRIV,
00172     ACLCHECK_NOT_OWNER
00173 } AclResult;
00174 
00175 /* this enum covers all object types that can have privilege errors */
00176 /* currently it's only used to tell aclcheck_error what to say */
00177 typedef enum AclObjectKind
00178 {
00179     ACL_KIND_COLUMN,            /* pg_attribute */
00180     ACL_KIND_CLASS,             /* pg_class */
00181     ACL_KIND_SEQUENCE,          /* pg_sequence */
00182     ACL_KIND_DATABASE,          /* pg_database */
00183     ACL_KIND_PROC,              /* pg_proc */
00184     ACL_KIND_OPER,              /* pg_operator */
00185     ACL_KIND_TYPE,              /* pg_type */
00186     ACL_KIND_LANGUAGE,          /* pg_language */
00187     ACL_KIND_LARGEOBJECT,       /* pg_largeobject */
00188     ACL_KIND_NAMESPACE,         /* pg_namespace */
00189     ACL_KIND_OPCLASS,           /* pg_opclass */
00190     ACL_KIND_OPFAMILY,          /* pg_opfamily */
00191     ACL_KIND_COLLATION,         /* pg_collation */
00192     ACL_KIND_CONVERSION,        /* pg_conversion */
00193     ACL_KIND_TABLESPACE,        /* pg_tablespace */
00194     ACL_KIND_TSDICTIONARY,      /* pg_ts_dict */
00195     ACL_KIND_TSCONFIGURATION,   /* pg_ts_config */
00196     ACL_KIND_FDW,               /* pg_foreign_data_wrapper */
00197     ACL_KIND_FOREIGN_SERVER,    /* pg_foreign_server */
00198     ACL_KIND_EVENT_TRIGGER,     /* pg_event_trigger */
00199     ACL_KIND_EXTENSION,         /* pg_extension */
00200     MAX_ACL_KIND                /* MUST BE LAST */
00201 } AclObjectKind;
00202 
00203 
00204 /*
00205  * routines used internally
00206  */
00207 extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
00208 extern Acl *get_user_default_acl(GrantObjectType objtype, Oid ownerId,
00209                      Oid nsp_oid);
00210 
00211 extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
00212           int modechg, Oid ownerId, DropBehavior behavior);
00213 extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
00214 extern Acl *make_empty_acl(void);
00215 extern Acl *aclcopy(const Acl *orig_acl);
00216 extern Acl *aclconcat(const Acl *left_acl, const Acl *right_acl);
00217 extern Acl *aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId);
00218 extern void aclitemsort(Acl *acl);
00219 extern bool aclequal(const Acl *left_acl, const Acl *right_acl);
00220 
00221 extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
00222         AclMode mask, AclMaskHow how);
00223 extern int  aclmembers(const Acl *acl, Oid **roleids);
00224 
00225 extern bool has_privs_of_role(Oid member, Oid role);
00226 extern bool is_member_of_role(Oid member, Oid role);
00227 extern bool is_member_of_role_nosuper(Oid member, Oid role);
00228 extern bool is_admin_of_role(Oid member, Oid role);
00229 extern void check_is_member_of_role(Oid member, Oid role);
00230 extern Oid  get_role_oid(const char *rolname, bool missing_ok);
00231 
00232 extern void select_best_grantor(Oid roleId, AclMode privileges,
00233                     const Acl *acl, Oid ownerId,
00234                     Oid *grantorId, AclMode *grantOptions);
00235 
00236 extern void initialize_acl(void);
00237 
00238 /*
00239  * SQL functions (from acl.c)
00240  */
00241 extern Datum aclitemin(PG_FUNCTION_ARGS);
00242 extern Datum aclitemout(PG_FUNCTION_ARGS);
00243 extern Datum aclinsert(PG_FUNCTION_ARGS);
00244 extern Datum aclremove(PG_FUNCTION_ARGS);
00245 extern Datum aclcontains(PG_FUNCTION_ARGS);
00246 extern Datum makeaclitem(PG_FUNCTION_ARGS);
00247 extern Datum aclitem_eq(PG_FUNCTION_ARGS);
00248 extern Datum hash_aclitem(PG_FUNCTION_ARGS);
00249 extern Datum acldefault_sql(PG_FUNCTION_ARGS);
00250 extern Datum aclexplode(PG_FUNCTION_ARGS);
00251 
00252 /*
00253  * prototypes for functions in aclchk.c
00254  */
00255 extern void ExecuteGrantStmt(GrantStmt *stmt);
00256 extern void ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt);
00257 
00258 extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid);
00259 extern void RemoveDefaultACLById(Oid defaclOid);
00260 
00261 extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum,
00262                      Oid roleid, AclMode mask, AclMaskHow how);
00263 extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
00264                  AclMode mask, AclMaskHow how);
00265 extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
00266                     AclMode mask, AclMaskHow how);
00267 extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
00268                 AclMode mask, AclMaskHow how);
00269 extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
00270                     AclMode mask, AclMaskHow how);
00271 extern AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
00272                             AclMode mask, AclMaskHow how, Snapshot snapshot);
00273 extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
00274                      AclMode mask, AclMaskHow how);
00275 extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
00276                       AclMode mask, AclMaskHow how);
00277 extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid,
00278                                 AclMode mask, AclMaskHow how);
00279 extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
00280                           AclMode mask, AclMaskHow how);
00281 extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid,
00282                 AclMode mask, AclMaskHow how);
00283 
00284 extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum,
00285                       Oid roleid, AclMode mode);
00286 extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid,
00287                           AclMode mode, AclMaskHow how);
00288 extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
00289 extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
00290 extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
00291 extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
00292 extern AclResult pg_largeobject_aclcheck_snapshot(Oid lang_oid, Oid roleid,
00293                                  AclMode mode, Snapshot snapshot);
00294 extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
00295 extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
00296 extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode);
00297 extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode);
00298 extern AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode);
00299 
00300 extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
00301                const char *objectname);
00302 
00303 extern void aclcheck_error_col(AclResult aclerr, AclObjectKind objectkind,
00304                    const char *objectname, const char *colname);
00305 
00306 extern void aclcheck_error_type(AclResult aclerr, Oid typeOid);
00307 
00308 /* ownercheck routines just return true (owner) or false (not) */
00309 extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
00310 extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
00311 extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
00312 extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
00313 extern bool pg_language_ownercheck(Oid lan_oid, Oid roleid);
00314 extern bool pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid);
00315 extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
00316 extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
00317 extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
00318 extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid);
00319 extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
00320 extern bool pg_collation_ownercheck(Oid coll_oid, Oid roleid);
00321 extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
00322 extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid);
00323 extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid);
00324 extern bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid);
00325 extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid);
00326 extern bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid);
00327 extern bool pg_extension_ownercheck(Oid ext_oid, Oid roleid);
00328 extern bool has_createrole_privilege(Oid roleid);
00329 
00330 #endif   /* ACL_H */