Projects
Kolab:3.4
cyrus-imapd
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 71
View file
cyrus-imapd.spec
Changed
@@ -38,7 +38,7 @@ Name: cyrus-imapd Summary: A high-performance mail server with IMAP, POP3, NNTP and SIEVE support Version: 2.5 -Release: 0.1.dev20140724%{?dist} +Release: 0.1.dev%(date +%Y%m%d)%{?dist} License: BSD Group: System Environment/Daemons URL: http://www.cyrusimap.org @@ -66,7 +66,7 @@ ## Patches ## -Patch9999: cyrus-imapd-mupdate-work.patch +Patch0001: cyrus-imapd-2.5-default-twoskip.patch BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) @@ -250,7 +250,7 @@ %prep %setup -q -n %{_name}-%{real_version}%{?dot_snapshot_version} -#%patch9999 -p1 +#%patch0001 -p1 # only to update config.* files aclocal -I cmulocal
View file
cyrus-imapd-2.5-default-twoskip.patch
Added
@@ -0,0 +1,80 @@ +diff --git a/lib/imapoptions b/lib/imapoptions +index 2c477a6..78c5f46 100644 +--- a/lib/imapoptions ++++ b/lib/imapoptions +@@ -163,7 +163,7 @@ are listed with ``<none>''. + affect LMTP delivery of messages directly to mailboxes via + plus-addressing. */ + +-{ "annotation_db", "skiplist", STRINGLIST("berkeley", "berkeley-hash", "skiplist", "twoskip")} ++{ "annotation_db", "twoskip", STRINGLIST("berkeley", "berkeley-hash", "skiplist", "twoskip")} + /* The cyrusdb backend to use for mailbox annotations. */ + + { "annotation_db_path", NULL, STRING } +@@ -413,7 +413,7 @@ Blank lines and lines beginning with ``#'' are ignored. + session. Otherwise, the missing mailbox is treated as empty while + in use by the client.*/ + +-{ "duplicate_db", "skiplist", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip")} ++{ "duplicate_db", "twoskip", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip")} + /* The cyrusdb backend to use for the duplicate delivery suppression + and sieve. */ + +@@ -841,10 +841,10 @@ Blank lines and lines beginning with ``#'' are ignored. + { "maxword", 131072, INT } + /* Maximum size of a single word for the parser. Default 128k */ + +-{ "mboxkey_db", "skiplist", STRINGLIST("berkeley", "skiplist", "twoskip") } ++{ "mboxkey_db", "twoskip", STRINGLIST("berkeley", "skiplist", "twoskip") } + /* The cyrusdb backend to use for mailbox keys. */ + +-{ "mboxlist_db", "skiplist", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "sql", "twoskip")} ++{ "mboxlist_db", "twoskip", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "sql", "twoskip")} + /* The cyrusdb backend to use for the mailbox list. */ + + { "mboxlist_db_path", NULL, STRING } +@@ -1163,7 +1163,7 @@ And the notification message will be available on \fIstdin\fR. + /* Unix domain socket that ptloader listens on. + (defaults to configdir/ptclient/ptsock) */ + +-{ "ptscache_db", "skiplist", STRINGLIST("berkeley", "berkeley-hash", "skiplist", "twoskip")} ++{ "ptscache_db", "twoskip", STRINGLIST("berkeley", "berkeley-hash", "skiplist", "twoskip")} + /* The cyrusdb backend to use for the pts cache. */ + + { "ptscache_db_path", NULL, STRING } +@@ -1188,7 +1188,7 @@ And the notification message will be available on \fIstdin\fR. + /* This specifies the Class Selector or Differentiated Services Code Point + designation on IP headers (in the ToS field). */ + +-{ "quota_db", "quotalegacy", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "sql", "quotalegacy", "twoskip")} ++{ "quota_db", "twoskip", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "sql", "quotalegacy", "twoskip")} + /* The cyrusdb backend to use for quotas. */ + + { "quota_db_path", NULL, STRING } +@@ -1269,7 +1269,7 @@ And the notification message will be available on \fIstdin\fR. + recommended for most cases - it's a good compromise which + keeps words separate. */ + +-{ "seenstate_db", "skiplist", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "twoskip")} ++{ "seenstate_db", "twoskip", STRINGLIST("flat", "berkeley", "berkeley-hash", "skiplist", "twoskip")} + /* The cyrusdb backend to use for the seen state. */ + + { "sendmail", "/usr/lib/sendmail", STRING } +@@ -1440,7 +1440,7 @@ product version in the capabilities */ + { "statuscache", 0, SWITCH } + /* Enable/disable the imap status cache. */ + +-{ "statuscache_db", "skiplist", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip") } ++{ "statuscache_db", "twoskip", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip") } + /* The cyrusdb backend to use for the imap status cache. */ + + { "statuscache_db_path", NULL, STRING } +@@ -1545,7 +1545,7 @@ product version in the capabilities */ + have filenames with the hashed value of the certificates (see + openssl(XXX)). */ + +-{ "tlscache_db", "skiplist", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip")} ++{ "tlscache_db", "twoskip", STRINGLIST("berkeley", "berkeley-nosync", "berkeley-hash", "berkeley-hash-nosync", "skiplist", "sql", "twoskip")} + /* The cyrusdb backend to use for the TLS cache. */ + + { "tlscache_db_path", NULL, STRING }
View file
cyrus-imapd-mupdate-work.patch
Deleted
@@ -1,1319 +0,0 @@ -diff --git a/imap/annotate.c b/imap/annotate.c -index 2dbac7a..a5c3a6d 100644 ---- a/imap/annotate.c -+++ b/imap/annotate.c -@@ -1183,6 +1183,7 @@ static int annotate_state_set_scope(annotate_state_t *state, - annotate_state_unset_scope(state); - - if (mbentry) { -+ assert(!uid); - if (!mailbox && !mbentry->server) { - /* local mailbox */ - r = mailbox_open_iwl(mbentry->name, &mailbox); -@@ -1190,11 +1191,21 @@ static int annotate_state_set_scope(annotate_state_t *state, - goto out; - state->mailbox_is_ours = 1; - } -- assert(mailbox); -+ -+ if (mailbox) { -+ syslog(LOG_DEBUG, "mailbox: %s (%s:%d)", mailbox->name, __FILE__, __LINE__); -+ } -+ -+ if (mbentry) { -+ syslog(LOG_DEBUG, "%s mbentry->server: %s (%s:%d)", mbentry->name, mbentry->server, __FILE__, __LINE__); -+ syslog(LOG_DEBUG, "%s mbentry->partition: %s (%s:%d)", mbentry->name, mbentry->partition, __FILE__, __LINE__); -+ } -+ -+ state->which = ANNOTATION_SCOPE_MAILBOX; - state->mbentry = mbentry; - } - -- if (uid) { -+ else if (uid) { - assert(mailbox); - state->which = ANNOTATION_SCOPE_MESSAGE; - } -@@ -1209,6 +1220,7 @@ static int annotate_state_set_scope(annotate_state_t *state, - } - assert(oldwhich == ANNOTATION_SCOPE_UNKNOWN || - oldwhich == state->which); -+ - state->mailbox = mailbox; - state->uid = uid; - -@@ -1431,6 +1443,8 @@ static void annotation_get_freespace(annotate_state_t *state, - static void annotation_get_server(annotate_state_t *state, - struct annotate_entry_list *entry) - { -+ syslog(LOG_DEBUG, "%s (%s:%d)", __func__, __FILE__, __LINE__); -+ - struct buf value = BUF_INITIALIZER; - int r; - -@@ -2024,14 +2038,20 @@ static void _annotate_fetch_entries(annotate_state_t *state, - for (ee = state->entry_list; ee; ee = ee->next) { - - if (proxy_check) { -- if (ee->desc->proxytype == BACKEND_ONLY && -- proxy_fetch_func && -- !config_getstring(IMAPOPT_PROXYSERVERS)) -+ if ( -+ ee->desc->proxytype == BACKEND_ONLY && -+ proxy_fetch_func && -+ !config_getstring(IMAPOPT_PROXYSERVERS) -+ ) { -+ syslog(LOG_DEBUG, "%s (%s:%d) backend only (skipping): %s", __func__, __FILE__, __LINE__, ee->desc->name); - continue; -+ } - } - -- if (!_annotate_may_fetch(state, ee->desc)) -+ if (!_annotate_may_fetch(state, ee->desc)) { -+ syslog(LOG_DEBUG, "%s (%s:%d) may not fetch (skipping): %s", __func__, __FILE__, __LINE__, ee->desc->name); - continue; -+ } - - ee->desc->get(state, ee); - } -@@ -2056,6 +2076,9 @@ EXPORTED int annotate_state_fetch(annotate_state_t *state, - state->sizeptr = maxsizeptr; /* pointer to push largest back */ - } - -+ syslog(LOG_DEBUG, "%s (%s:%d) entries: %s", __func__, __FILE__, __LINE__, strarray_join(entries, ",")); -+ syslog(LOG_DEBUG, "%s (%s:%d) attribs: %s", __func__, __FILE__, __LINE__, strarray_join(attribs, ",")); -+ - /* Build list of attributes to fetch */ - for (i = 0 ; i < attribs->count ; i++) - { -@@ -2091,15 +2114,20 @@ EXPORTED int annotate_state_fetch(annotate_state_t *state, - if (!state->attribs) - goto out; - -+ syslog(LOG_DEBUG, "%s (%s:%d) attribs: %s", __func__, __FILE__, __LINE__, strarray_join(attribs, ",")); -+ - if (state->which == ANNOTATION_SCOPE_SERVER) { -+ syslog(LOG_DEBUG, "%s (%s:%d) state->which == ANNOTATION_SCOPE_SERVER", __func__, __FILE__, __LINE__); - non_db_entries = &server_entries; - db_entry = &server_db_entry; - } - else if (state->which == ANNOTATION_SCOPE_MAILBOX) { -+ syslog(LOG_DEBUG, "%s (%s:%d) state->which == ANNOTATION_SCOPE_MAILBOX", __func__, __FILE__, __LINE__); - non_db_entries = &mailbox_entries; - db_entry = &mailbox_db_entry; - } - else if (state->which == ANNOTATION_SCOPE_MESSAGE) { -+ syslog(LOG_DEBUG, "%s (%s:%d) state->which == ANNOTATION_SCOPE_MESSAGE", __func__, __FILE__, __LINE__); - non_db_entries = &message_entries; - db_entry = &message_db_entry; - } -@@ -2109,6 +2137,11 @@ EXPORTED int annotate_state_fetch(annotate_state_t *state, - goto out; - } - -+ if (proxy_fetch_func) -+ syslog(LOG_DEBUG, "we have proxy_fetch_func"); -+ else -+ syslog(LOG_DEBUG, "we do not have proxy_fetch_func"); -+ - /* Build a list of callbacks for fetching the annotations */ - for (i = 0 ; i < entries->count ; i++) - { -@@ -2116,14 +2149,25 @@ EXPORTED int annotate_state_fetch(annotate_state_t *state, - int j; - int check_db = 0; /* should we check the db for this entry? */ - -+ syslog(LOG_DEBUG, "%s (%s:%d) char s: %s", __func__, __FILE__, __LINE__, s); -+ - g = glob_init(s, GLOB_HIERARCHY); - GLOB_SET_SEPARATOR(g, '/'); - - for (j = 0 ; j < non_db_entries->count ; j++) { - const annotate_entrydesc_t *desc = non_db_entries->data[j]; - -- if (!desc->get) -+ syslog(LOG_DEBUG, "%s (%s:%d) non_db_entry '%s'", __func__, __FILE__, __LINE__, desc->name); -+ -+ if (!desc->get) { -+ syslog(LOG_DEBUG, "%s (%s:%d) desc->get returns nothing for '%s'", __func__, __FILE__, __LINE__, desc->name); - continue; -+ } -+ -+ if (desc->proxytype == PROXY_ONLY) -+ syslog(LOG_DEBUG, "%s proxytype is proxy only (%s:%d)", desc->name, __FILE__, __LINE__); -+ else -+ syslog(LOG_DEBUG, "%s proxytype is NOT proxy only (%s:%d)", desc->name, __FILE__, __LINE__); - - if (GLOB_TEST(g, desc->name) != -1) { - /* Add this entry to our list only if it -@@ -2159,6 +2203,35 @@ EXPORTED int annotate_state_fetch(annotate_state_t *state, - glob_free(&g); - } - -+ struct annotate_entry_list *ee; -+ -+ for (ee = state->entry_list; ee; ee = ee->next) { -+ -+ syslog(LOG_DEBUG, "%s (%s:%d) state->entry_list: %s", __func__, __FILE__, __LINE__, ee->name); -+ -+ if ( -+ ee->desc->proxytype == BACKEND_ONLY && -+ !config_getstring(IMAPOPT_PROXYSERVERS) -+ ) { -+ -+ continue; -+ syslog(LOG_DEBUG, "%s (%s:%d) state->entry_list(backend): %s", __func__, __FILE__, __LINE__, ee->name); -+ } -+ -+ if (!_annotate_may_fetch(state, ee->desc)) { -+ syslog(LOG_DEBUG, "%s (%s:%d) may not fetch: %s", __func__, __FILE__, __LINE__, ee->name); -+ continue; -+ } -+ -+ ee->desc->get(state, ee); -+ -+ if (ee->have_shared) -+ syslog(LOG_DEBUG, "%s (%s:%d) entry shared: %s", __func__, __FILE__, __LINE__, ee->shared.s); -+ if (ee->have_priv) -+ syslog(LOG_DEBUG, "%s (%s:%d) entry private: %s", __func__, __FILE__, __LINE__, ee->priv.s); -+ } -+ -+ - if (state->which == ANNOTATION_SCOPE_SERVER) { - _annotate_fetch_entries(state, /*proxy_check*/1); - } -@@ -3313,16 +3386,22 @@ static void init_annotation_definitions(void) - ptrarray_t *entries = NULL; - - /* copy static entries into list */ -- for (i = 0 ; server_builtin_entries[i].name ; i++) -+ for (i = 0 ; server_builtin_entries[i].name ; i++) { -+ syslog(LOG_DEBUG, "appending %s to server_entries", server_builtin_entries[i].name); - ptrarray_append(&server_entries, (void *)&server_builtin_entries[i]); -+ } - - /* copy static entries into list */ -- for (i = 0 ; mailbox_builtin_entries[i].name ; i++) -+ for (i = 0 ; mailbox_builtin_entries[i].name ; i++) { -+ syslog(LOG_DEBUG, "appending %s to mailbox_entries", mailbox_builtin_entries[i].name); - ptrarray_append(&mailbox_entries, (void *)&mailbox_builtin_entries[i]); -+ } - - /* copy static entries into list */ -- for (i = 0 ; message_builtin_entries[i].name ; i++) -+ for (i = 0 ; message_builtin_entries[i].name ; i++) { -+ syslog(LOG_DEBUG, "appending %s to message_entries", message_builtin_entries[i].name); - ptrarray_append(&message_entries, (void *)&message_builtin_entries[i]); -+ } - - memset(&state, 0, sizeof(state)); - -diff --git a/imap/imap_proxy.c b/imap/imap_proxy.c -index f3154e2..88f2b93 100644 ---- a/imap/imap_proxy.c -+++ b/imap/imap_proxy.c -@@ -1345,16 +1345,19 @@ char *find_free_server(void) - be = proxy_findserver(cur_server, &imap_protocol, - proxy_userid, &backend_cached, - &backend_current, &backend_inbox, imapd_in); -+ - if (be) { - unsigned avail = 0; - int c; - - /* fetch annotation from remote */ - proxy_gentag(mytag, sizeof(mytag)); -+ - prot_printf(be->out, - "%s GETANNOTATION \"\" " - "\"/vendor/cmu/cyrus-imapd/freespace\" " - "\"value.shared\"\r\n", mytag); -+ - prot_flush(be->out); - - for (/* each annotation response */;;) { -@@ -1379,20 +1382,30 @@ char *find_free_server(void) - if (c != '\"') { c = EOF; break; } - eatline(be->in, c); /* we don't care about the rest of the line */ - } -+ - if (c != EOF) { - prot_ungetc(c, be->in); - - /* we should be looking at the tag now */ - eatline(be->in, c); - } -+ - if (c == EOF) { - /* uh oh, we're not happy */ - fatal("Lost connection to backend", EC_UNAVAILABLE); - } -+ -+ syslog(LOG_DEBUG, "Current server selected (before eval of %s): %s with %lu bytes", cur_server, server, max_avail); -+ - if (avail > max_avail) { - server = cur_server; - max_avail = avail; - } -+ -+ syslog(LOG_DEBUG, "Current server selected (after eval of %s): %s with %lu bytes", cur_server, server, max_avail); -+ -+ } else { -+ syslog(LOG_ERR, "Could not connect to %s to determine free space available", cur_server); - } - - /* move to next server */ -diff --git a/imap/imapd.c b/imap/imapd.c -index 9809981..902ad45 100644 ---- a/imap/imapd.c -+++ b/imap/imapd.c -@@ -423,7 +423,7 @@ static int parse_annotate_fetch_data(const char *tag, - strarray_t *attribs); - static int parse_metadata_string_or_list(const char *tag, - strarray_t *sa, -- int *was_singlep); -+ int *is_list); - static int parse_annotate_store_data(const char *tag, - int permessage_flag, - struct entryattlist **entryatts); -@@ -5332,7 +5332,7 @@ static void cmd_create(char *tag, char *name, struct dlist *extargs, int localon - { - int r = 0; - char mailboxname[MAX_MAILBOX_BUFFER]; -- int autocreatequotastorage; -+ //int autocreatequotastorage; - int mbtype = 0; - const char *partition = NULL; - const char *server = NULL; -@@ -5342,6 +5342,7 @@ static void cmd_create(char *tag, char *name, struct dlist *extargs, int localon - dlist_getatom(extargs, "PARTITION", &partition); - dlist_getatom(extargs, "SERVER", &server); - use = dlist_getchild(extargs, "USE"); -+ - if (use) { - struct dlist *item; - char *raw; -@@ -5350,212 +5351,331 @@ static void cmd_create(char *tag, char *name, struct dlist *extargs, int localon - * correct error. Sadly, that's a pain - so we compromise by - * "normalising" first */ - strarray_t *su = strarray_new(); -+ - for (item = use->head; item; item = item->next) { - strarray_append(su, dlist_cstring(item)); - } -+ - raw = strarray_join(su, " "); - strarray_free(su); - r = specialuse_validate(raw, &specialuse); - free(raw); -+ - if (r) { - prot_printf(imapd_out, "%s NO [USEATTR] %s\r\n", tag, error_message(r)); - goto done; - } -+ - } - -- if (partition && !imapd_userisadmin) { -- r = IMAP_PERMISSION_DENIED; -+ // A non-admin is not allowed to specify the server nor partition on which -+ // to create the mailbox. -+ if ((server || partition) && !imapd_userisadmin) { -+ prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_PERMISSION_DENIED)); -+ goto done; - } - -+ /* We don't care about trailing hierarchy delimiters. */ - if (name[0] && name[strlen(name)-1] == imapd_namespace.hier_sep) { -- /* We don't care about trailing hierarchy delimiters. */ - name[strlen(name)-1] = '\0'; - } - -- if (!r) { -- r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name, -- imapd_userid, mailboxname); -+ r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name, imapd_userid, mailboxname); -+ -+ if (r) { -+ prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -+ goto done; - } - - /* check for INBOX.INBOX creation by broken Apple clients */ -- if (!r) { -- char *copy = xstrdup(mailboxname); -- lcase(copy); -- if (strstr(copy, "inbox.inbox")) -- r = IMAP_MAILBOX_BADNAME; -- free(copy); -+ char *copy = xstrdup(mailboxname); -+ lcase(copy); -+ -+ if (strstr(copy, "inbox.inbox")) -+ r = IMAP_MAILBOX_BADNAME; -+ -+ free(copy); -+ -+ if (r) { -+ prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -+ goto done; - } - -- if (!r && !localonly && config_mupdate_server) { -- int guessedpart = 0; -+ // If the create command does not mandate the mailbox must be created -+ // locally, let's go and find the most appropriate location. -+ if (!localonly) { - -- /* determine if we're creating locally or remotely */ -- if (!partition && !server) { -- char *foundpart = NULL; -- guessedpart = 1; -- r = mboxlist_createmailboxcheck(mailboxname, 0, 0, -- imapd_userisadmin || imapd_userisproxyadmin, -- imapd_userid, imapd_authstate, -- NULL, &foundpart, 0); -- partition = foundpart; -+ // If we're running in a Murder, things get more complicated. -+ if (config_mupdate_server) { - -- if (!r && !partition && -- (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) && -- !config_getstring(IMAPOPT_PROXYSERVERS)) { -- /* proxy-only server, and no parent mailbox */ -- guessedpart = 0; -+ // Consider your actions on a per type of topology basis. -+ // -+ // First up: Standard / discrete murder topology, with dedicated -+ // imap frontends. -+ if (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) { -+ if (!config_getstring(IMAPOPT_PROXYSERVERS)) { -+ syslog(LOG_DEBUG, "I believe I am a dedicated frontend!"); - -- /* use defaultserver if specified */ -- partition = config_getstring(IMAPOPT_DEFAULTSERVER); -+ // Find the parent mailbox, if any. -+ mbentry_t *parent = NULL; - -- /* otherwise, find server with most available space */ -- if (!partition) partition = find_free_server(); -+ // mboxlist_findparent either supplies the parent -+ // or has a return code of IMAP_MAILBOX_NONEXISTENT. -+ r = mboxlist_findparent(mailboxname, &parent); - -- if (!partition) r = IMAP_SERVER_UNAVAILABLE; -- } -- } -+ if (r) { -+ if (r != IMAP_MAILBOX_NONEXISTENT) { -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); -+ goto done; -+ } else { -+ syslog(LOG_DEBUG, "OK, no parent for mailbox %s (yet)", mailboxname); -+ } -+ } - -- if (!r && !config_partitiondir(partition)) { -- /* invalid partition, assume its a server (remote mailbox) */ -- struct backend *s = NULL; -- char *p; -- int res; -- -- /* check for a remote partition */ -- server = partition; -- p = strchr(server, '!'); -- if (p) *p++ = '\0'; -- partition = guessedpart ? NULL : p; -+ if (!server && !partition) { -+ if (!parent) { -+ server = find_free_server(); - -- s = proxy_findserver(server, &imap_protocol, -- proxy_userid, &backend_cached, -- &backend_current, &backend_inbox, imapd_in); -- if (!s) r = IMAP_SERVER_UNAVAILABLE; -+ if (server) { -+ syslog(LOG_DEBUG, "server selected based on free disk space: %s", server); - -- if (!r && imapd_userisadmin && supports_referrals) { -- /* They aren't an admin remotely, so let's refer them */ -- imapd_refer(tag, server, name); -- referral_kick = 1; -- return; -- } -+ } else { -+ prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); -+ goto done; -+ } - -- if (!r) { -- if (!CAPA(s, CAPA_MUPDATE)) { -- /* reserve mailbox on MUPDATE */ -- } -- } -+ } else { -+ server = parent->server; -+ partition = parent->partition; -+ syslog(LOG_DEBUG, "using parent server/partition: %s, %s", server, partition); -+ -+/* -+ syslog(LOG_DEBUG, "starting mboxlist_entry_free(parent)"); -+ mboxlist_entry_free(parent); -+ syslog(LOG_DEBUG, "mboxlist_entry_free(parent) done"); -+*/ -+ } - -- if (!r) { -- /* ok, send the create to that server */ -- prot_printf(s->out, "%s CREATE ", tag); -- prot_printastring(s->out, name); -- /* special use needs extended support, so pass through extargs */ -- if (specialuse.len) { -- prot_printf(s->out, "(USE (%s)", buf_cstring(&specialuse)); -- if (partition) { -- prot_printf(s->out, " PARTITION "); -- prot_printastring(s->out, partition); - } -- prot_putc(')', s->out); -- } -- /* Send partition as an atom, since its supported by older servers */ -- else if (partition) { -- prot_putc(' ', s->out); -- prot_printastring(s->out, partition); -- } -- prot_printf(s->out, "\r\n"); - -- res = pipe_until_tag(s, tag, 0); -+ struct backend *s_conn = NULL; - -- if (!CAPA(s, CAPA_MUPDATE)) { -- /* do MUPDATE create operations */ -- } -- /* make sure we've seen the update */ -- if (ultraparanoid && res == PROXY_OK) kick_mupdate(); -- } -+ syslog(LOG_DEBUG, "connecting proxy_findserver()"); - -- imapd_check(s, 0); -+ s_conn = proxy_findserver( -+ server, -+ &imap_protocol, -+ proxy_userid, -+ &backend_cached, -+ &backend_current, -+ &backend_inbox, -+ imapd_in -+ ); - -- if (r) { -- prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -- } else { -- /* we're allowed to reference last_result since the noop, if -- sent, went to a different server */ -- prot_printf(imapd_out, "%s %s", tag, s->last_result.s); -+ if (!s_conn) { -+ prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); -+ goto done; -+ } -+ -+ syslog(LOG_DEBUG, "proxy_findserver() done"); -+ -+ // Huh? -+ if (imapd_userisadmin && supports_referrals) { -+ syslog(LOG_DEBUG, "going to refer the admin..."); -+ // "They are not an admin remotely, so let's refer them" -- -+ // - Who is they? -+ // - How did imapd_userisadmin get set all of a sudden? -+ imapd_refer(tag, server, name); -+ referral_kick = 1; -+ syslog(LOG_DEBUG, "done referring the admin"); -+ return; -+ } -+ -+ if (!CAPA(s_conn, CAPA_MUPDATE)) { -+ // Huh? -+ // "reserve mailbox on MUPDATE" -+ syslog(LOG_WARNING, "backend %s is not advertising any MUPDATE capability (%s:%d)", server, __FILE__, __LINE__); -+ } -+ -+ // ok, send the create to that server as localcreate -+ //prot_printf(s_conn->out, "%s LOCALCREATE ", tag); -+ // originally with CREATE -+ prot_printf(s_conn->out, "%s CREATE ", tag); -+ prot_printastring(s_conn->out, name); -+ -+ // special use needs extended support, so pass through extargs -+ if (specialuse.len) { -+ prot_printf(s_conn->out, "(USE (%s)", buf_cstring(&specialuse)); -+ -+ if (partition) { -+ prot_printf(s_conn->out, " PARTITION "); -+ prot_printastring(s_conn->out, partition); -+ } -+ -+ prot_putc(')', s_conn->out); -+ } -+ -+ // Send partition as an atom, since its supported by older servers -+ else if (partition) { -+ prot_putc(' ', s_conn->out); -+ prot_printastring(s_conn->out, partition); -+ } -+ -+ prot_printf(s_conn->out, "\r\n"); -+ -+ int res = pipe_until_tag(s_conn, tag, 0); -+ -+ if (!CAPA(s_conn, CAPA_MUPDATE)) { -+ // Huh? -+ // "do MUPDATE create operations" -+ syslog(LOG_WARNING, "backend %s is not advertising any MUPDATE capability (%s:%d)", server, __FILE__, __LINE__); -+ } -+ -+ /* make sure we've seen the update */ -+ if (ultraparanoid && res == PROXY_OK) kick_mupdate(); -+ -+ imapd_check(s_conn, 0); -+ -+ syslog(LOG_DEBUG, "passing (%s:%d)", __FILE__, __LINE__); -+ -+ prot_printf(imapd_out, "%s %s\r\n", tag, s_conn->last_result.s); -+ -+ goto done; -+ -+ } else { // (!config_getstring(IMAPOPT_PROXYSERVERS)) -+ syslog(LOG_DEBUG, "I have a standard murder config but also proxy servers configured; I'm a backend!"); -+ goto localcreate; -+ -+ } // (!config_getstring(IMAPOPT_PROXYSERVERS)) -+ -+ } // (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) -+ -+ else if (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_UNIFIED) { -+ } // (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_UNIFIED) -+ -+ else if (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_REPLICATED) { -+ } // (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_REPLICATED) -+ -+ else { -+ syslog(LOG_ERR, "murder configuration I cannot deal with"); -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE), __FILE__, __LINE__); -+ goto done; - } - -+ } else { // (config_mupdate_server) -+ // go localcreate -+ syslog(LOG_ERR, "Cannot create a mailbox 'not locally', while I'm not a part of a Cyrus IMAP Murder"); -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE), __FILE__, __LINE__); - goto done; -- } --#if 0 -- else if (!r && -- (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) && -- !config_getstring(IMAPOPT_PROXYSERVERS)) { -- /* can't create maiilboxes on proxy-only servers */ -- r = IMAP_PERMISSION_DENIED; -- } --#endif -+ } // (config_mupdate_server) - -- /* local mailbox -- fall through */ -- if (guessedpart) { -- partition = NULL; -- r = 0; -- } -+ } else { // (!localonly) -+ goto localcreate; - } - -- /* local mailbox */ -- if (!r) { -+localcreate: -+ syslog(LOG_DEBUG, "creating mailbox %s locally", mailboxname); - -- /* xxx we do forced user creates on LOCALCREATE to facilitate -- * mailbox moves */ -- r = mboxlist_createmailbox(mailboxname, mbtype, partition, -- imapd_userisadmin || imapd_userisproxyadmin, -- imapd_userid, imapd_authstate, -- localonly, localonly, 0, 1, NULL); -+ r = mboxlist_createmailbox( -+ mailboxname, // const char name -+ mbtype, // int mbtype -+ partition, // const char partition -+ imapd_userisadmin || imapd_userisproxyadmin, // int isadmin -+ imapd_userid, // const char userid -+ imapd_authstate, // struct auth_state auth_state -+ localonly, // int localonly -+ localonly, // int forceuser -+ 0, // int dbonly -+ 1, // int notify -+ NULL // struct mailbox mailboxptr -+ ); -+ -+#if 0 -+ // Clausing autocreate for the INBOX -+ if (r == IMAP_PERMISSION_DENIED) { -+ if (!strcasecmp(name, "INBOX")) { -+ if ((autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { -+ r = mboxlist_createmailbox( -+ mailboxname, -+ 0, -+ partition, -+ 1, -+ imapd_userid, -+ imapd_authstate, -+ 0, -+ 0, -+ 0, -+ 1, -+ NULL -+ ); - -- if (r == IMAP_PERMISSION_DENIED && !strcasecmp(name, "INBOX") && -- (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { -+ if (r) { -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - -- /* Auto create INBOX is always type zero */ -- r = mboxlist_createmailbox(mailboxname, /*mbtype*/0, partition, -- 1, imapd_userid, imapd_authstate, -- 0, 0, 0, 1, NULL); -+ int autocreatequotamessage = config_getint(IMAPOPT_AUTOCREATEQUOTAMSG); - -- int autocreatequotamessage = config_getint(IMAPOPT_AUTOCREATEQUOTAMSG); -- if (!r && ((autocreatequotastorage > 0) || (autocreatequotamessage > 0))) { -- int res; -- int newquotas[QUOTA_NUMRESOURCES]; -+ if ((autocreatequotastorage > 0) || (autocreatequotamessage > 0)) { -+ int newquotas[QUOTA_NUMRESOURCES]; -+ int res; - -- for (res = 0 ; res < QUOTA_NUMRESOURCES ; res++) -- newquotas[res] = QUOTA_UNLIMITED; -- newquotas[QUOTA_STORAGE] = autocreatequotastorage; -- newquotas[QUOTA_MESSAGE] = autocreatequotamessage; -+ for (res = 0; res < QUOTA_NUMRESOURCES; res++) { -+ newquotas[res] = QUOTA_UNLIMITED; -+ } - -- (void) mboxlist_setquotas(mailboxname, newquotas, 0); -- } -- } -+ newquotas[QUOTA_STORAGE] = autocreatequotastorage; -+ newquotas[QUOTA_MESSAGE] = autocreatequotamessage; - -- if (!r && specialuse.len) { -- r = annotatemore_write(mailboxname, "/specialuse", imapd_userid, &specialuse); -- if (r) { -- /* XXX - failure here SHOULD cause a cleanup of the created mailbox */ -- syslog(LOG_ERR, "IOERROR: failed to write specialuse for %s on %s (%s)", -- imapd_userid, mailboxname, buf_cstring(&specialuse)); -- } -+ (void) mboxlist_setquotas(mailboxname, newquotas, 0); -+ } // (autocreatequotastorage > 0) || (autocreatequotamessage > 0) -+ -+ } else { // (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA)) -+ syslog( -+ LOG_DEBUG, -+ "Attempt to create INBOX by %s but automatic creation not configured", -+ imapd_userid -+ ); -+ -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(IMAP_PERMISSION_DENIED), __FILE__, __LINE__); -+ goto done; -+ -+ } // (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA)) -+ -+ } else { // (!strcasecmp(name, "INBOX")) -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(IMAP_PERMISSION_DENIED), __FILE__, __LINE__); -+ goto done; -+ } // (!strcasecmp(name, "INBOX")) -+ -+ } else { // (r == IMAP_PERMISSION_DENIED) -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(IMAP_PERMISSION_DENIED), __FILE__, __LINE__); -+ goto done; -+ } // (r == IMAP_PERMISSION_DENIED) -+ -+ if (specialuse.len) { -+ r = annotatemore_write(mailboxname, "/specialuse", imapd_userid, &specialuse); -+ if (r) { -+ /* XXX - failure here SHOULD cause a cleanup of the created mailbox */ -+ syslog( -+ LOG_ERR, -+ "IOERROR: failed to write specialuse for %s on %s (%s) (%s:%d)", -+ imapd_userid, -+ mailboxname, -+ buf_cstring(&specialuse), -+ __FILE__, -+ __LINE__ -+ ); -+ -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); -+ goto done; - } - } - -- imapd_check(NULL, 0); -+#endif - -- if (r) { -- prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -- } -- else { -- if (config_mupdate_server) -- kick_mupdate(); -+ prot_printf(imapd_out, "%s OK Completed\r\n", tag); - -- prot_printf(imapd_out, "%s OK %s\r\n", tag, -- error_message(IMAP_OK_COMPLETED)); -- } -+ imapd_check(NULL, 0); - - done: - buf_free(&specialuse); -@@ -5588,8 +5708,9 @@ static int delmbox(char *name, - } - - if(r) { -- prot_printf(imapd_out, "* NO delete %s: %s\r\n", -- name, error_message(r)); -+ prot_printf(imapd_out, "* NO delete %s: %s (%s:%d)\r\n", -+ name, error_message(r), -+ __FILE__, __LINE__); - } - - return 0; -@@ -5647,7 +5768,7 @@ static void cmd_delete(char *tag, char *name, int localonly, int force) - imapd_check(s, 0); - - if (r) { -- prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); - } else { - /* we're allowed to reference last_result since the noop, if - sent, went to a different server */ -@@ -5710,7 +5831,7 @@ static void cmd_delete(char *tag, char *name, int localonly, int force) - imapd_check(NULL, 0); - - if (r) { -- prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); -+ prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); - } - else { - if (config_mupdate_server) -@@ -5787,8 +5908,9 @@ static int renmbox(char *name, - imapd_userid, newextname); - - if(r) { -- prot_printf(imapd_out, "* NO rename %s %s: %s\r\n", -- oldextname, newextname, error_message(r)); -+ prot_printf(imapd_out, "* NO rename %s %s: %s (%s:%d)\r\n", -+ oldextname, newextname, error_message(r), -+ __FILE__, __LINE__); - if (RENAME_STOP_ON_ERROR) return r; - } else { - /* If we're renaming a user, change quotaroot and ACL */ -@@ -5874,8 +5996,10 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *partition) - - if (strcmp(oldname, newname)) { - prot_printf(imapd_out, -- "%s NO Cross-server or cross-partition move w/rename not supported\r\n", -- tag); -+ "%s NO Cross-server or cross-partition move w/rename not supported (%s:%d)\r\n", -+ tag, -+ __FILE__, -+ __LINE__); - goto done; - } - -@@ -5886,7 +6010,7 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *partition) - char newserver[MAX_MAILBOX_BUFFER]; - if (strlen(partition) >= sizeof(newserver)) { - prot_printf(imapd_out, -- "%s NO Partition name too long\r\n", tag); -+ "%s NO Partition name too long (%s:%d)\r\n", tag, __FILE__, __LINE__); - goto done; - } - strcpy(newserver, partition); -@@ -5898,8 +6022,8 @@ static void cmd_rename(char *tag, char *oldname, char *newname, char *partition) - /* xxx this would require administrative access to the - * backend, which we won't get */ - prot_printf(imapd_out, -- "%s NO Can't move across partitions via a proxy\r\n", -- tag); -+ "%s NO Can't move across partitions via a proxy (%s:%d)\r\n", -+ tag, __FILE__, __LINE__); - goto done; - } else { - /* Cross Server */ -@@ -7877,12 +8001,14 @@ static int parse_annotate_fetch_data(const char *tag, - */ - static int parse_metadata_string_or_list(const char *tag, - strarray_t *entries, -- int *was_singlep) -+ int *is_list) - { - int c; - static struct buf arg; - -- *was_singlep = 0; -+ // Again, the assumption is that what can be lists, are -+ // lists until proven otherwise. -+ *is_list = 1; - - c = prot_getc(imapd_in); - if (c == EOF) { -@@ -7928,7 +8054,7 @@ static int parse_metadata_string_or_list(const char *tag, - } - - strarray_append(entries, arg.s); -- *was_singlep = 1; -+ *is_list = 0; - } - - if (c == ' ' || c == '\r') return c; -@@ -8507,7 +8633,8 @@ static void cmd_getmetadata(const char *tag) - strarray_t lists[3] = { STRARRAY_INITIALIZER, - STRARRAY_INITIALIZER, - STRARRAY_INITIALIZER }; -- int was_single[3] = { 0, 0, 0 }; -+ // The default is to consider potential lists a list -+ int is_list[3] = { 1, 1, 1 }; - int nlists = 0; - strarray_t *options = NULL; - strarray_t *mboxes = NULL; -@@ -8529,7 +8656,7 @@ static void cmd_getmetadata(const char *tag) - - while (nlists < 3) - { -- c = parse_metadata_string_or_list(tag, &lists[nlists], &was_single[nlists]); -+ c = parse_metadata_string_or_list(tag, &lists[nlists], &is_list[nlists]); - if (c == EOF) - goto missingargs; - nlists++; -@@ -8537,6 +8664,14 @@ static void cmd_getmetadata(const char *tag) - break; - } - -+ // GETMETADATA: parse result lists[0]: shared/test@lhm.klab.cc -+ // GETMETADATA: parse result lists[1]: /shared/vendor/cmu/cyrus-imapd/server -+ // GETMETADATA: parse result lists[2]: (null) -+ -+ syslog(LOG_DEBUG, "GETMETADATA: parse result lists[0]: %s", strarray_join(&lists[0], ",")); -+ syslog(LOG_DEBUG, "GETMETADATA: parse result lists[1]: %s", strarray_join(&lists[1], ",")); -+ syslog(LOG_DEBUG, "GETMETADATA: parse result lists[2]: %s", strarray_join(&lists[2], ",")); -+ - /* check for CRLF */ - if (c == '\r') c = prot_getc(imapd_in); - if (c != '\n') { -@@ -8579,9 +8714,10 @@ static void cmd_getmetadata(const char *tag) - goto missingargs; - entries = &lists[nlists-1]; /* entries always last */ - if (nlists == 2) { -+ syslog(LOG_DEBUG, "GETMETADATA: no options specified"); - /* no options */ - mboxes = &lists[0]; -- mbox_is_pattern = was_single[0]; -+ mbox_is_pattern = is_list[0]; - } - if (nlists == 3) { - /* options, either before or after */ -@@ -8595,12 +8731,12 @@ static void cmd_getmetadata(const char *tag) - /* (options) (mailboxes) */ - options = &lists[0]; - mboxes = &lists[1]; -- mbox_is_pattern = was_single[1]; -+ mbox_is_pattern = is_list[1]; - break; - case 2: - /* (mailboxes) (options) */ - mboxes = &lists[0]; -- mbox_is_pattern = was_single[0]; -+ mbox_is_pattern = is_list[0]; - options = &lists[1]; - break; - case 3: -@@ -8656,6 +8792,9 @@ static void cmd_getmetadata(const char *tag) - } - } - -+ syslog(LOG_DEBUG, "GETMETADATA: parse result newe: %s", strarray_join(&newe, ",")); -+ syslog(LOG_DEBUG, "GETMETADATA: parse result mboxes: %s", strarray_join(mboxes, ",")); -+ - if (have_private) strarray_append(&newa, "value.priv"); - if (have_shared) strarray_append(&newa, "value.shared"); - -@@ -8664,6 +8803,12 @@ static void cmd_getmetadata(const char *tag) - imapd_userisadmin || imapd_userisproxyadmin, - imapd_userid, imapd_authstate); - basesize = opts.maxsize; -+ -+ if (mbox_is_pattern) -+ syslog(LOG_DEBUG, "GETMETADATA: mbox is a pattern"); -+ else -+ syslog(LOG_DEBUG, "GETMETADATA: mbox is not a pattern"); -+ - if (!mboxes->count || !strcmpsafe(mboxes->data[0], NULL)) { - r = annotate_state_set_server(astate); - if (!r) -diff --git a/imap/lmtpd.c b/imap/lmtpd.c -index 634f350..cfa4518 100644 ---- a/imap/lmtpd.c -+++ b/imap/lmtpd.c -@@ -475,7 +475,7 @@ static int mlookup(const char *name, mbentry_t **mbentryptr) - - mbentry = mboxlist_entry_create(); - mbentry->acl = xstrdupnull(mailboxdata->acl); -- mbentry->server = xstrdupnull(mailboxdata->server); -+ mbentry->server = xstrdupnull(mailboxdata->location); - - /* XXX hack for now - should pull this out into mupdate_find */ - c = strchr(mbentry->server, '!'); -diff --git a/imap/mboxlist.c b/imap/mboxlist.c -index 403aeb9..2bc0bed 100644 ---- a/imap/mboxlist.c -+++ b/imap/mboxlist.c -@@ -485,7 +485,10 @@ HIDDEN int mboxlist_findstage(const char *name, char *stagedir, size_t sd_len) - root = config_partitiondir(mbentry->partition); - mboxlist_entry_free(&mbentry); - -- if (!root) return IMAP_PARTITION_UNKNOWN; -+ if (!root) { -+ syslog(LOG_ERR, "no stage directory for unknown partition"); -+ return IMAP_PARTITION_UNKNOWN; -+ } - - snprintf(stagedir, sd_len, "%s/stage./", root); - -@@ -544,7 +547,7 @@ EXPORTED int mboxlist_update(mbentry_t *mbentry, int localonly) - return r; - } - --static int mboxlist_findparent(const char *mboxname, -+EXPORTED int mboxlist_findparent(const char *mboxname, - mbentry_t **mbentryp) - { - mbentry_t *mbentry = NULL; -@@ -592,11 +595,15 @@ static int mboxlist_create_partition(const char *mboxname, - part = find_free_partition(NULL); - - /* Configuration error */ -- if (strlen(part) > MAX_PARTITION_LEN) -+ if (strlen(part) > MAX_PARTITION_LEN) { -+ syslog(LOG_ERR, "part longer than maximum partition length in mboxlist_create_partition()"); - goto err; -+ } - -- if (!config_partitiondir(part)) -+ if (!config_partitiondir(part)) { -+ syslog(LOG_ERR, "no configuration for partition dir in mboxlist_create_partition()"); - goto err; -+ } - - *out = xstrdupnull(part); - -@@ -769,16 +776,26 @@ EXPORTED int mboxlist_createmailboxcheck(const char *name, int mbtype __attribut - - r = mboxlist_create_namecheck(name, userid, auth_state, - isadmin, forceuser); -- if (r) goto done; -+ if (r) { -+ syslog(LOG_DEBUG, "mboxlist_create_namecheck returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - - if (newacl) { - r = mboxlist_create_acl(name, &acl); -- if (r) goto done; -+ if (r) { -+ syslog(LOG_DEBUG, "mboxlist_create_acl returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - } - - if (newpartition) { -+ syslog(LOG_DEBUG, "calling mboxlist_create_partition from mboxlist_createmailboxcheck"); - r = mboxlist_create_partition(name, partition, &part); -- if (r) goto done; -+ if (r) { -+ syslog(LOG_DEBUG, "mboxlist_create_partition returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - } - - done: -@@ -822,10 +839,16 @@ static int mboxlist_createmailbox_full(const char *mboxname, int mbtype, - - r = mboxlist_create_namecheck(mboxname, userid, auth_state, - isadmin, forceuser); -- if (r) goto done; -+ if (r) { -+ syslog(LOG_DEBUG, "mboxlist_create_namecheck returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - - /* check if a previous deleted mailbox existed */ - r = mboxlist_mylookup(mboxname, &mbentry, NULL, 0); -+ -+ syslog(LOG_DEBUG, "mboxlist_mylookup returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ - if (!r && mbentry->mbtype == MBTYPE_DELETED) { - /* changing the unique id since last time? */ - if (strcmpsafe(uniqueid, mbentry->uniqueid)) { -@@ -843,17 +866,30 @@ static int mboxlist_createmailbox_full(const char *mboxname, int mbtype, - if (r) goto done; - } - -+ syslog(LOG_DEBUG, "calling mboxlist_create_partition from mboxlist_createmailbox_full"); - r = mboxlist_create_partition(mboxname, partition, &newpartition); -- if (r) goto done; -+ syslog(LOG_DEBUG, "mboxlist_create_partition from mboxlist_createmailbox_full done"); -+ -+ if (r) { -+ syslog(LOG_DEBUG, "mboxlist_create_partition returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; -+ } - - if (!dbonly && !isremote) { - - /* Filesystem Operations */ -+ syslog(LOG_DEBUG, "calling mailbox_create from mboxlist_createmailbox_full"); - r = mailbox_create(mboxname, mbtype, newpartition, acl, uniqueid, - options, uidvalidity, &newmailbox); -- if (r) goto done; /* CREATE failed */ -+ syslog(LOG_DEBUG, "mailbox_create from mboxlist_createmailbox_full done"); -+ if (r) { -+ syslog(LOG_DEBUG, "mailbox_create returns %s (%s:%d)", error_message(r), __FILE__, __LINE__); -+ goto done; /* CREATE failed */ -+ } - } - -+ syslog(LOG_DEBUG, "all is well, activate the mailbox"); -+ - /* all is well - activate the mailbox */ - newmbentry = mboxlist_entry_create(); - newmbentry->acl = xstrdupnull(acl); -@@ -918,10 +954,24 @@ EXPORTED int mboxlist_createmailbox(const char *name, int mbtype, - int r; - struct mailbox *mailbox = NULL; - -- r = mboxlist_createmailbox_full(name, mbtype, partition, -- isadmin, userid, auth_state, -- options, 0, NULL, NULL, localonly, -- forceuser, dbonly, &mailbox); -+ syslog(LOG_DEBUG, "calling mboxlist_createmailbox_full from mboxlist_createmailbox"); -+ -+ r = mboxlist_createmailbox_full( -+ name, // const char mboxname -+ mbtype, // int mbtype -+ partition, // const char partition -+ isadmin, // int isadmin -+ userid, // const char userid -+ auth_state, // struct auth_state auth_state -+ options, // int options -+ 0, // unsigned uidvalidity -+ NULL, // const char copyacl -+ NULL, // const char uniqueid -+ localonly, // int localonly -+ forceuser, // int forceuser -+ dbonly, // int dbonly -+ &mailbox // struct mailbox mailboxptr -+ ); - - if (notify && !r) { - /* send a MailboxCreate event notification */ -@@ -945,6 +995,8 @@ EXPORTED int mboxlist_createsync(const char *name, int mbtype, - const char *acl, const char *uniqueid, - struct mailbox **mboxptr) - { -+ syslog(LOG_DEBUG, "calling mboxlist_createmailbox_full from mboxlist_createsync"); -+ - return mboxlist_createmailbox_full(name, mbtype, partition, - 1, userid, auth_state, - options, uidvalidity, acl, uniqueid, -@@ -959,6 +1011,8 @@ EXPORTED int mboxlist_insertremote(mbentry_t *mbentry, - int r = 0; - - if (mbentry->server) { -+ syslog(LOG_DEBUG, "%s mbentry->server specified", __func__); -+ - /* remote mailbox */ - if (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_UNIFIED && - !strcasecmp(mbentry->server, config_servername)) { -@@ -974,6 +1028,8 @@ EXPORTED int mboxlist_insertremote(mbentry_t *mbentry, - - mboxent = mboxlist_entry_cstring(mbentry); - -+ syslog(LOG_DEBUG, "mboxent: %s (%s:%d)", mboxent, __FILE__, __LINE__); -+ - /* database put */ - r = cyrusdb_store(mbdb, mbentry->name, strlen(mbentry->name), - mboxent, strlen(mboxent), tid); -@@ -1344,6 +1400,8 @@ EXPORTED int mboxlist_renamemailbox(const char *oldname, const char *newname, - /* this is OK because it uses a different static buffer */ - root = config_partitiondir(partition); - if (!root) { -+ syslog(LOG_ERR, "partition rename without existing target partition"); -+ - r = IMAP_PARTITION_UNKNOWN; - goto done; - } -@@ -1405,6 +1463,7 @@ EXPORTED int mboxlist_renamemailbox(const char *oldname, const char *newname, - isadmin, forceuser); - if (r) goto done; - -+ syslog(LOG_DEBUG, "calling mboxlist_create_partition from mboxlist_renamemailbox"); - r = mboxlist_create_partition(newname, partition, &newpartition); - if (r) goto done; - -diff --git a/imap/mboxlist.h b/imap/mboxlist.h -index 1b13dae..34d26ef 100644 ---- a/imap/mboxlist.h -+++ b/imap/mboxlist.h -@@ -124,6 +124,9 @@ int mboxlist_createmailboxcheck(const char *name, int mbtype, - char **newacl, char **newpartition, - int forceuser); - -+/* Find a parent mailbox */ -+int mboxlist_findparent(const char *mboxname, mbentry_t **mbentryp); -+ - /* create mailbox */ - /* localonly creates the local mailbox without touching mupdate */ - /* forceuser allows the creation of user.x.<name> without a user.x */ -diff --git a/imap/quota.c b/imap/quota.c -index d3b16e9..38583fa 100644 ---- a/imap/quota.c -+++ b/imap/quota.c -@@ -360,7 +360,8 @@ done: - */ - int buildquotalist(char *domain, char **roots, int nroots) - { -- int i, r; -+ int i; -+ int r = 1; // error - char buf[MAX_MAILBOX_BUFFER], *tail; - size_t domainlen = 0; - -@@ -611,7 +612,8 @@ done: - int fixquota_dopass(char *domain, char **roots, int nroots, - foreach_cb *cb) - { -- int i, r; -+ int i; -+ int r = 1; // error - char buf[MAX_MAILBOX_BUFFER], *tail; - size_t domainlen = 0; - -diff --git a/imap/rfc822_header.c b/imap/rfc822_header.c -index bd57930..7bb1f79 100644 ---- a/imap/rfc822_header.c -+++ b/imap/rfc822_header.c -@@ -1,5 +1,5 @@ - /* ANSI-C code produced by gperf version 3.0.4 */ --/* Command-line: gperf /tmp/compile_st_NBXFPK.gperf */ -+/* Command-line: gperf /home/kanarip/tmp/compile_st_2BOtSi.gperf */ - /* Computed positions: -k'1,10,$' */ - - #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ -diff --git a/lib/imapoptions b/lib/imapoptions -index 2c477a6..3c338b2 100644 ---- a/lib/imapoptions -+++ b/lib/imapoptions -@@ -126,7 +126,7 @@ are listed with ``<none>''. - /* Permit logins by the user "anonymous" using any password. Also - allows use of the SASL ANONYMOUS mechanism. */ - --{ "allowapop", 1, SWITCH } -+{ "allowapop", 0, SWITCH } - /* Allow use of the POP3 APOP authentication command. - .PP - Note that this command requires that SASL is compiled with APOP -@@ -141,9 +141,14 @@ are listed with ``<none>''. - enabled when absolutely necessary. */ - - { "allowplaintext", 0, SWITCH } --/* Allow the use of cleartext passwords on the wire. */ -+/* Allow the use of cleartext passwords on the wire -+.PP -+ WARNING: Enabling this option allows cleartext, legible passwords -+ to be transmitted over the network, without any transport layer -+ security (such as SSL encryption) and creates an MiM attack -+ vector. */ - --{ "allowusermoves", 0, SWITCH } -+{ "allowusermoves", 1, SWITCH } - /* Allow moving user accounts (with associated meta-data) via RENAME - or XFER. - .PP -@@ -152,7 +157,7 @@ are listed with ``<none>''. - to do so may result in the user's meta-data (seen state, - subscriptions, etc) being corrupted or out of date. */ - --{ "altnamespace", 0, SWITCH } -+{ "altnamespace", 1, SWITCH } - /* Use the alternate IMAP namespace, where personal folders reside at the - same level in the hierarchy as INBOX. - .PP -@@ -170,7 +175,7 @@ are listed with ``<none>''. - /* The absolute path to the annotations db file. If not specified, - will be confdir/annotations.db */ - --{ "anyoneuseracl", 1, SWITCH } -+{ "anyoneuseracl", 0, SWITCH } - /* Should non-admin users be allowed to set ACLs for the 'anyone' - user on their mailboxes? In a large organization this can cause - support problems, but it's enabled by default. */ -@@ -482,7 +487,7 @@ Blank lines and lines beginning with ``#'' are ignored. - { "failedloginpause", 3, INT } - /* Number of seconds to pause after a failed login. */ - --{ "flushseenstate", 0, SWITCH } -+{ "flushseenstate", 1, SWITCH } - /* If enabled, changes to the seen state will be flushed to disk - immediately, otherwise changes will be cached and flushed when the - mailbox is closed. This option may be used to fix the problem of -@@ -510,7 +515,7 @@ Blank lines and lines beginning with ``#'' are ignored. - server must be quiesced and then the directories moved with the - \fBrehash\fR utility. */ - --{ "hashimapspool", 0, SWITCH } -+{ "hashimapspool", 1, SWITCH } - /* If enabled, the partitions will also be hashed, in addition to the - hashing done on configuration directories. This is recommended if - one partition has a very bushy mailbox tree. */ -@@ -751,7 +756,7 @@ Blank lines and lines beginning with ``#'' are ignored. - /* If enabled, lmtpd will convert the recipient addresses to lowercase - (up to a '+' character, if present). */ - --{ "lmtp_fuzzy_mailbox_match", 0, SWITCH } -+{ "lmtp_fuzzy_mailbox_match", 1, SWITCH } - /* If enabled, and the mailbox specified in the detail part of the - recipient (everything after the '+') does not exist, lmtpd will try - to find the closest match (ignoring case, ignoring whitespace, -@@ -1508,7 +1513,7 @@ product version in the capabilities */ - /* Number of seconds to wait for a response before returning a timeout - failure when talking to a replication peer (client or server). */ - --{ "syslog_prefix", NULL, STRING } -+{ "syslog_prefix", "cyrus-imapd", STRING } - /* String to be prepended to the process name in syslog entries. */ - - { "syslog_facility", NULL, STRING } -@@ -1598,12 +1603,12 @@ product version in the capabilities */ - with a backend (such as LDAP) that can make getgrent() calls very - slow) */ - --{ "unixhierarchysep", 0, SWITCH } -+{ "unixhierarchysep", 1, SWITCH } - /* Use the UNIX separator character '/' for delimiting levels of - mailbox hierarchy. The default is to use the netnews separator - character '.'. */ - --{ "virtdomains", "off", ENUM("off", "userid", "on") } -+{ "virtdomains", "userid", ENUM("off", "userid", "on") } - /* Enable virtual domain support. If enabled, the user's domain will - be determined by splitting a fully qualified userid at the last '@' - or '%' symbol. If the userid is unqualified, and the virtdomains
View file
cyrus-imapd-2.5.tar.gz/configure.ac
Changed
@@ -1624,7 +1624,7 @@ event notification: $enable_event_notification idled: $enable_idled murder: $enable_murder - nttpd: $enable_nntp + nntpd: $enable_nntp replication: $enable_replication sieve: $enable_sieve
View file
cyrus-imapd-2.5.tar.gz/imap/annotate.c
Changed
@@ -1183,18 +1183,20 @@ annotate_state_unset_scope(state); if (mbentry) { - if (!mailbox && !mbentry->server) { + assert(!mailbox); + assert(!uid); + if (!mbentry->server) { /* local mailbox */ r = mailbox_open_iwl(mbentry->name, &mailbox); if (r) goto out; state->mailbox_is_ours = 1; } - assert(mailbox); state->mbentry = mbentry; + state->which = ANNOTATION_SCOPE_MAILBOX; } - if (uid) { + else if (uid) { assert(mailbox); state->which = ANNOTATION_SCOPE_MESSAGE; } @@ -1278,6 +1280,8 @@ if (state->mailbox) mboxname = state->mailbox->name; + else if (state->mbentry) + mboxname = state->mbentry->name; else mboxname = ""; /* @mboxname is now an internal mailbox name */ @@ -1367,13 +1371,14 @@ return 1; } else if (state->which == ANNOTATION_SCOPE_MAILBOX) { - assert(state->mailbox); + assert(state->mailbox || state->mbentry); /* Make sure its a local mailbox annotation */ if (state->mbentry && state->mbentry->server) return 0; - acl = state->mailbox->acl; + if (state->mailbox) acl = state->mailbox->acl; + else if (state->mbentry) acl = state->mbentry->acl; /* RFC5464 is a trifle vague about access control for mailbox * annotations but this seems to be compliant */ needed = ACL_LOOKUP|ACL_READ; @@ -1439,16 +1444,19 @@ r = annotate_state_need_mbentry(state); assert(r == 0); + /* Make sure its a remote mailbox */ + if (!state->mbentry->server) goto out; + /* Check ACL */ /* Note that we use a weaker form of access control than * normal - we only check for ACL_LOOKUP and we don't refuse * access if the mailbox is not local */ - if (!state->mbentry->acl || - !(cyrus_acl_myrights(state->auth_state, state->mbentry->acl) & ACL_LOOKUP)) + if (!state->isadmin && + (!state->mbentry->acl || + !(cyrus_acl_myrights(state->auth_state, state->mbentry->acl) & ACL_LOOKUP))) goto out; - if (state->mbentry->server) - buf_appendcstr(&value, state->mbentry->server); + buf_appendcstr(&value, state->mbentry->server); output_entryatt(state, entry->name, "", &value); out: @@ -1466,13 +1474,16 @@ r = annotate_state_need_mbentry(state); assert(r == 0); + /* Make sure its a local mailbox */ + if (state->mbentry->server) goto out; + /* Check ACL */ - if (!state->mbentry->acl || - !(cyrus_acl_myrights(state->auth_state, state->mbentry->acl) & ACL_LOOKUP)) + if (!state->isadmin && + (!state->mbentry->acl || + !(cyrus_acl_myrights(state->auth_state, state->mbentry->acl) & ACL_LOOKUP))) goto out; - if (!state->mbentry->server) - buf_appendcstr(&value, state->mbentry->partition); + buf_appendcstr(&value, state->mbentry->partition); output_entryatt(state, entry->name, "", &value); out: @@ -2177,12 +2188,12 @@ state->orig_attribute = attribs; } - _annotate_fetch_entries(state, /*proxy_check*/0); + _annotate_fetch_entries(state, /*proxy_check*/1); if (proxy_fetch_func && state->orig_entry && state->mbentry->server && !hash_lookup(state->mbentry->server, &state->server_table)) { /* xxx ignoring result */ - proxy_fetch_func(state->mbentry->server, state->orig_mailbox, + proxy_fetch_func(state->mbentry->server, state->mbentry->ext_name, state->orig_entry, state->orig_attribute); hash_insert(state->mbentry->server, (void *)0xDEADBEEF, &state->server_table); } @@ -2468,9 +2479,14 @@ struct annotate_entry_list *ee; int r; - /* Loop through the list of provided entries to get */ + /* Loop through the list of provided entries to set */ for (ee = state->entry_list ; ee ; ee = ee->next) { + /* Skip annotations that can't be stored on frontend */ + if ((ee->desc->proxytype == BACKEND_ONLY) && + (state->mbentry && state->mbentry->server)) + continue; + if (ee->have_shared && !_annotate_may_store(state, /*shared*/1, ee->desc)) return IMAP_PERMISSION_DENIED; @@ -2875,7 +2891,7 @@ goto cleanup; assert(state->mbentry); } - assert(state->mailbox); + else assert(state->mailbox); r = _annotate_store_entries(state); if (r) @@ -2894,7 +2910,7 @@ if (!r) { /* proxy command to backends */ struct proxy_rock prock = { NULL, NULL }; - prock.mbox_pat = state->mbentry->name; + prock.mbox_pat = state->mbentry->ext_name; prock.entryatts = l; hash_enumerate(&state->server_table, store_proxy, &prock); }
View file
cyrus-imapd-2.5.tar.gz/imap/ctl_mboxlist.c
Changed
@@ -214,10 +214,10 @@ } // if (r = dlist_getatom()) if (dl_ace->name && tmp) { - const char *ace = strconcat(xstrdup(dl_ace->name), " ", xstrdup(tmp)); + const char *ace = strconcat(xstrdup(dl_ace->name), "\t", xstrdup(tmp)); if (acl) { - acl = strconcat(xstrdup(acl), " ", ace); + acl = strconcat(xstrdup(acl), "\t", ace); } else { acl = xstrdup(ace); } @@ -242,13 +242,8 @@ r = dlist_getatom(dl, "T", (const char **)&mbtype_str); if (!r) { - syslog( - LOG_ERR, - "Failed to obtain (T)ype from dlist (%s:%d)", - __FILE__, - __LINE__ - ); - + // That's OK, the mailbox is local (0) + mbtype = 0; } mbtype = mboxlist_string_to_mbtype(mbtype_str); @@ -283,6 +278,10 @@ part = strconcat(server, "!", xstrdup(part)); } // (mbtype & MBTYPE_REMOTE) + + // Reset r **NOT** to the return value of ffin dlist functions + r = 0; + } // if (r = dlist_parsemap()) else { syslog(
View file
cyrus-imapd-2.5.tar.gz/imap/imapd.c
Changed
@@ -423,7 +423,7 @@ strarray_t *attribs); static int parse_metadata_string_or_list(const char *tag, strarray_t *sa, - int *was_singlep); + int *is_list); static int parse_annotate_store_data(const char *tag, int permessage_flag, struct entryattlist **entryatts); @@ -5363,200 +5363,300 @@ } } - if (partition && !imapd_userisadmin) { - r = IMAP_PERMISSION_DENIED; + // A non-admin is not allowed to specify the server nor partition on which + // to create the mailbox. + // + // However, this only applies to frontends. If we're a backend, a frontend will + // proxy the partition it wishes to create the mailbox on. + if ((server || partition) && !imapd_userisadmin) { + if ( + config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD || + config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_UNIFIED + ) { + + if (!config_getstring(IMAPOPT_PROXYSERVERS)) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_PERMISSION_DENIED)); + goto done; + } + } } + /* We don't care about trailing hierarchy delimiters. */ if (name[0] && name[strlen(name)-1] == imapd_namespace.hier_sep) { - /* We don't care about trailing hierarchy delimiters. */ name[strlen(name)-1] = '\0'; } - if (!r) { - r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name, - imapd_userid, mailboxname); + r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name, + imapd_userid, mailboxname); + + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + goto done; } /* check for INBOX.INBOX creation by broken Apple clients */ - if (!r) { - char *copy = xstrdup(mailboxname); - lcase(copy); - if (strstr(copy, "inbox.inbox")) - r = IMAP_MAILBOX_BADNAME; - free(copy); + char *copy = xstrdup(mailboxname); + lcase(copy); + + if (strstr(copy, "inbox.inbox")) + r = IMAP_MAILBOX_BADNAME; + + free(copy); + + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + goto done; } - if (!r && !localonly && config_mupdate_server) { - int guessedpart = 0; + // If the create command does not mandate the mailbox must be created + // locally, let's go and find the most appropriate location. + if (!localonly) { + + // If we're running in a Murder, things get more complicated. + if (config_mupdate_server) { + + // Consider your actions on a per type of topology basis. + // + // First up: Standard / discrete murder topology, with dedicated + // imap frontends, or unified -- both allow the IMAP server to either + // need to proxy through, or create locally. + if ( + config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD || + config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_UNIFIED + ) { + + // The way that we detect whether we're a frontend is by testing + // for the proxy servers setting ... :/ + if (!config_getstring(IMAPOPT_PROXYSERVERS)) { + // Find the parent mailbox, if any. + mbentry_t *parent = NULL; + + // mboxlist_findparent either supplies the parent + // or has a return code of IMAP_MAILBOX_NONEXISTENT. + r = mboxlist_findparent(mailboxname, &parent); + + if (r) { + if (r != IMAP_MAILBOX_NONEXISTENT) { + prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); + goto done; + } + } - /* determine if we're creating locally or remotely */ - if (!partition && !server) { - char *foundpart = NULL; - guessedpart = 1; - r = mboxlist_createmailboxcheck(mailboxname, 0, 0, - imapd_userisadmin || imapd_userisproxyadmin, - imapd_userid, imapd_authstate, - NULL, &foundpart, 0); - partition = foundpart; + if (!server && !partition) { + if (!parent) { + server = find_free_server(); + + if (!server) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); + goto done; + } + + } else { + server = parent->server; + partition = parent->partition; + } + } - if (!r && !partition && - (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) && - !config_getstring(IMAPOPT_PROXYSERVERS)) { - /* proxy-only server, and no parent mailbox */ - guessedpart = 0; + struct backend *s_conn = NULL; - /* use defaultserver if specified */ - partition = config_getstring(IMAPOPT_DEFAULTSERVER); + s_conn = proxy_findserver( + server, + &imap_protocol, + proxy_userid, + &backend_cached, + &backend_current, + &backend_inbox, + imapd_in + ); + + if (!s_conn) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); + goto done; + } - /* otherwise, find server with most available space */ - if (!partition) partition = find_free_server(); + // Huh? + if (imapd_userisadmin && supports_referrals) { + // "They are not an admin remotely, so let's refer them" -- + // - Who is they? + // - How did imapd_userisadmin get set all of a sudden? + imapd_refer(tag, server, name); + referral_kick = 1; + return; + } - if (!partition) r = IMAP_SERVER_UNAVAILABLE; - } - } + if (!CAPA(s_conn, CAPA_MUPDATE)) { + // Huh? + // "reserve mailbox on MUPDATE" + syslog(LOG_WARNING, "backend %s is not advertising any MUPDATE capability (%s:%d)", server, __FILE__, __LINE__); + } - if (!r && !config_partitiondir(partition)) { - /* invalid partition, assume its a server (remote mailbox) */ - struct backend *s = NULL; - char *p; - int res; - - /* check for a remote partition */ - server = partition; - p = strchr(server, '!'); - if (p) *p++ = '\0'; - partition = guessedpart ? NULL : p; + // why not send a LOCALCREATE to the backend? + prot_printf(s_conn->out, "%s CREATE ", tag); + prot_printastring(s_conn->out, name); + + // special use needs extended support, so pass through extargs + if (specialuse.len) { + prot_printf(s_conn->out, "(USE (%s)", buf_cstring(&specialuse)); + + if (partition) { + prot_printf(s_conn->out, " PARTITION "); + prot_printastring(s_conn->out, partition); + } - s = proxy_findserver(server, &imap_protocol, - proxy_userid, &backend_cached, - &backend_current, &backend_inbox, imapd_in); - if (!s) r = IMAP_SERVER_UNAVAILABLE; + prot_putc(')', s_conn->out); + } - if (!r && imapd_userisadmin && supports_referrals) { - /* They aren't an admin remotely, so let's refer them */ - imapd_refer(tag, server, name); - referral_kick = 1; - return; - } + // Send partition as an atom, since its supported by older servers + else if (partition) { + prot_putc(' ', s_conn->out); + prot_printastring(s_conn->out, partition); + } - if (!r) { - if (!CAPA(s, CAPA_MUPDATE)) { - /* reserve mailbox on MUPDATE */ - } - } + prot_printf(s_conn->out, "\r\n"); - if (!r) { - /* ok, send the create to that server */ - prot_printf(s->out, "%s CREATE ", tag); - prot_printastring(s->out, name); - /* special use needs extended support, so pass through extargs */ - if (specialuse.len) { - prot_printf(s->out, "(USE (%s)", buf_cstring(&specialuse)); - if (partition) { - prot_printf(s->out, " PARTITION "); - prot_printastring(s->out, partition); + int res = pipe_until_tag(s_conn, tag, 0); + + if (!CAPA(s_conn, CAPA_MUPDATE)) { + // Huh? + // "do MUPDATE create operations" + syslog(LOG_WARNING, "backend %s is not advertising any MUPDATE capability (%s:%d)", server, __FILE__, __LINE__); } - prot_putc(')', s->out); - } - /* Send partition as an atom, since its supported by older servers */ - else if (partition) { - prot_putc(' ', s->out); - prot_printastring(s->out, partition); - } - prot_printf(s->out, "\r\n"); - res = pipe_until_tag(s, tag, 0); + /* make sure we've seen the update */ + if (ultraparanoid && res == PROXY_OK) kick_mupdate(); - if (!CAPA(s, CAPA_MUPDATE)) { - /* do MUPDATE create operations */ - } - /* make sure we've seen the update */ - if (ultraparanoid && res == PROXY_OK) kick_mupdate(); - } + imapd_check(s_conn, 0); - imapd_check(s, 0); + prot_printf(imapd_out, "%s %s", tag, s_conn->last_result.s); - if (r) { - prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); - } else { - /* we're allowed to reference last_result since the noop, if - sent, went to a different server */ - prot_printf(imapd_out, "%s %s", tag, s->last_result.s); - } + goto done; - goto done; - } -#if 0 - else if (!r && - (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) && - !config_getstring(IMAPOPT_PROXYSERVERS)) { - /* can't create maiilboxes on proxy-only servers */ - r = IMAP_PERMISSION_DENIED; - } -#endif + } else { // (!config_getstring(IMAPOPT_PROXYSERVERS)) + // I have a standard murder config but also proxy servers configured; I'm a backend! + goto localcreate; + + } // (!config_getstring(IMAPOPT_PROXYSERVERS)) + + } // (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_STANDARD) + + else if (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_REPLICATED) { + // Everything is local + goto localcreate; + } // (config_mupdate_config == IMAP_ENUM_MUPDATE_CONFIG_REPLICATED) - /* local mailbox -- fall through */ - if (guessedpart) { - partition = NULL; - r = 0; - } - } + else { + syslog(LOG_ERR, "murder configuration I cannot deal with"); + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_SERVER_UNAVAILABLE)); + goto done; + } - /* local mailbox */ - if (!r) { + } else { // (config_mupdate_server) + // I'm no part of a Murder, *everything* is localcreate + goto localcreate; + } // (config_mupdate_server) + + } else { // (!localonly) + goto localcreate; + } + +localcreate: + r = mboxlist_createmailbox( + mailboxname, // const char name + mbtype, // int mbtype + partition, // const char partition + imapd_userisadmin || imapd_userisproxyadmin, // int isadmin + imapd_userid, // const char userid + imapd_authstate, // struct auth_state auth_state + localonly, // int localonly + localonly, // int forceuser + 0, // int dbonly + 1, // int notify + NULL // struct mailbox mailboxptr + ); + + // Clausing autocreate for the INBOX + if (r == IMAP_PERMISSION_DENIED) { + if (strcasecmp(name, "INBOX")) { + if ((autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { + r = mboxlist_createmailbox( + mailboxname, + 0, + partition, + 1, + imapd_userid, + imapd_authstate, + 0, + 0, + 0, + 1, + NULL + ); - /* xxx we do forced user creates on LOCALCREATE to facilitate - * mailbox moves */ - r = mboxlist_createmailbox(mailboxname, mbtype, partition, - imapd_userisadmin || imapd_userisproxyadmin, - imapd_userid, imapd_authstate, - localonly, localonly, 0, 1, NULL); + if (r) { + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); + goto done; + } - if (r == IMAP_PERMISSION_DENIED && !strcasecmp(name, "INBOX") && - (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA))) { + int autocreatequotamessage = config_getint(IMAPOPT_AUTOCREATEQUOTAMSG); - /* Auto create INBOX is always type zero */ - r = mboxlist_createmailbox(mailboxname, /*mbtype*/0, partition, - 1, imapd_userid, imapd_authstate, - 0, 0, 0, 1, NULL); + if ((autocreatequotastorage > 0) || (autocreatequotamessage > 0)) { + int newquotas[QUOTA_NUMRESOURCES]; + int res; - int autocreatequotamessage = config_getint(IMAPOPT_AUTOCREATEQUOTAMSG); - if (!r && ((autocreatequotastorage > 0) || (autocreatequotamessage > 0))) { - int res; - int newquotas[QUOTA_NUMRESOURCES]; + for (res = 0; res < QUOTA_NUMRESOURCES; res++) { + newquotas[res] = QUOTA_UNLIMITED; + } - for (res = 0 ; res < QUOTA_NUMRESOURCES ; res++) - newquotas[res] = QUOTA_UNLIMITED; - newquotas[QUOTA_STORAGE] = autocreatequotastorage; - newquotas[QUOTA_MESSAGE] = autocreatequotamessage; + newquotas[QUOTA_STORAGE] = autocreatequotastorage; + newquotas[QUOTA_MESSAGE] = autocreatequotamessage; - (void) mboxlist_setquotas(mailboxname, newquotas, 0); - } - } + (void) mboxlist_setquotas(mailboxname, newquotas, 0); + } // (autocreatequotastorage > 0) || (autocreatequotamessage > 0) - if (!r && specialuse.len) { - r = annotatemore_write(mailboxname, "/specialuse", imapd_userid, &specialuse); - if (r) { - /* XXX - failure here SHOULD cause a cleanup of the created mailbox */ - syslog(LOG_ERR, "IOERROR: failed to write specialuse for %s on %s (%s)", - imapd_userid, mailboxname, buf_cstring(&specialuse)); - } - } - } + } else { // (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA)) + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_PERMISSION_DENIED)); + goto done; - imapd_check(NULL, 0); + } // (autocreatequotastorage = config_getint(IMAPOPT_AUTOCREATEQUOTA)) - if (r) { + } else { // (!strcasecmp(name, "INBOX")) + prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(IMAP_PERMISSION_DENIED)); + goto done; + } // (!strcasecmp(name, "INBOX")) + + } else if (r) { // (r == IMAP_PERMISSION_DENIED) prot_printf(imapd_out, "%s NO %s\r\n", tag, error_message(r)); - } - else { - if (config_mupdate_server) - kick_mupdate(); + goto done; - prot_printf(imapd_out, "%s OK %s\r\n", tag, - error_message(IMAP_OK_COMPLETED)); + } else { // (r == IMAP_PERMISSION_DENIED) + prot_printf(imapd_out, "%s OK %s\r\n", tag, error_message(IMAP_OK_COMPLETED)); + goto done; + + } // (r == IMAP_PERMISSION_DENIED) + + if (specialuse.len) { + r = annotatemore_write(mailboxname, "/specialuse", imapd_userid, &specialuse); + if (r) { + /* XXX - failure here SHOULD cause a cleanup of the created mailbox */ + syslog( + LOG_ERR, + "IOERROR: failed to write specialuse for %s on %s (%s) (%s:%d)", + imapd_userid, + mailboxname, + buf_cstring(&specialuse), + __FILE__, + __LINE__ + ); + + prot_printf(imapd_out, "%s NO %s (%s:%d)\r\n", tag, error_message(r), __FILE__, __LINE__); + goto done; + } } + prot_printf(imapd_out, "%s OK Completed\r\n", tag); + + imapd_check(NULL, 0); + done: buf_free(&specialuse); } @@ -7189,11 +7289,13 @@ imapd_check(s, 0); prot_printf(s->out, "%s Setquota ", tag); - prot_printliteral(s->out, quotaroot, strlen(quotaroot)); + prot_printstring(s->out, quotaroot); prot_putc(' ', s->out); + pipe_command(s, 0); pipe_including_tag(s, tag, 0); - goto out; + return; + } mboxlist_entry_free(&mbentry); @@ -7877,12 +7979,14 @@ */ static int parse_metadata_string_or_list(const char *tag, strarray_t *entries, - int *was_singlep) + int *is_list) { int c; static struct buf arg; - *was_singlep = 0; + // Assume by default the arguments are a list of entries, + // until proven otherwise. + *is_list = 1; c = prot_getc(imapd_in); if (c == EOF) { @@ -7928,7 +8032,9 @@ } strarray_append(entries, arg.s); - *was_singlep = 1; + + // Not a list + *is_list = 0; } if (c == ' ' || c == '\r') return c; @@ -8236,6 +8342,7 @@ annotate_state_t *state = arock->state; mbentry_t *mbentry = NULL; char int_mboxname[MAX_MAILBOX_BUFFER]; + char ext_mboxname[MAX_MAILBOX_BUFFER]; int r; /* Suppress any output of a partial match */ @@ -8271,6 +8378,11 @@ if (r) goto out; + // Store the external name in the mbentry as ext_name, for later reference + (*imapd_namespace.mboxname_toexternal)(&imapd_namespace, int_mboxname, imapd_userid, ext_mboxname); + mbentry->ext_name = xmalloc(sizeof(ext_mboxname)+1); + strlcpy(mbentry->ext_name, ext_mboxname, sizeof(ext_mboxname)); + r = arock->proc(state, arock->data); arock->nseen++; @@ -8507,7 +8619,7 @@ strarray_t lists[3] = { STRARRAY_INITIALIZER, STRARRAY_INITIALIZER, STRARRAY_INITIALIZER }; - int was_single[3] = { 0, 0, 0 }; + int is_list[3] = { 1, 1, 1 }; int nlists = 0; strarray_t *options = NULL; strarray_t *mboxes = NULL; @@ -8529,22 +8641,35 @@ while (nlists < 3) { - c = parse_metadata_string_or_list(tag, &lists[nlists], &was_single[nlists]); - if (c == EOF) - goto missingargs; + c = parse_metadata_string_or_list(tag, &lists[nlists], &is_list[nlists]); + if (c == EOF) { + // Note we have not yet incremented nlists, this should read as + // "not yet two 'lists'", the minimum set of arguments. + if (nlists < 1) { + goto missingargs; + } + } + nlists++; - if (c == '\r') + if (c == '\r' || c == EOF) break; } /* check for CRLF */ - if (c == '\r') c = prot_getc(imapd_in); - if (c != '\n') { - prot_printf(imapd_out, - "%s BAD Unexpected extra arguments to Getannotation\r\n", - tag); + if (c == '\r') { + + c = prot_getc(imapd_in); + + if (c != '\n') { + prot_printf(imapd_out, + "%s BAD Unexpected extra arguments to Getannotation\r\n", + tag); + eatline(imapd_in, c); + goto freeargs; + } + } else { + // Make sure this line is gone eatline(imapd_in, c); - goto freeargs; } /* @@ -8581,7 +8706,7 @@ if (nlists == 2) { /* no options */ mboxes = &lists[0]; - mbox_is_pattern = was_single[0]; + mbox_is_pattern = is_list[0]; } if (nlists == 3) { /* options, either before or after */ @@ -8595,12 +8720,12 @@ /* (options) (mailboxes) */ options = &lists[0]; mboxes = &lists[1]; - mbox_is_pattern = was_single[1]; + mbox_is_pattern = is_list[1]; break; case 2: /* (mailboxes) (options) */ mboxes = &lists[0]; - mbox_is_pattern = was_single[0]; + mbox_is_pattern = is_list[0]; options = &lists[1]; break; case 3: @@ -8696,7 +8821,7 @@ tag, error_message(IMAP_OK_COMPLETED)); } - freeargs: +freeargs: strarray_fini(&lists[0]); strarray_fini(&lists[1]); strarray_fini(&lists[2]);
View file
cyrus-imapd-2.5.tar.gz/imap/mboxlist.c
Changed
@@ -112,6 +112,7 @@ if (!mbentry) return; free(mbentry->name); + free(mbentry->ext_name); free(mbentry->partition); free(mbentry->server); @@ -544,7 +545,7 @@ return r; } -static int mboxlist_findparent(const char *mboxname, +EXPORTED int mboxlist_findparent(const char *mboxname, mbentry_t **mbentryp) { mbentry_t *mbentry = NULL;
View file
cyrus-imapd-2.5.tar.gz/imap/mboxlist.h
Changed
@@ -77,6 +77,7 @@ /* each mailbox has the following data */ struct mboxlist_entry { char *name; + char *ext_name; time_t mtime; uint32_t uidvalidity; int mbtype; @@ -193,6 +194,10 @@ struct auth_state *auth_state, int (*proc)(), void *rock); +/* Find a mailbox's parent (if any) */ +int mboxlist_findparent(const char *mboxname, + mbentry_t **mbentryp); + /* direct access to subs DB */ int mboxlist_allsubs(const char *userid, foreach_cb *proc, void *rock); int mboxlist_allmbox(const char *prefix, foreach_cb *proc, void *rock, int incdel);
View file
cyrus-imapd-2.5.tar.gz/imap/mupdate-client.c
Changed
@@ -183,8 +183,6 @@ if (!mailbox || !location || !acl) return MUPDATE_BADPARAM; if (!handle->saslcompleted) return MUPDATE_NOAUTH; - syslog(LOG_DEBUG, "mupdate_activate for mailbox: %s, location: %s, acl: %s", mailbox, location, acl); - /* make sure we don't have a double server!partition */ if ((p = strchr(location, '!')) && strchr(p+1, '!')) return MUPDATE_BADPARAM; @@ -193,8 +191,6 @@ if (p) location = p + 1; } - syslog(LOG_DEBUG, "mupdate_activate for mailbox: %s, location: %s, acl: %s", mailbox, location, acl); - prot_printf(handle->conn->out, "X%u ACTIVATE " "{" SIZE_T_FMT "+}\r\n%s " @@ -235,8 +231,6 @@ if (p) location = p + 1; } - syslog(LOG_DEBUG, "mupdate_reserve for mailbox: %s, location: %s", mailbox, location); - prot_printf(handle->conn->out, "X%u RESERVE " "{" SIZE_T_FMT "+}\r\n%s "
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.