aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/acl.h
blob: fec5a8ed3822502275d676d87e3a91f992357274 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*-------------------------------------------------------------------------
 *
 * acl.h--
 *    Definition of (and support for) access control list data structures.
 *
 *
 * Copyright (c) 1994, Regents of the University of California
 *
 * $Id: acl.h,v 1.1.1.1 1996/07/09 06:22:01 scrappy Exp $
 *
 * NOTES
 *    For backward-compatability purposes we have to allow there
 *    to be a null ACL in a pg_class tuple.  This will be defined as
 *    meaning "no protection" (i.e., old catalogs get old semantics).
 *
 *    The AclItems in an ACL array are currently kept in sorted order.
 *    Things will break hard if you change that without changing the
 *    code wherever this is included.
 *
 *-------------------------------------------------------------------------
 */
#ifndef ACL_H
#define ACL_H

#include "postgres.h"
#include "utils/array.h"
#include "nodes/parsenodes.h" /* for ChangeACLStmt */

/*
 * AclId	system identifier for the user, group, etc.
 *		XXX currently UNIX uid for users...
 */
typedef uint32 AclId;
#define	ACL_ID_WORLD	0	/* XXX only idtype should be checked */

/*
 * AclIdType	tag that describes if the AclId is a user, group, etc.
 */
typedef uint8 AclIdType;
#define	ACL_IDTYPE_WORLD	0x00
#define	ACL_IDTYPE_UID		0x01	/* user id - from pg_user */
#define	ACL_IDTYPE_GID		0x02	/* group id - from pg_group */

/*
 * AclMode	the actual permissions
 *		XXX should probably use bit.h routines.
 *		XXX should probably also stuff the modechg cruft in the
 *		    high bits, too.
 */
typedef uint8 AclMode;
#define	ACL_NO		0	/* no permissions */
#define	ACL_AP		(1<<0)	/* append */
#define	ACL_RD		(1<<1)	/* read */
#define	ACL_WR		(1<<2)	/* write (append/delete/replace) */
#define	ACL_RU		(1<<3)	/* place rules */
#define	N_ACL_MODES	4

#define	ACL_MODECHG_ADD		1
#define	ACL_MODECHG_DEL		2
#define	ACL_MODECHG_EQL		3

/* change this line if you want to set the default acl permission  */
#define	ACL_WORLD_DEFAULT	(ACL_RD)
/* #define	ACL_WORLD_DEFAULT	(ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
#define	ACL_OWNER_DEFAULT	(ACL_RD|ACL_WR|ACL_AP|ACL_RU)

/*
 * AclItem
 */
typedef struct AclItem {
    AclId	ai_id;
    AclIdType	ai_idtype;
    AclMode	ai_mode;
} AclItem;
/* Note: if the size of AclItem changes, 
   change the aclitem typlen in pg_type.h */

/*
 * The value of the first dimension-array element.  Since these arrays
 * always have a lower-bound of 0, this is the same as the number of
 * elements in the array.
 */
#define	ARR_DIM0(a) (((unsigned *) (((char *) a) + sizeof(ArrayType)))[0])

/*
 * Acl		a one-dimensional POSTGRES array of AclItem
 */
typedef ArrayType Acl;
#define	ACL_NUM(ACL)		ARR_DIM0(ACL)
#define	ACL_DAT(ACL)		((AclItem *) ARR_DATA_PTR(ACL))
#define	ACL_N_SIZE(N) \
	((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclItem))))
#define	ACL_SIZE(ACL)		ARR_SIZE(ACL)

/*
 * IdList	a one-dimensional POSTGRES array of AclId
 */
typedef ArrayType IdList;
#define	IDLIST_NUM(IDL)		ARR_DIM0(IDL)
#define	IDLIST_DAT(IDL)		((AclId *) ARR_DATA_PTR(IDL))
#define	IDLIST_N_SIZE(N) \
	((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))))
#define	IDLIST_SIZE(IDL)	ARR_SIZE(IDL)

#define	ACL_MODECHG_STR		"+-="	/* list of valid characters */
#define	ACL_MODECHG_ADD_CHR	'+'
#define	ACL_MODECHG_DEL_CHR	'-'
#define	ACL_MODECHG_EQL_CHR	'='
#define	ACL_MODE_STR		"arwR"	/* list of valid characters */
#define	ACL_MODE_AP_CHR		'a'
#define	ACL_MODE_RD_CHR		'r'
#define	ACL_MODE_WR_CHR		'w'
#define	ACL_MODE_RU_CHR		'R'

/* we use this warning string both for non-existent tables and
   insufficient privilege so non-privileged users cannot ascertain whether 
   the class exists or not */
#define ACL_NO_PRIV_WARNING "Either no such class or insufficient privilege"

/*
 * Enable ACL execution tracing and table dumps
 */
/*#define ACLDEBUG_TRACE*/

/*
 * routines used internally (parser, etc.) 
 */
extern char *aclparse(char *s, AclItem *aip, unsigned *modechg);
extern Acl *aclownerdefault(AclId ownerid);
extern Acl *acldefault();
extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg);

extern char* aclmakepriv(char* old_privlist, char new_priv);
extern char* aclmakeuser(char* user_type, char* user);
extern ChangeACLStmt* makeAclStmt(char* privs, List* rel_list, char* grantee,
				  char grant_or_revoke);

/*
 * exported routines (from acl.c)
 */
extern Acl *makeacl(int n);
extern AclItem *aclitemin(char *s);
extern char *aclitemout(AclItem *aip);
extern Acl *aclinsert(Acl *old_acl, AclItem *mod_aip);
extern Acl *aclremove(Acl *old_acl, AclItem *mod_aip);
extern int32 aclcontains(Acl *acl, AclItem *aip);

/*
 * prototypes for functions in aclchk.c
 */
extern void ChangeAcl(char *relname, AclItem *mod_aip, unsigned modechg);
extern AclId get_grosysid(char *groname);
extern char *get_groname(AclId grosysid);
extern int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);

/* XXX move these elsewhere -pma */
extern int32 pg_aclcheck(char *relname, char *usename, AclMode mode);
extern int32 pg_ownercheck(char *usename, char *value, int cacheid);
extern int32 pg_func_ownercheck(char *usename, char *funcname,
			 int nargs, Oid *arglist);

#endif	/* ACL_H */