]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm: allow access to server attributes via empty mailbox name
authorJosef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
Tue, 13 Sep 2016 11:50:04 +0000 (07:50 -0400)
committerJosef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
Mon, 26 Sep 2016 12:12:19 +0000 (08:12 -0400)
src/doveadm/doveadm-mail-mailbox-metadata.c
src/doveadm/doveadm-mail.c
src/doveadm/doveadm-mail.h

index a8ddab6328e7c9859b2dd8988aacbb32ff22cc9f..f818dce9980f73a6170514df83774e1feb7aeb30 100644 (file)
@@ -24,10 +24,33 @@ cmd_mailbox_metadata_set_run(struct doveadm_mail_cmd_context *_ctx,
        struct mail_namespace *ns;
        struct mailbox *box;
        struct mailbox_transaction_context *trans;
+       bool empty_mailbox_name;
+       const char *key;
        int ret;
 
-       ns = mail_namespace_find(user->namespaces, ctx->mailbox);
-       box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+       empty_mailbox_name = (ctx->mailbox[0] == '\0');
+
+       if (empty_mailbox_name) {
+               if (!_ctx->allow_empty_mailbox_name) {
+                       i_error("Failed to set attribute: %s",
+                               "mailbox name cannot be empty");
+                       _ctx->exit_code = EX_USAGE;
+                       return -1;
+               }
+
+               /* server attribute */
+               ns = mail_namespace_find_inbox(user->namespaces);
+               box = mailbox_alloc(ns->list, "INBOX", 0);
+
+               key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER,
+                                 ctx->key);
+       } else {
+               /* mailbox attributes */
+               ns = mail_namespace_find(user->namespaces, ctx->mailbox);
+               box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+
+               key = ctx->key;
+       }
 
        if (mailbox_open(box) < 0) {
                i_error("Failed to open mailbox: %s",
@@ -36,11 +59,12 @@ cmd_mailbox_metadata_set_run(struct doveadm_mail_cmd_context *_ctx,
                mailbox_free(&box);
                return -1;
        }
-       trans = mailbox_transaction_begin(box, 0);
+       trans = mailbox_transaction_begin(box, empty_mailbox_name ?
+                                         MAILBOX_TRANSACTION_FLAG_EXTERNAL : 0);
 
        ret = ctx->value.value == NULL ?
-               mailbox_attribute_unset(trans, ctx->key_type, ctx->key) :
-               mailbox_attribute_set(trans, ctx->key_type, ctx->key, &ctx->value);
+               mailbox_attribute_unset(trans, ctx->key_type, key) :
+               mailbox_attribute_set(trans, ctx->key_type, key, &ctx->value);
        if (ret < 0) {
                i_error("Failed to set attribute: %s",
                        mailbox_get_last_error(box, NULL));
@@ -142,10 +166,30 @@ cmd_mailbox_metadata_get_run(struct doveadm_mail_cmd_context *_ctx,
        struct mailbox *box;
        struct mailbox_transaction_context *trans;
        struct mail_attribute_value value;
+       const char *key;
        int ret;
 
-       ns = mail_namespace_find(user->namespaces, ctx->mailbox);
-       box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+       if (ctx->mailbox[0] == '\0') {
+               if (!_ctx->allow_empty_mailbox_name) {
+                       i_error("Failed to get attribute: %s",
+                               "mailbox name cannot be empty");
+                       _ctx->exit_code = EX_USAGE;
+                       return -1;
+               }
+
+               /* server attribute */
+               ns = mail_namespace_find_inbox(user->namespaces);
+               box = mailbox_alloc(ns->list, "INBOX", 0);
+
+               key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER,
+                                 ctx->key);
+       } else {
+               /* mailbox attribute */
+               ns = mail_namespace_find(user->namespaces, ctx->mailbox);
+               box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+
+               key = ctx->key;
+       }
 
        if (mailbox_open(box) < 0) {
                i_error("Failed to open mailbox: %s",
@@ -156,7 +200,7 @@ cmd_mailbox_metadata_get_run(struct doveadm_mail_cmd_context *_ctx,
        }
        trans = mailbox_transaction_begin(box, 0);
 
-       ret = mailbox_attribute_get_stream(trans, ctx->key_type, ctx->key, &value);
+       ret = mailbox_attribute_get_stream(trans, ctx->key_type, key, &value);
        if (ret < 0) {
                i_error("Failed to get attribute: %s",
                        mailbox_get_last_error(box, NULL));
@@ -232,8 +276,25 @@ cmd_mailbox_metadata_list_run(struct doveadm_mail_cmd_context *_ctx,
        struct mailbox *box;
        int ret = 0;
 
-       ns = mail_namespace_find(user->namespaces, ctx->mailbox);
-       box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+       if (ctx->mailbox[0] == '\0') {
+               if (!_ctx->allow_empty_mailbox_name) {
+                       i_error("Failed to list attributes: %s",
+                               "mailbox name cannot be empty");
+                       _ctx->exit_code = EX_USAGE;
+                       return -1;
+               }
+
+               /* server attribute */
+               ns = mail_namespace_find_inbox(user->namespaces);
+               box = mailbox_alloc(ns->list, "INBOX", 0);
+
+               ctx->key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER,
+                                      ctx->key);
+       } else {
+               /* mailbox attribute */
+               ns = mail_namespace_find(user->namespaces, ctx->mailbox);
+               box = mailbox_alloc(ns->list, ctx->mailbox, 0);
+       }
 
        if (mailbox_open(box) < 0) {
                i_error("Failed to open mailbox: %s",
@@ -290,9 +351,10 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_metadata_list_alloc(void)
 struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_set_ver2 = {
        .name = "mailbox metadata set",
        .mail_cmd = cmd_mailbox_metadata_set_alloc,
-       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<mailbox> <key> <value>",
+       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key> <value>",
 DOVEADM_CMD_PARAMS_START
 DOVEADM_CMD_MAIL_COMMON
+DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
 DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAM('\0', "value", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
@@ -302,9 +364,10 @@ DOVEADM_CMD_PARAMS_END
 struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_unset_ver2 = {
        .name = "mailbox metadata unset",
        .mail_cmd = cmd_mailbox_metadata_unset_alloc,
-       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<mailbox> <key>",
+       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key>",
 DOVEADM_CMD_PARAMS_START
 DOVEADM_CMD_MAIL_COMMON
+DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
 DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAMS_END
@@ -313,9 +376,10 @@ DOVEADM_CMD_PARAMS_END
 struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_get_ver2 = {
        .name = "mailbox metadata get",
        .mail_cmd = cmd_mailbox_metadata_get_alloc,
-       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<mailbox> <key>",
+       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> <key>",
 DOVEADM_CMD_PARAMS_START
 DOVEADM_CMD_MAIL_COMMON
+DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
 DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAM('\0', "key", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAMS_END
@@ -324,9 +388,10 @@ DOVEADM_CMD_PARAMS_END
 struct doveadm_cmd_ver2 doveadm_cmd_mailbox_metadata_list_ver2 = {
        .name = "mailbox metadata list",
        .mail_cmd = cmd_mailbox_metadata_list_alloc,
-       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"<mailbox> [<key prefix>]",
+       .usage = DOVEADM_CMD_MAIL_USAGE_PREFIX"[-s] <mailbox> [<key prefix>]",
 DOVEADM_CMD_PARAMS_START
 DOVEADM_CMD_MAIL_COMMON
+DOVEADM_CMD_PARAM('s', "allow-empty-mailbox-name", CMD_PARAM_BOOL, 0)
 DOVEADM_CMD_PARAM('\0', "mailbox", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAM('\0', "key-prefix", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
 DOVEADM_CMD_PARAMS_END
index 11a213b236309dc2e522b5ee981c6bacce53a86b..565967d1ceff9d07de62c506928220b22b415774 100644 (file)
@@ -1013,6 +1013,10 @@ doveadm_cmd_ver2_to_mail_cmd_wrapper(struct doveadm_cmd_context *cctx)
                        }
                        mctx->cmd_input = arg->value.v_istream;
                        i_stream_ref(mctx->cmd_input);
+               } else if (strcmp(arg->name, "allow-empty-mailbox-name") == 0) {
+                       /* allow an empty mailbox name - to access server
+                          attributes */
+                       mctx->allow_empty_mailbox_name = arg->value.v_bool;
 
                /* Keep all named special parameters above this line */
 
index a15c8fa4605235dd66bf59c9b3cd233c2293946b..fd9e26d989d47df63151d4ed0a48b5f40b8b3991 100644 (file)
@@ -101,6 +101,9 @@ struct doveadm_mail_cmd_context {
        unsigned int add_username_header:1;
        /* Running from CLI doveadm (not doveadm-server) */
        unsigned int cli:1;
+
+       /* Allow empty mailbox name - to allow access to server attributes */
+       unsigned int allow_empty_mailbox_name:1;
 };
 
 struct doveadm_mail_cmd {