dovecot-2.0-sslstream: Added recipient_delimiter setting that LM...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Feb 13 02:56:19 EET 2010
details: http://hg.dovecot.org/dovecot-2.0-sslstream/rev/51160ecbacaf
changeset: 10304:51160ecbacaf
user: Timo Sirainen <tss at iki.fi>
date: Tue Nov 10 18:33:41 2009 -0500
description:
Added recipient_delimiter setting that LMTP server now uses.
diffstat:
4 files changed, 85 insertions(+), 38 deletions(-)
src/lib-lda/lda-settings.c | 7 ++
src/lib-lda/lda-settings.h | 1
src/lmtp/client.h | 3 -
src/lmtp/commands.c | 112 +++++++++++++++++++++++++++++---------------
diffs (truncated from 321 to 300 lines):
diff -r 7d9cd9b7da08 -r 51160ecbacaf src/lib-lda/lda-settings.c
--- a/src/lib-lda/lda-settings.c Tue Nov 10 15:09:10 2009 -0500
+++ b/src/lib-lda/lda-settings.c Tue Nov 10 18:33:41 2009 -0500
@@ -24,6 +24,7 @@ static const struct setting_define lda_s
DEF(SET_STR, rejection_subject),
DEF(SET_STR, rejection_reason),
DEF(SET_STR, deliver_log_format),
+ DEF(SET_STR, recipient_delimiter),
DEF(SET_BOOL, quota_full_tempfail),
DEF(SET_BOOL, lda_mailbox_autocreate),
DEF(SET_BOOL, lda_mailbox_autosubscribe),
@@ -39,6 +40,7 @@ static const struct lda_settings lda_def
MEMBER(rejection_reason)
"Your message to <%t> was automatically rejected:%n%r",
MEMBER(deliver_log_format) "msgid=%m: %$",
+ MEMBER(recipient_delimiter) "",
MEMBER(quota_full_tempfail) FALSE,
MEMBER(lda_mailbox_autocreate) FALSE,
MEMBER(lda_mailbox_autosubscribe) FALSE
@@ -81,5 +83,10 @@ static bool lda_settings_check(void *_se
i_assert(my_hostname != NULL);
set->hostname = my_hostname;
}
+ if (*set->recipient_delimiter != '\0' &&
+ set->recipient_delimiter[1] != '\0') {
+ *error_r = "recipient_delimiter must one character long";
+ return FALSE;
+ }
return TRUE;
}
diff -r 7d9cd9b7da08 -r 51160ecbacaf src/lib-lda/lda-settings.h
--- a/src/lib-lda/lda-settings.h Tue Nov 10 15:09:10 2009 -0500
+++ b/src/lib-lda/lda-settings.h Tue Nov 10 18:33:41 2009 -0500
@@ -10,6 +10,7 @@ struct lda_settings {
const char *rejection_subject;
const char *rejection_reason;
const char *deliver_log_format;
+ const char *recipient_delimiter;
bool quota_full_tempfail;
bool lda_mailbox_autocreate;
bool lda_mailbox_autosubscribe;
diff -r 7d9cd9b7da08 -r 51160ecbacaf src/lmtp/client.h
--- a/src/lmtp/client.h Tue Nov 10 15:09:10 2009 -0500
+++ b/src/lmtp/client.h Tue Nov 10 18:33:41 2009 -0500
@@ -6,7 +6,8 @@
#define CLIENT_MAIL_DATA_MAX_INMEMORY_SIZE (1024*128)
struct mail_recipient {
- const char *name;
+ const char *address;
+ const char *detail; /* +detail part is also in address */
struct mail_storage_service_user *service_user;
};
diff -r 7d9cd9b7da08 -r 51160ecbacaf src/lmtp/commands.c
--- a/src/lmtp/commands.c Tue Nov 10 15:09:10 2009 -0500
+++ b/src/lmtp/commands.c Tue Nov 10 18:33:41 2009 -0500
@@ -114,12 +114,12 @@ int cmd_mail(struct client *client, cons
return 0;
}
-static bool rcpt_is_duplicate(struct client *client, const char *name)
+static bool rcpt_is_duplicate(struct client *client, const char *address)
{
const struct mail_recipient *rcpt;
array_foreach(&client->state.rcpt_to, rcpt) {
- if (strcmp(rcpt->name, name) == 0)
+ if (strcmp(rcpt->address, address) == 0)
return TRUE;
}
return FALSE;
@@ -192,13 +192,14 @@ client_proxy_is_ourself(const struct cli
return TRUE;
}
-static bool client_proxy_rcpt(struct client *client, const char *address)
+static bool client_proxy_rcpt(struct client *client, const char *address,
+ const char *username)
{
struct auth_master_connection *auth_conn;
struct lmtp_proxy_settings set;
struct auth_user_info info;
struct mail_storage_service_input input;
- const char *args, *const *fields, *orig_address = address;
+ const char *args, *const *fields, *orig_username = username;
pool_t pool;
int ret;
@@ -215,7 +216,7 @@ static bool client_proxy_rcpt(struct cli
pool = pool_alloconly_create("auth lookup", 1024);
auth_conn = mail_storage_service_get_auth_conn(storage_service);
- ret = auth_master_pass_lookup(auth_conn, address, &info,
+ ret = auth_master_pass_lookup(auth_conn, username, &info,
pool, &fields);
if (ret <= 0) {
pool_unref(&pool);
@@ -234,15 +235,16 @@ static bool client_proxy_rcpt(struct cli
set.protocol = LMTP_CLIENT_PROTOCOL_LMTP;
set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS;
- if (!client_proxy_rcpt_parse_fields(&set, fields, &address)) {
+ if (!client_proxy_rcpt_parse_fields(&set, fields, &username)) {
/* not proxying this user */
pool_unref(&pool);
return FALSE;
}
- if (strcmp(address, orig_address) == 0 &&
+ if (strcmp(username, orig_username) == 0 &&
client_proxy_is_ourself(client, &set)) {
- i_error("Proxying to <%s> loops to itself", address);
- client_send_line(client, "554 5.4.6 Proxying loops to itself");
+ i_error("Proxying to <%s> loops to itself", username);
+ client_send_line(client, "554 5.4.6 <%s> "
+ "Proxying loops to itself", address);
pool_unref(&pool);
return FALSE;
}
@@ -300,11 +302,37 @@ static const char *lmtp_unescape_address
return str_c(str);
}
+static void rcpt_address_parse(struct client *client, const char *address,
+ const char **username_r, const char **detail_r)
+{
+ const char *p, *p2;
+
+ *username_r = address;
+ *detail_r = "";
+
+ if (*client->set->recipient_delimiter == '\0')
+ return;
+
+ p = strchr(address, *client->set->recipient_delimiter);
+ if (p != NULL) {
+ /* user+detail at domain */
+ *username_r = t_strdup_until(*username_r, p);
+ p2 = strchr(p, '@');
+ if (p2 == NULL)
+ *detail_r = p+1;
+ else {
+ *detail_r = t_strdup_until(p+1, p2);
+ *username_r = t_strconcat(*username_r, p2, NULL);
+ }
+ }
+}
+
int cmd_rcpt(struct client *client, const char *args)
{
struct mail_recipient rcpt;
struct mail_storage_service_input input;
- const char *name, *error = NULL, *addr, *const *argv;
+ const char *address, *username, *detail;
+ const char *error = NULL, *arg, *const *argv;
unsigned int len;
int ret = 0;
@@ -315,21 +343,21 @@ int cmd_rcpt(struct client *client, cons
argv = t_strsplit(args, " ");
if (argv == NULL)
- addr = "";
+ arg = "";
else {
- addr = argv[0];
+ arg = argv[0];
argv++;
}
- len = strlen(addr);
- if (strncasecmp(addr, "TO:<", 4) != 0 || addr[len-1] != '>') {
+ len = strlen(arg);
+ if (strncasecmp(arg, "TO:<", 4) != 0 || arg[len-1] != '>') {
client_send_line(client, "501 5.5.4 Invalid parameters");
return 0;
}
memset(&rcpt, 0, sizeof(rcpt));
- name = lmtp_unescape_address(t_strndup(addr + 4, len - 5));
-
- if (rcpt_is_duplicate(client, name)) {
+ address = lmtp_unescape_address(t_strndup(arg + 4, len - 5));
+
+ if (rcpt_is_duplicate(client, address)) {
client_send_line(client, "250 2.1.5 OK, ignoring duplicate");
return 0;
}
@@ -338,16 +366,17 @@ int cmd_rcpt(struct client *client, cons
client_send_line(client, "501 5.5.4 Unsupported options");
return 0;
}
+ rcpt_address_parse(client, address, &username, &detail);
if (client->lmtp_set->lmtp_proxy) {
- if (client_proxy_rcpt(client, name))
+ if (client_proxy_rcpt(client, address, username))
return 0;
}
memset(&input, 0, sizeof(input));
input.service = "lmtp";
input.module = "lda";
- input.username = name;
+ input.username = username;
input.local_ip = client->local_ip;
input.remote_ip = client->remote_ip;
@@ -356,16 +385,18 @@ int cmd_rcpt(struct client *client, cons
if (ret < 0) {
i_error("User lookup failed: %s", error);
- client_send_line(client, ERRSTR_TEMP_USERDB_FAIL, name);
+ client_send_line(client, ERRSTR_TEMP_USERDB_FAIL, username);
return 0;
}
if (ret == 0) {
client_send_line(client,
- "550 5.1.1 <%s> User doesn't exist", name);
- return 0;
- }
-
- rcpt.name = p_strdup(client->state_pool, name);
+ "550 5.1.1 <%s> User doesn't exist: %s",
+ address, username);
+ return 0;
+ }
+
+ rcpt.address = p_strdup(client->state_pool, address);
+ rcpt.detail = p_strdup(client->state_pool, detail);
array_append(&client->state.rcpt_to, &rcpt, 1);
client_send_line(client, "250 2.1.5 OK");
@@ -403,18 +434,23 @@ client_deliver(struct client *client, co
{
struct mail_deliver_context dctx;
struct mail_storage *storage;
+ const struct mail_storage_service_input *input;
void **sets;
- const char *error;
+ const char *error, *username;
enum mail_error mail_error;
int ret;
+ input = mail_storage_service_user_get_input(rcpt->service_user);
+ username = t_strdup(input->username);
+
i_set_failure_prefix(t_strdup_printf("lmtp(%s, %s): ",
- my_pid, rcpt->name));
+ my_pid, username));
if (mail_storage_service_next(storage_service, rcpt->service_user,
&client->state.dest_user,
&error) < 0) {
i_error("%s", error);
- client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, rcpt->name);
+ client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
+ rcpt->address);
return -1;
}
sets = mail_storage_service_user_get_set(rcpt->service_user);
@@ -426,8 +462,8 @@ client_deliver(struct client *client, co
dctx.src_mail = src_mail;
dctx.src_envelope_sender = client->state.mail_from;
dctx.dest_user = client->state.dest_user;
- dctx.dest_addr = rcpt->name;
- dctx.dest_mailbox_name = "INBOX";
+ dctx.dest_addr = rcpt->address;
+ dctx.dest_mailbox_name = *rcpt->detail == '\0' ? "INBOX" : rcpt->detail;
dctx.save_dest_mail = array_count(&client->state.rcpt_to) > 1 &&
client->state.first_saved_mail == NULL;
@@ -437,13 +473,13 @@ client_deliver(struct client *client, co
client->state.first_saved_mail = dctx.dest_mail;
}
client_send_line(client, "250 2.0.0 <%s> %s Saved",
- rcpt->name, client->state.session_id);
+ rcpt->address, client->state.session_id);
ret = 0;
} else if (storage == NULL) {
/* This shouldn't happen */
i_error("BUG: Saving failed to unknown storage");
client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
- rcpt->name);
+ rcpt->address);
ret = -1;
} else {
error = mail_storage_get_last_error(storage, &mail_error);
@@ -451,10 +487,10 @@ client_deliver(struct client *client, co
client_send_line(client, "%s <%s> %s",
dctx.set->quota_full_tempfail ?
"452 4.2.2" : "552 5.2.2",
- rcpt->name, error);
+ rcpt->address, error);
} else {
client_send_line(client, "451 4.2.0 <%s> %s",
- rcpt->name, error);
+ rcpt->address, error);
}
ret = -1;
}
@@ -488,8 +524,10 @@ static void client_rcpt_fail_all(struct
More information about the dovecot-cvs
mailing list