commands.c revision a795ff053b41be95cb94a33cd5501f8d2e843e20
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2009-2012 Dovecot authors, see the included COPYING file */
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen#define ERRSTR_TEMP_MAILBOX_FAIL "451 4.3.0 <%s> Temporary internal error"
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen#define ERRSTR_TEMP_USERDB_FAIL_PREFIX "451 4.3.0 <%s> "
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen ERRSTR_TEMP_USERDB_FAIL_PREFIX "Temporary user lookup failure"
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen#define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint cmd_lhlo(struct client *client, const char *args)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *p;
c8cf8a605e0ddea7cb36fe04551aeca5090e684bTimo Sirainen client_send_line(client, "501 Missing hostname");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* domain / address-literal */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen rfc822_parser_init(&parser, (const unsigned char *)args, strlen(args),
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "250-%s", client->my_domain);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "250-ENHANCEDSTATUSCODES");
33a9c31657771606be5942b55f5f91a5606b2199Timo Sirainenstatic int parse_address(const char *str, const char **address_r,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char **rest_r)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* "quoted-string"@domain */
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainenint cmd_mail(struct client *client, const char *args)
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen client_send_line(client, "503 5.5.1 MAIL already given");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "501 5.5.4 Invalid parameters");
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen else if (strcasecmp(*argv, "BODY=8BITMIME") == 0)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen "501 5.5.4 Unsupported options");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client->state.mail_from = p_strdup(client->state_pool, addr);
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen p_array_init(&client->state.rcpt_to, client->state_pool, 64);
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainenclient_proxy_rcpt_parse_fields(struct lmtp_proxy_settings *set,
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen const char *const *args, const char **address)
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen /* changing the username */
b1c42176a65dbe9c83a0af766e6bd8315530f3a5Timo Sirainen /* just ignore it */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenclient_proxy_is_ourself(const struct client *client,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic const char *
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenaddress_add_detail(struct client *client, const char *username,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *delim = client->set->recipient_delimiter;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen return t_strconcat(username, delim, detail, NULL);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen return t_strconcat(username, delim, detail, domain, NULL);
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainenstatic bool client_proxy_rcpt(struct client *client, const char *address,
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen const char *args, *const *fields, *errstr, *orig_username = username;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mail_storage_service_init_settings(storage_service, &input);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen info.service = master_service_get_name(master_service);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen pool = pool_alloconly_create("auth lookup", 1024);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen auth_conn = mail_storage_service_get_auth_conn(storage_service);
c8cf8a605e0ddea7cb36fe04551aeca5090e684bTimo Sirainen ret = auth_master_pass_lookup(auth_conn, username, &info,
9762e4f86950549c8186c7d3d4fa4a6b533ea848Timo Sirainen errstr = ret < 0 && fields[0] != NULL ? t_strdup(fields[0]) :
e930af34580510d2fe58628d270dbaf786e86248Timo Sirainen t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL, address);
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen /* user not found from passdb. try userdb also. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (!client_proxy_rcpt_parse_fields(&set, fields, &username)) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* not proxying this user */
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen /* username changed. change the address as well */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen address = address_add_detail(client, username, detail);
4ac2d38239cea8090154e17faefd77de5a71d882Timo Sirainen } else if (client_proxy_is_ourself(client, &set)) {
c7194d1d3872ffb2901737e1df337cc227a3fa77Timo Sirainen i_error("Proxying to <%s> loops to itself", username);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (array_count(&client->state.rcpt_to) != 0) {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen "Can't handle mixed proxy/non-proxy destinations",
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client->proxy = lmtp_proxy_init(client->set->hostname,
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen lmtp_proxy_mail_from(client->proxy, t_strdup_printf(
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (lmtp_proxy_add_rcpt(client->proxy, address, &set) < 0)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, ERRSTR_TEMP_REMOTE_FAILURE);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic const char *lmtp_unescape_address(const char *name)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *p;
77c462c3a415536f9c87028ee34546ee96fd1445Timo Sirainen /* quoted-string local-part. drop the quotes unless there's a
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen '@' character inside or there's an error. */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (*p == '\0')
return name;
return name;
return name;
return name;
const char *p, *domain;
unsigned int len;
if (p == NULL)
if (p == NULL)
if (p == NULL)
int ret = 0;
if (ret < 0) {
username);
if (ret == 0) {
address);
void **sets;
int ret;
ret = 0;
return ret;
unsigned int count;
int ret;
if (ret == 0)
return TRUE;
return FALSE;
FALSE);
return cinput;
static const char *wanted_headers[] = {
&box) < 0) {
if (seteuid(0) < 0)
if (old_uid == 0) {
if (seteuid(0) < 0)
return ret;
int fd;
const unsigned char *data;
if (ret == 0)