imap-acl-plugin.c revision e1203014de25c8c3d3975a9f4b4a04616df4bba2
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "common.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-quote.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-resp-code.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "commands.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-storage.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "mail-namespace.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "acl-api.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "acl-storage.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "imap-acl-plugin.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include <stdlib.h>
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define ERROR_NOT_ADMIN "["IMAP_RESP_CODE_ACL"] " \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen "You lack administrator privileges on this mailbox."
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define ACL_MAILBOX_OPEN_FLAGS \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen (MAILBOX_OPEN_READONLY | MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define IMAP_ACL_ANYONE "anyone"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IMAP_ACL_AUTHENTICATED "authenticated"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IMAP_ACL_OWNER "owner"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define IMAP_ACL_GROUP_PREFIX "$"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IMAP_ACL_GROUP_OVERRIDE_PREFIX "!$"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IMAP_ACL_GLOBAL_PREFIX "#"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct imap_acl_letter_map {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char letter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *name;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic const struct imap_acl_letter_map imap_acl_letter_map[] = {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen { 'l', MAIL_ACL_LOOKUP },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'r', MAIL_ACL_READ },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'w', MAIL_ACL_WRITE },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 's', MAIL_ACL_WRITE_SEEN },
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen { 't', MAIL_ACL_WRITE_DELETED },
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen { 'i', MAIL_ACL_INSERT },
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen { 'e', MAIL_ACL_EXPUNGE },
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen { 'k', MAIL_ACL_CREATE },
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen { 'x', MAIL_ACL_DELETE },
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen { 'a', MAIL_ACL_ADMIN },
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen { '\0', NULL }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool acl_anyone_allow = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct mailbox *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenacl_mailbox_open_as_admin(struct client_command_context *cmd, const char *name)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_storage *storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen int ret;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen storage = client_find_storage(cmd, &name);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (storage == NULL)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return NULL;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen /* Force opening the mailbox so that we can give a nicer error message
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen if mailbox isn't selectable but is listable. */
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen box = mailbox_open(storage, name, NULL, ACL_MAILBOX_OPEN_FLAGS |
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen MAIL_STORAGE_FLAG_IGNORE_ACLS);
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen if (box == NULL) {
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen client_send_storage_error(cmd, storage);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_ADMIN);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return box;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen /* not an administrator. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_LOOKUP) <= 0) {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen client_send_tagline(cmd, t_strdup_printf(
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "NO ["IMAP_RESP_CODE_NONEXISTENT"] "
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_ERRSTR_MAILBOX_NOT_FOUND, name));
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "NO "ERROR_NOT_ADMIN);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mailbox_close(&box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic const struct imap_acl_letter_map *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimap_acl_letter_map_find(const char *name)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; imap_acl_letter_map[i].name != NULL; i++) {
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen if (strcmp(imap_acl_letter_map[i].name, name) == 0)
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen return &imap_acl_letter_map[i];
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimap_acl_write_rights_list(string_t *dest, const char *const *rights)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct imap_acl_letter_map *map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool append_c = FALSE, append_d = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; rights[i] != NULL; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* write only letters */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map = imap_acl_letter_map_find(rights[i]);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (map != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(dest, map->letter);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (map->letter == 'k' || map->letter == 'x')
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen append_c = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (map->letter == 't' || map->letter == 'e')
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen append_d = TRUE;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (append_c)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append_c(dest, 'c');
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (append_d)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append_c(dest, 'd');
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstatic void
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenimap_acl_write_right(string_t *dest, string_t *tmp,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const struct acl_rights *right, bool neg)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *const *rights = neg ? right->neg_rights : right->rights;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (neg) str_append_c(dest,'-');
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_truncate(tmp, 0);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (right->global)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, IMAP_ACL_GLOBAL_PREFIX);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen switch (right->id_type) {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_ANYONE:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, IMAP_ACL_ANYONE);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_AUTHENTICATED:
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen str_append(tmp, IMAP_ACL_AUTHENTICATED);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_OWNER:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, IMAP_ACL_OWNER);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_USER:
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen str_append(tmp, right->identifier);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_GROUP:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, IMAP_ACL_GROUP_PREFIX);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, right->identifier);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen case ACL_ID_GROUP_OVERRIDE:
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, IMAP_ACL_GROUP_OVERRIDE_PREFIX);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen str_append(tmp, right->identifier);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen break;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen case ACL_ID_TYPE_COUNT:
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_unreached();
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen imap_quote_append(dest, str_data(tmp), str_len(tmp), FALSE);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen str_append_c(dest, ' ');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_acl_write_rights_list(dest, rights);
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen}
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenstatic int imap_acl_write_aclobj(string_t *dest, struct acl_object *aclobj)
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen{
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen struct acl_object_list_iter *iter;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen struct acl_rights rights;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen string_t *tmp;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen int ret;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen tmp = t_str_new(128);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen iter = acl_object_list_init(aclobj);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen while ((ret = acl_object_list_next(iter, &rights)) > 0) {
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen str_append_c(dest, ' ');
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen if (rights.rights != NULL)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen imap_acl_write_right(dest, tmp, &rights, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (rights.neg_rights != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_acl_write_right(dest, tmp, &rights, TRUE);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen acl_object_list_deinit(&iter);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainenstatic bool cmd_getacl(struct client_command_context *cmd)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *mailbox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen string_t *str;
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen unsigned int len;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (!client_read_string_args(cmd, 1, &mailbox)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (box == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str = t_str_new(128);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "* ACL ");
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen imap_quote_append_string(str, mailbox, FALSE);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen len = str_len(str);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = imap_acl_write_aclobj(str, acl_mailbox_get_aclobj(box));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_line(cmd->client, str_c(str));
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen client_send_tagline(cmd, "OK Getacl completed.");
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen } else {
5529671faac3c5672a948be93091056736c7afffTimo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
5529671faac3c5672a948be93091056736c7afffTimo Sirainen }
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen mailbox_close(&box);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen return TRUE;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainenstatic bool cmd_myrights(struct client_command_context *cmd)
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen{
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen struct mail_storage *storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen const char *mailbox, *real_mailbox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *rights;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen string_t *str;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (!client_read_string_args(cmd, 1, &mailbox)) {
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen return TRUE;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen real_mailbox = mailbox;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen storage = client_find_storage(cmd, &real_mailbox);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen if (storage == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen box = mailbox_open(storage, real_mailbox, NULL, ACL_MAILBOX_OPEN_FLAGS |
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen MAIL_STORAGE_FLAG_IGNORE_ACLS);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (box == NULL) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client_send_storage_error(cmd, storage);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (acl_object_get_my_rights(acl_mailbox_get_aclobj(box),
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen pool_datastack_create(), &rights) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mailbox_close(&box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (*rights == NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, t_strdup_printf(
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "NO ["IMAP_RESP_CODE_NONEXISTENT"] "
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen MAIL_ERRSTR_MAILBOX_NOT_FOUND, real_mailbox));
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen mailbox_close(&box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen str = t_str_new(128);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen str_append(str, "* MYRIGHTS ");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_quote_append_string(str, mailbox, FALSE);
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen str_append_c(str,' ');
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen imap_acl_write_rights_list(str, rights);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_line(cmd->client, str_c(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK Myrights completed.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen}
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool cmd_listrights(struct client_command_context *cmd)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *mailbox, *identifier;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen string_t *str;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!client_read_string_args(cmd, 2, &mailbox, &identifier)) {
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen client_send_command_error(cmd, "Invalid arguments.");
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen return TRUE;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen }
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (box == NULL)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen return TRUE;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str = t_str_new(128);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "* LISTRIGHTS ");
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen imap_quote_append_string(str, mailbox, FALSE);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen str_append_c(str, ' ');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen imap_quote_append_string(str, identifier, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(str, ' ');
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen str_append(str, "\"\" l r w s t p i e k x a c d");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_line(cmd->client, str_c(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_tagline(cmd, "OK Listrights completed.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstatic int
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenimap_acl_letters_parse(const char *letters, const char *const **rights_r,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ARRAY_TYPE(const_string) rights;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen t_array_init(&rights, 64);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (; *letters != '\0'; letters++) {
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen for (i = 0; imap_acl_letter_map[i].name != NULL; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (imap_acl_letter_map[i].letter == *letters) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append(&rights,
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen &imap_acl_letter_map[i].name, 1);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen break;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen if (imap_acl_letter_map[i].name == NULL) {
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen *error_r = t_strdup_printf("Invalid ACL right: %c",
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen *letters);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen return -1;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (void)array_append_space(&rights);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *rights_r = array_idx(&rights, 0);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimap_acl_identifier_parse(const char *id, struct acl_rights *rights,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool check_anyone, const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strncmp(id, IMAP_ACL_GLOBAL_PREFIX,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strlen(IMAP_ACL_GLOBAL_PREFIX)) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = t_strdup_printf("Global ACLs can't be modified: %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strcmp(id, IMAP_ACL_ANYONE) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!acl_anyone_allow && check_anyone) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen *error_r = "'anyone' identifier is disallowed";
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return -1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->id_type = ACL_ID_ANYONE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strcmp(id, IMAP_ACL_AUTHENTICATED) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!acl_anyone_allow && check_anyone) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = "'authenticated' identifier is disallowed";
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->id_type = ACL_ID_AUTHENTICATED;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strcmp(id, IMAP_ACL_OWNER) == 0)
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen rights->id_type = ACL_ID_OWNER;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (strncmp(id, IMAP_ACL_GROUP_PREFIX,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strlen(IMAP_ACL_GROUP_PREFIX)) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->id_type = ACL_ID_GROUP;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->identifier = id + strlen(IMAP_ACL_GROUP_PREFIX);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strncmp(id, IMAP_ACL_GROUP_OVERRIDE_PREFIX,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strlen(IMAP_ACL_GROUP_OVERRIDE_PREFIX)) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->id_type = ACL_ID_GROUP_OVERRIDE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->identifier = id +
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strlen(IMAP_ACL_GROUP_OVERRIDE_PREFIX);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->id_type = ACL_ID_USER;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rights->identifier = id;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic bool cmd_setacl(struct client_command_context *cmd)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct acl_rights_update update;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *mailbox, *identifier, *rights, *error;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen bool negative = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!client_read_string_args(cmd, 3, &mailbox, &identifier, &rights) ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *identifier == '\0' || *rights == '\0') {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(&update, 0, sizeof(update));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (*identifier == '-') {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen negative = TRUE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen identifier++;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (imap_acl_identifier_parse(identifier, &update.rights,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen TRUE, &error) < 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen client_send_command_error(cmd, error);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return TRUE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (imap_acl_letters_parse(rights, &update.rights.rights, &error) < 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen client_send_command_error(cmd, error);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return TRUE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (box == NULL)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return TRUE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen switch (*rights) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen case '-':
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_REMOVE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen rights++;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen break;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen case '+':
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen update.modify_mode = ACL_MODIFY_MODE_ADD;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen rights++;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen break;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen default:
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen update.modify_mode = ACL_MODIFY_MODE_REPLACE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen break;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (negative) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen update.neg_modify_mode = update.modify_mode;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen update.modify_mode = ACL_MODIFY_MODE_REMOVE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen update.rights.neg_rights = update.rights.rights;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen update.rights.rights = NULL;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (acl_object_update(acl_mailbox_get_aclobj(box), &update) < 0)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen else
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen client_send_tagline(cmd, "OK Setacl complete.");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen mailbox_close(&box);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen return TRUE;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic bool cmd_deleteacl(struct client_command_context *cmd)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mailbox *box;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct acl_rights_update update;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *mailbox, *identifier, *error;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (!client_read_string_args(cmd, 2, &mailbox, &identifier) ||
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen *identifier == '\0') {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client_send_command_error(cmd, "Invalid arguments.");
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return TRUE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen memset(&update, 0, sizeof(update));
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (*identifier != '-')
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen update.modify_mode = ACL_MODIFY_MODE_CLEAR;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen else {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen update.neg_modify_mode = ACL_MODIFY_MODE_CLEAR;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen identifier++;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (imap_acl_identifier_parse(identifier, &update.rights,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen FALSE, &error) < 0) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client_send_command_error(cmd, error);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return TRUE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen box = acl_mailbox_open_as_admin(cmd, mailbox);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (box == NULL)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return TRUE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (acl_object_update(acl_mailbox_get_aclobj(box), &update) < 0)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client_send_tagline(cmd, "NO "MAIL_ERRSTR_CRITICAL_MSG);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen else
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen client_send_tagline(cmd, "OK Deleteacl complete.");
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mailbox_close(&box);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return TRUE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenvoid imap_acl_plugin_init(void)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen{
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen const char *env;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (getenv("ACL") == NULL)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen return;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen env = getenv("ACL_ANYONE");
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (env != NULL)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen acl_anyone_allow = strcmp(env, "allow") == 0;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen str_append(capability_string, " ACL RIGHTS=texk");
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen command_register("LISTRIGHTS", cmd_listrights, 0);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen command_register("GETACL", cmd_getacl, 0);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen command_register("MYRIGHTS", cmd_myrights, 0);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen command_register("SETACL", cmd_setacl, 0);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen command_register("DELETEACL", cmd_deleteacl, 0);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid imap_acl_plugin_deinit(void)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen command_unregister("GETACL");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen command_unregister("MYRIGHTS");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen command_unregister("SETACL");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen command_unregister("DELETEACL");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen command_unregister("LISTRIGHTS");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen