bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "imap-common.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "str.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "imap-quote.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "imap-resp-code.h"
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "imap-commands.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "mail-storage.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "mail-namespace.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "acl-api.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "acl-storage.h"
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen#include "acl-plugin.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#include "imap-acl-plugin.h"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
25d624dd86700c82cd28427f3d3bebe7c8f7f459Timo Sirainen#define ERROR_NOT_ADMIN "["IMAP_RESP_CODE_NOPERM"] " \
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen "You lack administrator privileges on this mailbox."
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#define IMAP_ACL_ANYONE "anyone"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#define IMAP_ACL_AUTHENTICATED "authenticated"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#define IMAP_ACL_OWNER "owner"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#define IMAP_ACL_GROUP_PREFIX "$"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen#define IMAP_ACL_GROUP_OVERRIDE_PREFIX "!$"
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen#define IMAP_ACL_GLOBAL_PREFIX "#"
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstruct imap_acl_letter_map {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen char letter;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *name;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen};
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic const struct imap_acl_letter_map imap_acl_letter_map[] = {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'l', MAIL_ACL_LOOKUP },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'r', MAIL_ACL_READ },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'w', MAIL_ACL_WRITE },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 's', MAIL_ACL_WRITE_SEEN },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 't', MAIL_ACL_WRITE_DELETED },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'i', MAIL_ACL_INSERT },
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen { 'p', MAIL_ACL_POST },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'e', MAIL_ACL_EXPUNGE },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'k', MAIL_ACL_CREATE },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'x', MAIL_ACL_DELETE },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { 'a', MAIL_ACL_ADMIN },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen { '\0', NULL }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen};
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainenconst char *imap_acl_plugin_version = DOVECOT_ABI_VERSION;
15a07b47846c47a81d69a14d649564e222d6f742Timo Sirainen
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainenstatic struct module *imap_acl_module;
c1faff067b29fb48426cb84260adba563e93189aTimo Sirainenstatic imap_client_created_func_t *next_hook_client_created;
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic struct mailbox *
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenacl_mailbox_open_as_admin(struct client_command_context *cmd, const char *name)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_namespace *ns;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen enum mailbox_existence existence = MAILBOX_EXISTENCE_NONE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen int ret;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (ACL_USER_CONTEXT(cmd->client->user) == NULL) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen client_send_command_error(cmd, "ACLs disabled.");
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return NULL;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen ns = client_find_namespace(cmd, &name);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (ns == NULL)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return NULL;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* Force opening the mailbox so that we can give a nicer error message
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if mailbox isn't selectable but is listable. */
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_READONLY |
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAILBOX_FLAG_IGNORE_ACLS);
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen if (mailbox_exists(box, TRUE, &existence) == 0 &&
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen existence == MAILBOX_EXISTENCE_SELECT) {
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_ADMIN);
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen if (ret > 0)
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen return box;
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen /* mailbox doesn't exist / not an administrator. */
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen if (existence != MAILBOX_EXISTENCE_SELECT ||
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP) <= 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, t_strdup_printf(
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen "NO ["IMAP_RESP_CODE_NONEXISTENT"] "
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen MAIL_ERRSTR_MAILBOX_NOT_FOUND, name));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else {
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen client_send_tagline(cmd, "NO "ERROR_NOT_ADMIN);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return NULL;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic const struct imap_acl_letter_map *
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenimap_acl_letter_map_find(const char *name)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen unsigned int i;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen for (i = 0; imap_acl_letter_map[i].name != NULL; i++) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (strcmp(imap_acl_letter_map[i].name, name) == 0)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return &imap_acl_letter_map[i];
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return NULL;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic void
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenimap_acl_write_rights_list(string_t *dest, const char *const *rights)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct imap_acl_letter_map *map;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t orig_len = str_len(dest);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen bool append_c = FALSE, append_d = FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen for (i = 0; rights[i] != NULL; i++) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* write only letters */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen map = imap_acl_letter_map_find(rights[i]);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (map != NULL) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(dest, map->letter);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (map->letter == 'k' || map->letter == 'x')
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen append_c = TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (map->letter == 't' || map->letter == 'e')
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen append_d = TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (append_c)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(dest, 'c');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (append_d)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(dest, 'd');
411f318ed3a25fa66c1b932e10df43841e2725c9Timo Sirainen if (orig_len == str_len(dest))
411f318ed3a25fa66c1b932e10df43841e2725c9Timo Sirainen str_append(dest, "\"\"");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic void
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenimap_acl_write_right(string_t *dest, string_t *tmp,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct acl_rights *right, bool neg)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *const *rights = neg ? right->neg_rights : right->rights;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_truncate(tmp, 0);
3a9eb305fd4aad5502cb7e64625874385ab5bc19Timo Sirainen if (neg) str_append_c(tmp,'-');
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen if (right->global)
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen str_append(tmp, IMAP_ACL_GLOBAL_PREFIX);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen switch (right->id_type) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_ANYONE:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, IMAP_ACL_ANYONE);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_AUTHENTICATED:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, IMAP_ACL_AUTHENTICATED);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_OWNER:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, IMAP_ACL_OWNER);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_USER:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, right->identifier);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_GROUP:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, IMAP_ACL_GROUP_PREFIX);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, right->identifier);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_GROUP_OVERRIDE:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, IMAP_ACL_GROUP_OVERRIDE_PREFIX);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(tmp, right->identifier);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case ACL_ID_TYPE_COUNT:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_unreached();
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen imap_append_astring(dest, str_c(tmp));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(dest, ' ');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen imap_acl_write_rights_list(dest, rights);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainenstatic bool
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainenacl_rights_is_owner(struct acl_backend *backend,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen const struct acl_rights *rights)
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen{
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen switch (rights->id_type) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen case ACL_ID_OWNER:
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen return TRUE;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen case ACL_ID_USER:
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen return acl_backend_user_name_equals(backend,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen rights->identifier);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen default:
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen return FALSE;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen }
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen}
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainenstatic bool have_positive_owner_rights(struct acl_backend *backend,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_object *aclobj)
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen{
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_object_list_iter *iter;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_rights rights;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen bool ret = FALSE;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen iter = acl_object_list_init(aclobj);
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi while (acl_object_list_next(iter, &rights)) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (acl_rights_is_owner(backend, &rights)) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (rights.rights != NULL) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen ret = TRUE;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen break;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen }
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen }
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen }
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi (void)acl_object_list_deinit(&iter);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen return ret;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen}
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainenstatic int
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainenimap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen struct acl_object *aclobj, bool convert_owner,
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen bool add_default)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct acl_object_list_iter *iter;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct acl_rights rights;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen string_t *tmp;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen const char *username;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t orig_len = str_len(dest);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen bool seen_owner = FALSE, seen_positive_owner = FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen int ret;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen username = acl_backend_get_acl_username(backend);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (username == NULL)
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen convert_owner = FALSE;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen tmp = t_str_new(128);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen iter = acl_object_list_init(aclobj);
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi while (acl_object_list_next(iter, &rights)) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (acl_rights_is_owner(backend, &rights)) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (rights.id_type == ACL_ID_OWNER && convert_owner) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.id_type = ACL_ID_USER;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.identifier = username;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (seen_owner && convert_owner) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen /* oops, we have both owner and user=myself.
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen can't do the conversion, so try again. */
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen str_truncate(dest, orig_len);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen return imap_acl_write_aclobj(dest, backend,
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen aclobj, FALSE,
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen add_default);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen seen_owner = TRUE;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (rights.rights != NULL)
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen seen_positive_owner = TRUE;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen if (rights.rights != NULL) {
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen str_append_c(dest, ' ');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen imap_acl_write_right(dest, tmp, &rights, FALSE);
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen }
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen if (rights.neg_rights != NULL) {
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen str_append_c(dest, ' ');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen imap_acl_write_right(dest, tmp, &rights, TRUE);
34015eb0b74735f2fac07c12697bde20a94735e6Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi ret = acl_object_list_deinit(&iter);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen if (!seen_positive_owner && username != NULL && add_default) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen /* no positive owner rights returned, write default ACLs */
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&rights);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (!convert_owner) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.id_type = ACL_ID_OWNER;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen } else {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.id_type = ACL_ID_USER;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.identifier = username;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen rights.rights = acl_object_get_default_rights(aclobj);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (rights.rights != NULL) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen str_append_c(dest, ' ');
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen imap_acl_write_right(dest, tmp, &rights, FALSE);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return ret;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool cmd_getacl(struct client_command_context *cmd)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen struct acl_backend *backend;
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen struct mail_namespace *ns;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *mailbox;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen string_t *str;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen int ret;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen return FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (box == NULL)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str = t_str_new(128);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(str, "* ACL ");
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen imap_append_astring(str, mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ns = mailbox_get_namespace(box);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen backend = acl_mailbox_list_get_backend(ns->list);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen ret = imap_acl_write_aclobj(str, backend,
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen acl_mailbox_get_aclobj(box), TRUE,
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen ns->type == MAIL_NAMESPACE_TYPE_PRIVATE);
75771bd32a86b7360d28f1254ffba99f63d763d9Aki Tuomi if (ret > -1) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_line(cmd->client, str_c(str));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "OK Getacl completed.");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool cmd_myrights(struct client_command_context *cmd)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_namespace *ns;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
ec5fec7eab19e134a2607b7e224b3e14a1771ee0Timo Sirainen const char *mailbox, *orig_mailbox;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *const *rights;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen string_t *str;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen return FALSE;
ec5fec7eab19e134a2607b7e224b3e14a1771ee0Timo Sirainen orig_mailbox = mailbox;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (ACL_USER_CONTEXT(cmd->client->user) == NULL) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen client_send_command_error(cmd, "ACLs disabled.");
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return TRUE;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen ns = client_find_namespace(cmd, &mailbox);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (ns == NULL)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen box = mailbox_alloc(ns->list, mailbox,
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen MAILBOX_FLAG_READONLY | MAILBOX_FLAG_IGNORE_ACLS);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (acl_object_get_my_rights(acl_mailbox_get_aclobj(box),
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen pool_datastack_create(), &rights) < 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen /* Post right alone doesn't give permissions to see if the mailbox
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen exists or not. Only mail deliveries care about that. */
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen if (*rights == NULL ||
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen (strcmp(*rights, MAIL_ACL_POST) == 0 && rights[1] == NULL)) {
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen client_send_tagline(cmd, t_strdup_printf(
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen "NO ["IMAP_RESP_CODE_NONEXISTENT"] "
e593e507ee5ea3869271a631874c5c4b5c7a294dTimo Sirainen MAIL_ERRSTR_MAILBOX_NOT_FOUND, mailbox));
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen return TRUE;
e1203014de25c8c3d3975a9f4b4a04616df4bba2Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str = t_str_new(128);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(str, "* MYRIGHTS ");
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen imap_append_astring(str, orig_mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(str,' ');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen imap_acl_write_rights_list(str, rights);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_line(cmd->client, str_c(str));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "OK Myrights completed.");
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool cmd_listrights(struct client_command_context *cmd)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *mailbox, *identifier;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen string_t *str;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (!client_read_string_args(cmd, 2, &mailbox, &identifier))
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen return FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (box == NULL)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str = t_str_new(128);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(str, "* LISTRIGHTS ");
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen imap_append_astring(str, mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(str, ' ');
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen imap_append_astring(str, identifier);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append_c(str, ' ');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_append(str, "\"\" l r w s t p i e k x a c d");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_line(cmd->client, str_c(str));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "OK Listrights completed.");
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic int
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenimap_acl_letters_parse(const char *letters, const char *const **rights_r,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen static const char *acl_k = MAIL_ACL_CREATE;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen static const char *acl_x = MAIL_ACL_DELETE;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen static const char *acl_e = MAIL_ACL_EXPUNGE;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen static const char *acl_t = MAIL_ACL_WRITE_DELETED;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ARRAY_TYPE(const_string) rights;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen unsigned int i;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen t_array_init(&rights, 64);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen for (; *letters != '\0'; letters++) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen for (i = 0; imap_acl_letter_map[i].name != NULL; i++) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (imap_acl_letter_map[i].letter == *letters) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen array_append(&rights,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen &imap_acl_letter_map[i].name, 1);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (imap_acl_letter_map[i].name == NULL) {
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen /* Handling of obsolete rights as virtual
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen rights according to RFC 4314 */
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen switch (*letters) {
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen case 'c':
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen array_append(&rights, &acl_k, 1);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen array_append(&rights, &acl_x, 1);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen break;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen case 'd':
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen array_append(&rights, &acl_e, 1);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen array_append(&rights, &acl_t, 1);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen break;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen default:
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen *error_r = t_strdup_printf(
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen "Invalid ACL right: %c", *letters);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen return -1;
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&rights);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *rights_r = array_idx(&rights, 0);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return 0;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenstatic bool acl_anyone_allow(struct mail_user *user)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char *env;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen env = mail_user_plugin_getenv(user, "acl_anyone");
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return env != NULL && strcmp(env, "allow") == 0;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen}
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic int
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainenimap_acl_identifier_parse(struct client_command_context *cmd,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char *id, struct acl_rights *rights,
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen bool check_anyone, const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen struct mail_user *user = cmd->client->user;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen if (strncmp(id, IMAP_ACL_GLOBAL_PREFIX,
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen strlen(IMAP_ACL_GLOBAL_PREFIX)) == 0) {
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen *error_r = t_strdup_printf("Global ACLs can't be modified: %s",
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen id);
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen return -1;
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen }
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen if (strcmp(id, IMAP_ACL_ANYONE) == 0) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (check_anyone && !acl_anyone_allow(user)) {
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen *error_r = "'anyone' identifier is disallowed";
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen return -1;
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_ANYONE;
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen } else if (strcmp(id, IMAP_ACL_AUTHENTICATED) == 0) {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (check_anyone && !acl_anyone_allow(user)) {
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen *error_r = "'authenticated' identifier is disallowed";
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen return -1;
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_AUTHENTICATED;
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen } else if (strcmp(id, IMAP_ACL_OWNER) == 0)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_OWNER;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen else if (strncmp(id, IMAP_ACL_GROUP_PREFIX,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen strlen(IMAP_ACL_GROUP_PREFIX)) == 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_GROUP;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->identifier = id + strlen(IMAP_ACL_GROUP_PREFIX);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if (strncmp(id, IMAP_ACL_GROUP_OVERRIDE_PREFIX,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen strlen(IMAP_ACL_GROUP_OVERRIDE_PREFIX)) == 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_GROUP_OVERRIDE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->identifier = id +
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen strlen(IMAP_ACL_GROUP_OVERRIDE_PREFIX);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->id_type = ACL_ID_USER;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights->identifier = id;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return 0;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainenstatic void imap_acl_update_ensure_keep_admins(struct acl_backend *backend,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_object *aclobj,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_rights_update *update)
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen{
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen static const char *acl_admin = MAIL_ACL_ADMIN;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen const char *const *rights = update->rights.rights;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen const char *const *default_rights;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen ARRAY_TYPE(const_string) new_rights;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen unsigned int i;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen t_array_init(&new_rights, 64);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen for (i = 0; rights[i] != NULL; i++) {
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (strcmp(rights[i], MAIL_ACL_ADMIN) == 0)
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen break;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen array_append(&new_rights, &rights[i], 1);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen }
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen switch (update->modify_mode) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen case ACL_MODIFY_MODE_ADD:
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (have_positive_owner_rights(backend, aclobj))
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen return;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen /* adding initial rights for a user. we need to add
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen the defaults also. don't worry about duplicates. */
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen for (; rights[i] != NULL; i++)
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen array_append(&new_rights, &rights[i], 1);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen default_rights = acl_object_get_default_rights(aclobj);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen for (i = 0; default_rights[i] != NULL; i++)
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen array_append(&new_rights, &default_rights[i], 1);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen break;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen case ACL_MODIFY_MODE_REMOVE:
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (rights[i] == NULL)
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen return;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen /* skip over the ADMIN removal and add the rest */
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen for (i++; rights[i] != NULL; i++)
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen array_append(&new_rights, &rights[i], 1);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen break;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen case ACL_MODIFY_MODE_REPLACE:
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (rights[i] != NULL)
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen return;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen /* add the missing ADMIN right */
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen array_append(&new_rights, &acl_admin, 1);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen break;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen default:
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen return;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen }
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&new_rights);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen update->rights.rights = array_idx(&new_rights, 0);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen}
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic int
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainencmd_acl_mailbox_update(struct mailbox *box,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen const struct acl_rights_update *update,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen const char **error_r)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen{
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen struct mailbox_transaction_context *t;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen int ret;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (mailbox_open(box) < 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen *error_r = mailbox_get_last_error(box, NULL);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return -1;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen }
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi __func__);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen ret = acl_mailbox_update_acl(t, update);
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (mailbox_transaction_commit(&t) < 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen ret = -1;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen *error_r = MAIL_ERRSTR_CRITICAL_MSG;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen return ret;
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen}
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool cmd_setacl(struct client_command_context *cmd)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen struct mail_namespace *ns;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen struct acl_backend *backend;
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen struct acl_object *aclobj;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct acl_rights_update update;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen struct acl_rights *r;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *mailbox, *identifier, *rights, *error;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen bool negative = FALSE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (!client_read_string_args(cmd, 3, &mailbox, &identifier, &rights))
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen return FALSE;
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (*identifier == '\0') {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (*identifier == '-') {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen negative = TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen identifier++;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen switch (*rights) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case '-':
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_REMOVE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights++;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen case '+':
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_ADD;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rights++;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen default:
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_REPLACE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen break;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (imap_acl_identifier_parse(cmd, identifier, &update.rights,
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen TRUE, &error) < 0) {
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen client_send_command_error(cmd, error);
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen return TRUE;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen }
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen if (imap_acl_letters_parse(rights, &update.rights.rights, &error) < 0) {
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen client_send_command_error(cmd, error);
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen return TRUE;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen }
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen r = &update.rights;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen if (box == NULL)
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen return TRUE;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen ns = mailbox_get_namespace(box);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen backend = acl_mailbox_list_get_backend(ns->list);
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen if (ns->type == MAIL_NAMESPACE_TYPE_PUBLIC &&
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen r->id_type == ACL_ID_OWNER) {
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen client_send_tagline(cmd, "NO Public namespaces have no owner");
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen return TRUE;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen }
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen aclobj = acl_mailbox_get_aclobj(box);
411f318ed3a25fa66c1b932e10df43841e2725c9Timo Sirainen if (negative) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.neg_modify_mode = update.modify_mode;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_REMOVE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.rights.neg_rights = update.rights.rights;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.rights.rights = NULL;
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen } else if (ns->type == MAIL_NAMESPACE_TYPE_PRIVATE &&
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen r->rights != NULL &&
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen ((r->id_type == ACL_ID_USER &&
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen acl_backend_user_name_equals(backend, r->identifier)) ||
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen (r->id_type == ACL_ID_OWNER &&
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen strcmp(acl_backend_get_acl_username(backend),
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen ns->user->username) == 0))) {
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen /* make sure client doesn't (accidentally) remove admin
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen privileges from its own mailboxes */
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen imap_acl_update_ensure_keep_admins(backend, aclobj, &update);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (cmd_acl_mailbox_update(box, &update, &error) < 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen client_send_tagline(cmd, t_strdup_printf("NO %s", error));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen else
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "OK Setacl complete.");
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool cmd_deleteacl(struct client_command_context *cmd)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mailbox *box;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct acl_rights_update update;
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen const char *mailbox, *identifier, *error;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (!client_read_string_args(cmd, 2, &mailbox, &identifier))
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen return FALSE;
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen if (*identifier == '\0') {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (*identifier != '-')
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_CLEAR;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen else {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen update.neg_modify_mode = ACL_MODIFY_MODE_CLEAR;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen identifier++;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (imap_acl_identifier_parse(cmd, identifier, &update.rights,
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen FALSE, &error) < 0) {
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen client_send_command_error(cmd, error);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen }
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (box == NULL)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (cmd_acl_mailbox_update(box, &update, &error) < 0)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen client_send_tagline(cmd, t_strdup_printf("NO %s", error));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen else
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen client_send_tagline(cmd, "OK Deleteacl complete.");
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen return TRUE;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void imap_acl_client_created(struct client **client)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
2c719bcb92302f45df4badb71d1d97f57235d0ccTimo Sirainen if (mail_user_is_plugin_loaded((*client)->user, imap_acl_module)) {
2c719bcb92302f45df4badb71d1d97f57235d0ccTimo Sirainen client_add_capability(*client, "ACL");
2c719bcb92302f45df4badb71d1d97f57235d0ccTimo Sirainen client_add_capability(*client, "RIGHTS=texk");
2c719bcb92302f45df4badb71d1d97f57235d0ccTimo Sirainen }
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (next_hook_client_created != NULL)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen next_hook_client_created(client);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainenvoid imap_acl_plugin_init(struct module *module)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_register("LISTRIGHTS", cmd_listrights, 0);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_register("GETACL", cmd_getacl, 0);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_register("MYRIGHTS", cmd_myrights, 0);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_register("SETACL", cmd_setacl, 0);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_register("DELETEACL", cmd_deleteacl, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainen imap_acl_module = module;
ac0fed903142d28ae3a1d5d00d2097fdf161b138Timo Sirainen next_hook_client_created =
ac0fed903142d28ae3a1d5d00d2097fdf161b138Timo Sirainen imap_client_created_hook_set(imap_acl_client_created);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenvoid imap_acl_plugin_deinit(void)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen{
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_unregister("GETACL");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_unregister("MYRIGHTS");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_unregister("SETACL");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_unregister("DELETEACL");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen command_unregister("LISTRIGHTS");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen imap_client_created_hook_set(next_hook_client_created);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen}
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainen
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainenconst char *imap_acl_plugin_dependencies[] = { "acl", NULL };
8552b0cad8ffe9ccb8270577ba28b8010c89af11Timo Sirainenconst char imap_acl_plugin_binary_dependency[] = "imap";