dovecot-2.0: imap-acl: Initial SETACL box owner +rights should a...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Aug 9 18:08:02 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/bbfe3a00bc74
changeset: 11964:bbfe3a00bc74
user: Timo Sirainen <tss at iki.fi>
date: Mon Aug 09 16:07:54 2010 +0100
description:
imap-acl: Initial SETACL box owner +rights should apply on top of default rights, not empty rights.
So typically this should be a no-op when mailbox doesn't yet have explicit
rights for owner.
diffstat:
src/plugins/imap-acl/imap-acl-plugin.c | 73 +++++++++++++++++++++++++++++-------
1 files changed, 58 insertions(+), 15 deletions(-)
diffs (140 lines):
diff -r 8814ced6d012 -r bbfe3a00bc74 src/plugins/imap-acl/imap-acl-plugin.c
--- a/src/plugins/imap-acl/imap-acl-plugin.c Mon Aug 09 15:33:20 2010 +0100
+++ b/src/plugins/imap-acl/imap-acl-plugin.c Mon Aug 09 16:07:54 2010 +0100
@@ -177,6 +177,41 @@
imap_acl_write_rights_list(dest, rights);
}
+static bool
+acl_rights_is_owner(struct acl_backend *backend,
+ const struct acl_rights *rights)
+{
+ switch (rights->id_type) {
+ case ACL_ID_OWNER:
+ return TRUE;
+ case ACL_ID_USER:
+ return acl_backend_user_name_equals(backend,
+ rights->identifier);
+ default:
+ return FALSE;
+ }
+}
+
+static bool have_positive_owner_rights(struct acl_backend *backend,
+ struct acl_object *aclobj)
+{
+ struct acl_object_list_iter *iter;
+ struct acl_rights rights;
+ bool ret = FALSE;
+
+ iter = acl_object_list_init(aclobj);
+ while ((ret = acl_object_list_next(iter, &rights)) > 0) {
+ if (acl_rights_is_owner(backend, &rights)) {
+ if (rights.rights != NULL) {
+ ret = TRUE;
+ break;
+ }
+ }
+ }
+ acl_object_list_deinit(&iter);
+ return ret;
+}
+
static int
imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
struct acl_object *aclobj, bool convert_owner,
@@ -187,7 +222,7 @@
string_t *tmp;
const char *username;
unsigned int orig_len = str_len(dest);
- bool owner, seen_owner = FALSE, seen_positive_owner = FALSE;
+ bool seen_owner = FALSE, seen_positive_owner = FALSE;
int ret;
username = acl_backend_get_acl_username(backend);
@@ -197,20 +232,11 @@
tmp = t_str_new(128);
iter = acl_object_list_init(aclobj);
while ((ret = acl_object_list_next(iter, &rights)) > 0) {
- if (rights.id_type == ACL_ID_USER &&
- acl_backend_user_name_equals(backend, rights.identifier))
- owner = TRUE;
- else if (rights.id_type == ACL_ID_OWNER) {
- owner = TRUE;
- if (convert_owner) {
+ if (acl_rights_is_owner(backend, &rights)) {
+ if (rights.id_type == ACL_ID_OWNER && convert_owner) {
rights.id_type = ACL_ID_USER;
rights.identifier = username;
}
- } else {
- owner = FALSE;
- }
-
- if (owner) {
if (seen_owner && convert_owner) {
/* oops, we have both owner and user=myself.
can't do the conversion, so try again. */
@@ -462,10 +488,13 @@
return 0;
}
-static void imap_acl_update_ensure_keep_admins(struct acl_rights_update *update)
+static void imap_acl_update_ensure_keep_admins(struct acl_backend *backend,
+ struct acl_object *aclobj,
+ struct acl_rights_update *update)
{
static const char *acl_admin = MAIL_ACL_ADMIN;
const char *const *rights = update->rights.rights;
+ const char *const *default_rights;
ARRAY_TYPE(const_string) new_rights;
unsigned int i;
@@ -477,6 +506,18 @@
}
switch (update->modify_mode) {
+ case ACL_MODIFY_MODE_ADD:
+ if (have_positive_owner_rights(backend, aclobj))
+ return;
+
+ /* adding initial rights for a user. we need to add
+ the defaults also. don't worry about duplicates. */
+ for (; rights[i] != NULL; i++)
+ array_append(&new_rights, &rights[i], 1);
+ default_rights = acl_object_get_default_rights(aclobj);
+ for (i = 0; default_rights[i] != NULL; i++)
+ array_append(&new_rights, &default_rights[i], 1);
+ break;
case ACL_MODIFY_MODE_REMOVE:
if (rights[i] == NULL)
return;
@@ -504,6 +545,7 @@
struct mail_namespace *ns;
struct mailbox *box;
struct acl_backend *backend;
+ struct acl_object *aclobj;
struct acl_rights_update update;
struct acl_rights *r;
const char *mailbox, *identifier, *rights, *error;
@@ -560,6 +602,7 @@
return TRUE;
}
+ aclobj = acl_mailbox_get_aclobj(box);
if (negative) {
update.neg_modify_mode = update.modify_mode;
update.modify_mode = ACL_MODIFY_MODE_REMOVE;
@@ -573,10 +616,10 @@
ns->user->username) == 0))) {
/* make sure client doesn't (accidentally) remove admin
privileges from its own mailboxes */
- imap_acl_update_ensure_keep_admins(&update);
+ imap_acl_update_ensure_keep_admins(backend, aclobj, &update);
}
- if (acl_object_update(acl_mailbox_get_aclobj(box), &update) < 0)
+ if (acl_object_update(aclobj, &update) < 0)
client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
else
client_send_tagline(cmd, "OK Setacl complete.");
More information about the dovecot-cvs
mailing list