commands.c revision e20e638805c4bd54e039891a3e92760b1dfa189a
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen#define ERRSTR_TEMP_MAILBOX_FAIL "451 4.3.0 <%s> Temporary internal error"
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen#define ERRSTR_TEMP_USERDB_FAIL "451 4.3.0 <%s> Temporary user lookup failure"
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen#define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint cmd_lhlo(struct client *client, const char *args ATTR_UNUSED)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen client_send_line(client, "250-%s", client->my_domain);
f7fe4f81c0887196a1f938d83ae1cdba03cfad85Josef 'Jeff' Sipek client_send_line(client, "250-ENHANCEDSTATUSCODES");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint cmd_mail(struct client *client, const char *args)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen unsigned int len;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "503 5.5.1 MAIL already given");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (strncasecmp(addr, "FROM:<", 6) != 0 || addr[len-1] != '>') {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "501 5.5.4 Invalid parameters");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen else if (strcasecmp(*argv, "BODY=8BITMIME") == 0)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen "501 5.5.4 Unsupported options");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen p_strndup(client->state_pool, addr + 6, len - 7);
139cbf8d9e1cc0c65d985f525756fe47a7bfada6Timo Sirainen p_array_init(&client->state.rcpt_to, client->state_pool, 64);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic bool rcpt_is_duplicate(struct client *client, const char *name)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenclient_proxy_rcpt_parse_fields(struct lmtp_proxy_settings *set,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *const *args, const char **address)
512f492f410fdaefb2f58e19c2b067ef20fb4adfTimo Sirainen /* changing the username */
512f492f410fdaefb2f58e19c2b067ef20fb4adfTimo Sirainen /* just ignore it */
d29e35631075b8c172ce781b85fd1cdaf0a400fdTimo Sirainenclient_proxy_is_ourself(const struct client *client,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic bool client_proxy_rcpt(struct client *client, const char *address)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *args, *const *fields, *orig_address = address;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen info.service = master_service_get_name(master_service);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen pool = pool_alloconly_create("auth lookup", 1024);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen auth_conn = mail_storage_service_multi_get_auth_conn(multi_service);
35083063d0e432d0cf78206b5929750e613ad772Timo Sirainen ret = auth_master_pass_lookup(auth_conn, address, &info,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, ERRSTR_TEMP_USERDB_FAIL,
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen /* user not found from passdb. try userdb also. */
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS;
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen if (!client_proxy_rcpt_parse_fields(&set, fields, &address)) {
d927bc5618696157fc55eb1f11b5cab05400ed52Timo Sirainen /* not proxying this user */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen i_error("Proxying to <%s> loops to itself", address);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "554 5.4.6 Proxying loops to itself");
0671e0ae0cfd8d5d671a0c2a75a070c8e2a39fecTimo Sirainen client->proxy = lmtp_proxy_init(client->set->hostname,
0671e0ae0cfd8d5d671a0c2a75a070c8e2a39fecTimo Sirainen lmtp_proxy_mail_from(client->proxy, t_strdup_printf(
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (lmtp_proxy_add_rcpt(client->proxy, address, &set) < 0)
d927bc5618696157fc55eb1f11b5cab05400ed52Timo Sirainen client_send_line(client, ERRSTR_TEMP_REMOTE_FAILURE);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint cmd_rcpt(struct client *client, const char *args)
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *name, *error = NULL, *addr, *const *argv;
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen unsigned int len;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "503 5.5.1 MAIL needed first");
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (strncasecmp(addr, "TO:<", 4) != 0 || addr[len-1] != '>') {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "501 5.5.4 Invalid parameters");
f534c0d42f1470fca8e4ff3493c94927bf600260Timo Sirainen client_send_line(client, "250 2.1.5 OK, ignoring duplicate");
1453e7c587b98f93e1434aa0b147933948dbb50fTimo Sirainen client_send_line(client, "501 5.5.4 Unsupported options");
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen ret = mail_storage_service_multi_lookup(multi_service, &input,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen client_send_line(client, ERRSTR_TEMP_USERDB_FAIL, name);
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen rcpt.name = p_strdup(client->state_pool, name);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen array_append(&client->state.rcpt_to, &rcpt, 1);
5b82f3b2f544cf891a390083f1bcf60409be20b8Timo Sirainenint cmd_quit(struct client *client, const char *args ATTR_UNUSED)
fedb7a111ba2102edce8e55a1ba77cf907c6add9Timo Sirainen client_destroy(client, "221 2.0.0", "Logged out");
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint cmd_vrfy(struct client *client, const char *args ATTR_UNUSED)
4ed1c0fedf33299264a319b2c4e0fe2465ea321bTimo Sirainen client_send_line(client, "252 2.3.3 Try RCPT instead");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenint cmd_rset(struct client *client, const char *args ATTR_UNUSED)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenint cmd_noop(struct client *client, const char *args ATTR_UNUSED)
d29e35631075b8c172ce781b85fd1cdaf0a400fdTimo Sirainenclient_deliver(struct client *client, const struct mail_recipient *rcpt,
cc2c73be39dfe988f52c0370667e3882d01c63a2Timo Sirainen i_set_failure_prefix(t_strdup_printf("lmtp(%s): ", rcpt->name));
cc2c73be39dfe988f52c0370667e3882d01c63a2Timo Sirainen if (mail_storage_service_multi_next(multi_service, rcpt->multi_user,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL, rcpt->name);
512f492f410fdaefb2f58e19c2b067ef20fb4adfTimo Sirainen sets = mail_storage_service_multi_user_get_set(rcpt->multi_user);
512f492f410fdaefb2f58e19c2b067ef20fb4adfTimo Sirainen dctx.pool = pool_alloconly_create("mail delivery", 1024);
31327a74b86728e201fcedd0acaecf69d077bf1dTimo Sirainen dctx.src_envelope_sender = client->state.mail_from;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen dctx.save_dest_mail = array_count(&client->state.rcpt_to) > 1 &&
708efcd8581258763289b95cde119ca9423641d8Timo Sirainen i_assert(client->state.first_saved_mail == NULL);
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen client->state.first_saved_mail = dctx.dest_mail;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "250 2.0.0 <%s> Saved", rcpt->name);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* This shouldn't happen */
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen i_error("BUG: Saving failed to unknown storage");
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen error = mail_storage_get_last_error(storage, &mail_error);
return ret;
unsigned int count;
int ret;
src_mail);
if (ret == 0)
return TRUE;
return FALSE;
return input;
static const char *wanted_headers[] = {
0, headers_ctx);
return ret;
int fd;
const unsigned char *data;
if (ret == 0)