summaryrefslogtreecommitdiffstats
path: root/src/plugins/acl/acl-api.h
blob: 7b19a98ec94528c20dd2850f990662cdbcec55e7 (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
164
165
166
167
#ifndef ACL_API_H
#define ACL_API_H

#include <sys/stat.h>

struct mailbox_list;
struct mail_storage;
struct mailbox;
struct acl_object;

/* Show mailbox in mailbox list. Allow subscribing to it. */
#define MAIL_ACL_LOOKUP		"lookup"
/* Allow opening mailbox for reading */
#define MAIL_ACL_READ		"read"
/* Allow permanent flag changes (except for seen/deleted).
   If not set, doesn't allow save/copy to set any flags either. */
#define MAIL_ACL_WRITE		"write"
/* Allow permanent seen-flag changes */
#define MAIL_ACL_WRITE_SEEN	"write-seen"
/* Allow permanent deleted-flag changes */
#define MAIL_ACL_WRITE_DELETED	"write-deleted"
/* Allow saving and copying mails into the mailbox */
#define MAIL_ACL_INSERT		"insert"
/* Allow posting mails to the mailbox (e.g. Sieve fileinto) */
#define MAIL_ACL_POST		"post"
/* Allow expunging mails */
#define MAIL_ACL_EXPUNGE	"expunge"
/* Allow creating child mailboxes */
#define MAIL_ACL_CREATE		"create"
/* Allow deleting this mailbox */
#define MAIL_ACL_DELETE		"delete"
/* Allow changing ACL state in this mailbox */
#define MAIL_ACL_ADMIN		"admin"

#define MAILBOX_ATTRIBUTE_PREFIX_ACL \
	MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT"acl/"

/* ACL identifiers in override order */
enum acl_id_type {
	/* Anyone's rights, including anonymous's.
	   identifier name is ignored. */
	ACL_ID_ANYONE,
	/* Authenticate users' rights. identifier name is ignored. */
	ACL_ID_AUTHENTICATED,
	/* Group's rights */
	ACL_ID_GROUP,
	/* Owner's rights, used when user is the storage's owner.
	   identifier name is ignored. */
	ACL_ID_OWNER,
	/* User's rights */
	ACL_ID_USER,
	/* Same as group's rights, but also overrides user's rights */
	ACL_ID_GROUP_OVERRIDE,

	ACL_ID_TYPE_COUNT
};

enum acl_modify_mode {
	/* Remove rights from existing ACL */
	ACL_MODIFY_MODE_REMOVE = 0,
	/* Add rights to existing ACL (or create a new one) */
	ACL_MODIFY_MODE_ADD,
	/* Replace existing ACL with given rights */
	ACL_MODIFY_MODE_REPLACE,
	/* Clear all the rights from an existing ACL */
	ACL_MODIFY_MODE_CLEAR
};

struct acl_rights {
	/* Type of the identifier, user/group */
	enum acl_id_type id_type;
	/* Identifier, eg. username / group name */
	const char *identifier;

	/* Rights assigned. NULL entry can be ignored, but { NULL } means user
	   has no rights. */
	const char *const *rights;
	/* Negative rights assigned */
	const char *const *neg_rights;

	/* These rights are global for all users */
	bool global:1;
};
ARRAY_DEFINE_TYPE(acl_rights, struct acl_rights);

struct acl_rights_update {
	struct acl_rights rights;

	enum acl_modify_mode modify_mode;
	enum acl_modify_mode neg_modify_mode;
	/* These changes' "last changed" timestamp */
	time_t last_change;
};

/* data contains the information needed to initialize ACL backend. If username
   is NULL, it means the user is anonymous. Username and groups are matched
   case-sensitively. */
struct acl_backend *
acl_backend_init(const char *data, struct mailbox_list *list,
		 const char *acl_username, const char *const *groups,
		 bool owner);
void acl_backend_deinit(struct acl_backend **backend);

/* Returns the acl_username passed to acl_backend_init(). Note that with
   anonymous users NULL is returned. */
const char *acl_backend_get_acl_username(struct acl_backend *backend);

/* Returns TRUE if user isn't anonymous. */
bool acl_backend_user_is_authenticated(struct acl_backend *backend);
/* Returns TRUE if user owns the storage. */
bool acl_backend_user_is_owner(struct acl_backend *backend);
/* Returns TRUE if given name matches the ACL user name. */
bool acl_backend_user_name_equals(struct acl_backend *backend,
				  const char *username);
/* Returns TRUE if ACL user is in given group. */
bool acl_backend_user_is_in_group(struct acl_backend *backend,
				  const char *group_name);
/* Returns index for the right name. If it doesn't exist, it's created. */
unsigned int acl_backend_lookup_right(struct acl_backend *backend,
				      const char *right);
/* Returns TRUE if acl_rights matches backend user. */
bool acl_backend_rights_match_me(struct acl_backend *backend,
				 const struct acl_rights *rights);

/* List mailboxes that have lookup right to some non-owners. */
struct acl_mailbox_list_context *
acl_backend_nonowner_lookups_iter_init(struct acl_backend *backend);
bool acl_backend_nonowner_lookups_iter_next(struct acl_mailbox_list_context *ctx,
					   const char **name_r);
int
acl_backend_nonowner_lookups_iter_deinit(struct acl_mailbox_list_context **ctx);

/* Force a rebuild for nonowner lookups index */
int acl_backend_nonowner_lookups_rebuild(struct acl_backend *backend);

struct acl_object *acl_object_init_from_name(struct acl_backend *backend,
					     const char *name);
struct acl_object *acl_object_init_from_parent(struct acl_backend *backend,
					       const char *child_name);
void acl_object_deinit(struct acl_object **aclobj);

/* Returns 1 if we have the requested rights, 0 if not, or -1 if internal
   error occurred. */
int acl_object_have_right(struct acl_object *aclobj, unsigned int right_idx);
/* Returns 0 = ok, -1 = internal error */
int acl_object_get_my_rights(struct acl_object *aclobj, pool_t pool,
			     const char *const **rights_r);
/* Returns the default rights for the object. */
const char *const *acl_object_get_default_rights(struct acl_object *aclobj);
/* Returns timestamp of when the ACLs were last changed for this object,
   or 0 = never. */
int acl_object_last_changed(struct acl_object *aclobj, time_t *last_changed_r);

/* Update ACL of given object. */
int acl_object_update(struct acl_object *aclobj,
		      const struct acl_rights_update *update);

/* List all identifiers. */
struct acl_object_list_iter *acl_object_list_init(struct acl_object *aclobj);
bool acl_object_list_next(struct acl_object_list_iter *iter,
			  struct acl_rights *rights_r);
int acl_object_list_deinit(struct acl_object_list_iter **iter);

/* Returns the canonical ID for the right. */
const char *acl_rights_get_id(const struct acl_rights *right);

#endif