Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8756:be1d1c722c92 HEAD
imap-acl: GETACL: Convert "owner" to the actual username whenever possible.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 20 Feb 2009 16:26:41 -0500 |
parents | 2579345e877f |
children | 0ac80bed5d3e |
files | src/plugins/acl/acl-api-private.h src/plugins/acl/acl-api.c src/plugins/acl/acl-api.h src/plugins/acl/acl-backend-vfile.c src/plugins/acl/acl-backend.c src/plugins/imap-acl/imap-acl-plugin.c |
diffstat | 6 files changed, 77 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/plugins/acl/acl-api-private.h Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/acl/acl-api-private.h Fri Feb 20 16:26:41 2009 -0500 @@ -73,7 +73,6 @@ struct acl_object *aclobj; unsigned int idx; - unsigned int returned_owner:1; unsigned int failed:1; };
--- a/src/plugins/acl/acl-api.c Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/acl/acl-api.c Fri Feb 20 16:26:41 2009 -0500 @@ -124,6 +124,13 @@ return ret; } +const char *const *acl_object_get_default_rights(struct acl_object *aclobj) +{ + return acl_backend_mask_get_names(aclobj->backend, + aclobj->backend->default_aclmask, + pool_datastack_create()); +} + int acl_object_update(struct acl_object *aclobj, const struct acl_rights_update *update) {
--- a/src/plugins/acl/acl-api.h Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/acl/acl-api.h Fri Feb 20 16:26:41 2009 -0500 @@ -92,6 +92,11 @@ 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. */ @@ -128,6 +133,8 @@ /* 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); /* Update ACL of given object. */ int acl_object_update(struct acl_object *aclobj,
--- a/src/plugins/acl/acl-backend-vfile.c Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/acl/acl-backend-vfile.c Fri Feb 20 16:26:41 2009 -0500 @@ -1127,7 +1127,6 @@ struct acl_object_vfile *aclobj = (struct acl_object_vfile *)_aclobj; struct acl_object_list_iter *iter; - struct mail_namespace *ns; iter = i_new(struct acl_object_list_iter, 1); iter->aclobj = _aclobj; @@ -1138,12 +1137,6 @@ acl_cache_flush(_aclobj->backend->cache, _aclobj->name); } - /* be sure to return owner for private namespaces. - (other namespaces don't have an owner) */ - ns = mailbox_list_get_namespace(_aclobj->backend->list); - if (ns->type != NAMESPACE_PRIVATE) - iter->returned_owner = TRUE; - if (_aclobj->backend->v.object_refresh_cache(_aclobj) < 0) iter->failed = TRUE; return iter; @@ -1157,26 +1150,10 @@ (struct acl_object_vfile *)iter->aclobj; const struct acl_rights *rights; - if (iter->idx == array_count(&aclobj->rights)) { - struct acl_backend *backend = iter->aclobj->backend; - - if (iter->returned_owner) - return 0; - - /* return missing owner based on the default ACLs */ - iter->returned_owner = TRUE; - memset(rights_r, 0, sizeof(*rights_r)); - rights_r->id_type = ACL_ID_OWNER; - rights_r->rights = - acl_backend_mask_get_names(backend, - backend->default_aclmask, - pool_datastack_create()); - return 1; - } + if (iter->idx == array_count(&aclobj->rights)) + return 0; rights = array_idx(&aclobj->rights, iter->idx++); - if (rights->id_type == ACL_ID_OWNER && rights->rights != NULL) - iter->returned_owner = TRUE; *rights_r = *rights; return 1; }
--- a/src/plugins/acl/acl-backend.c Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/acl/acl-backend.c Fri Feb 20 16:26:41 2009 -0500 @@ -95,6 +95,11 @@ backend->v.deinit(backend); } +const char *acl_backend_get_acl_username(struct acl_backend *backend) +{ + return backend->username; +} + bool acl_backend_user_is_authenticated(struct acl_backend *backend) { return backend->username != NULL;
--- a/src/plugins/imap-acl/imap-acl-plugin.c Fri Feb 20 15:47:39 2009 -0500 +++ b/src/plugins/imap-acl/imap-acl-plugin.c Fri Feb 20 16:26:41 2009 -0500 @@ -162,16 +162,51 @@ imap_acl_write_rights_list(dest, rights); } -static int imap_acl_write_aclobj(string_t *dest, struct acl_object *aclobj) +static int +imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend, + struct acl_object *aclobj, bool convert_owner) { struct acl_object_list_iter *iter; struct acl_rights rights; string_t *tmp; + const char *username; + unsigned int orig_len = str_len(dest); + bool owner, seen_owner = FALSE, seen_positive_owner = FALSE; int ret; + username = acl_backend_get_acl_username(backend); + if (username == NULL) + convert_owner = FALSE; + 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) { + 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. */ + str_truncate(dest, orig_len); + return imap_acl_write_aclobj(dest, backend, + aclobj, FALSE); + } + seen_owner = TRUE; + if (rights.rights != NULL) + seen_positive_owner = TRUE; + } + if (rights.rights != NULL) { str_append_c(dest, ' '); imap_acl_write_right(dest, tmp, &rights, FALSE); @@ -182,11 +217,28 @@ } } acl_object_list_deinit(&iter); + + if (!seen_positive_owner && username != NULL) { + /* no positive owner rights returned, write default ACLs */ + memset(&rights, 0, sizeof(rights)); + if (!convert_owner) { + rights.id_type = ACL_ID_OWNER; + } else { + rights.id_type = ACL_ID_USER; + rights.identifier = username; + } + rights.rights = acl_object_get_default_rights(aclobj); + if (rights.rights != NULL) { + str_append_c(dest, ' '); + imap_acl_write_right(dest, tmp, &rights, FALSE); + } + } return ret; } static bool cmd_getacl(struct client_command_context *cmd) { + struct acl_backend *backend; struct mailbox *box; const char *mailbox; string_t *str; @@ -207,7 +259,9 @@ imap_quote_append_string(str, mailbox, FALSE); len = str_len(str); - ret = imap_acl_write_aclobj(str, acl_mailbox_get_aclobj(box)); + backend = acl_storage_get_backend(mailbox_get_storage(box)); + ret = imap_acl_write_aclobj(str, backend, + acl_mailbox_get_aclobj(box), TRUE); if (ret == 0) { client_send_line(cmd->client, str_c(str)); client_send_tagline(cmd, "OK Getacl completed.");