From: Timo Sirainen Date: Mon, 2 Aug 2010 15:25:19 +0000 (+0100) Subject: imap: imap_capability = +foo only adds new capabilities instead of replacing everything. X-Git-Tag: 2.0.rc4~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71bf346cddcec75a7394b2acf6f954808383aa4c;p=thirdparty%2Fdovecot%2Fcore.git imap: imap_capability = +foo only adds new capabilities instead of replacing everything. --- diff --git a/doc/example-config/conf.d/20-imap.conf b/doc/example-config/conf.d/20-imap.conf index b432aa313a..5f8725e6dd 100644 --- a/doc/example-config/conf.d/20-imap.conf +++ b/doc/example-config/conf.d/20-imap.conf @@ -20,7 +20,8 @@ protocol imap { # %o - total number of bytes sent to client #imap_logout_format = bytes=%i/%o - # Override the IMAP CAPABILITY response. + # Override the IMAP CAPABILITY response. If the value begins with '+', + # add the given capabilities on top of the defaults (e.g. +XFOO XBAR). #imap_capability = # How long to wait between "OK Still here" notifications when client is diff --git a/src/imap-login/client-authenticate.c b/src/imap-login/client-authenticate.c index 87ce71957d..883f4acdb3 100644 --- a/src/imap-login/client-authenticate.c +++ b/src/imap-login/client-authenticate.c @@ -18,21 +18,17 @@ #include -const char *client_authenticate_get_capabilities(struct client *client) +void client_authenticate_get_capabilities(struct client *client, string_t *str) { const struct auth_mech_desc *mech; unsigned int i, count; - string_t *str; - str = t_str_new(128); mech = sasl_server_get_advertised_mechs(client, &count); for (i = 0; i < count; i++) { str_append_c(str, ' '); str_append(str, "AUTH="); str_append(str, mech[i].name); } - - return str_c(str); } bool imap_client_auth_handle_reply(struct client *client, diff --git a/src/imap-login/client-authenticate.h b/src/imap-login/client-authenticate.h index 7d9f4226d8..118a745fe8 100644 --- a/src/imap-login/client-authenticate.h +++ b/src/imap-login/client-authenticate.h @@ -3,7 +3,7 @@ struct imap_arg; -const char *client_authenticate_get_capabilities(struct client *client); +void client_authenticate_get_capabilities(struct client *client, string_t *str); bool imap_client_auth_handle_reply(struct client *client, const struct client_auth_reply *reply); diff --git a/src/imap-login/client.c b/src/imap-login/client.c index 85a8becde8..bb9140b74d 100644 --- a/src/imap-login/client.c +++ b/src/imap-login/client.c @@ -62,16 +62,25 @@ bool client_skip_line(struct imap_client *client) static const char *get_capability(struct client *client) { struct imap_client *imap_client = (struct imap_client *)client; - const char *auths, *cap_str; - - cap_str = *imap_client->set->imap_capability != '\0' ? - imap_client->set->imap_capability : CAPABILITY_BANNER_STRING; - auths = client_authenticate_get_capabilities(client); - return t_strconcat(cap_str, - (ssl_initialized && !client->tls) ? " STARTTLS" : "", - client->set->disable_plaintext_auth && - !client->secured ? " LOGINDISABLED" : "", - auths, NULL); + string_t *cap_str = t_str_new(256); + + if (*imap_client->set->imap_capability == '\0') + str_append(cap_str, CAPABILITY_BANNER_STRING); + else if (*imap_client->set->imap_capability != '+') + str_append(cap_str, imap_client->set->imap_capability); + else { + str_append(cap_str, CAPABILITY_BANNER_STRING); + str_append_c(cap_str, ' '); + str_append(cap_str, imap_client->set->imap_capability + 1); + } + + if (ssl_initialized && !client->tls) + str_append(cap_str, " STARTTLS"); + if (client->set->disable_plaintext_auth && !client->secured) + str_append(cap_str, " LOGINDISABLED"); + + client_authenticate_get_capabilities(client, cap_str); + return str_c(cap_str); } static int cmd_capability(struct imap_client *imap_client) diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index ff38c19fa6..dee92bf854 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -72,8 +72,16 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, client->capability_string = str_new(client->pool, sizeof(CAPABILITY_STRING)+64); - str_append(client->capability_string, *set->imap_capability != '\0' ? - set->imap_capability : CAPABILITY_STRING); + + if (*set->imap_capability == '\0') + str_append(client->capability_string, CAPABILITY_STRING); + else if (*set->imap_capability != '+') + str_append(client->capability_string, set->imap_capability); + else { + str_append(client->capability_string, CAPABILITY_STRING); + str_append_c(client->capability_string, ' '); + str_append(client->capability_string, set->imap_capability + 1); + } ident = mail_user_get_anvil_userip_ident(client->user); if (ident != NULL) {