commands.c revision 3b22894b8805b186c73d8b754001e8d7e944be85
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen/* Copyright (c) 2009-2010 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_PREFIX "451 4.3.0 <%s> "
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen ERRSTR_TEMP_USERDB_FAIL_PREFIX "Temporary user lookup failure"
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen#define LMTP_PROXY_DEFAULT_TIMEOUT_MSECS (1000*30)
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainenint cmd_lhlo(struct client *client, const char *args)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *p;
4654f788834c9d7920a351306b89cf5d1c21772eTimo 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");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client->state.lhlo = p_strdup(client->state_pool, str_c(domain));
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");
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen p_strndup(client->state_pool, addr + 6, len - 7);
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen p_array_init(&client->state.rcpt_to, client->state_pool, 64);
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainenstatic bool rcpt_is_duplicate(struct client *client, const char *address)
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainenclient_proxy_rcpt_parse_fields(struct lmtp_proxy_settings *set,
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen const char *const *args, const char **address)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* changing the username */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* just ignore it */
4654f788834c9d7920a351306b89cf5d1c21772eTimo 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, *errstr, *orig_username = username;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen mail_storage_service_init_settings(storage_service, &input);
4654f788834c9d7920a351306b89cf5d1c21772eTimo 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);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen ret = auth_master_pass_lookup(auth_conn, username, &info,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen errstr = ret < 0 && fields[0] != NULL ? t_strdup(fields[0]) :
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL, address);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* user not found from passdb. try userdb also. */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS;
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen if (!client_proxy_rcpt_parse_fields(&set, fields, &username)) {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen /* not proxying this user */
c7194d1d3872ffb2901737e1df337cc227a3fa77Timo Sirainen i_error("Proxying to <%s> loops to itself", username);
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo 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)
c4c9be10781e1a16b3b001dc6b0461c4640da101Timo Sirainen const char *p;
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen /* quoted-string local-part. drop the quotes unless there's a
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen '@' character inside or there's an error. */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (*p == '\0')
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (*p == '\\') {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (*p == '@')
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenstatic void rcpt_address_parse(struct client *client, const char *address,
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char **username_r, const char **detail_r)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *p, *p2;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (*client->set->recipient_delimiter == '\0')
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen p = strstr(address, client->set->recipient_delimiter);
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen /* user+detail@domain */
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen *username_r = t_strconcat(*username_r, p2, NULL);
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint cmd_rcpt(struct client *client, const char *args)
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen const char *address, *username, *detail, *prefix;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen unsigned int len;
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "503 5.5.1 MAIL needed first");
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen if (strncasecmp(arg, "TO:<", 4) != 0 || arg[len-1] != '>') {
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainen client_send_line(client, "501 5.5.4 Invalid parameters");
if (ret < 0) {
username);
if (ret == 0) {
void **sets;
int ret;
ret = 0;
if (old_uid == 0) {
if (seteuid(0) < 0)
return ret;
unsigned int count;
int ret;
src_mail);
if (ret == 0)
return TRUE;
return FALSE;
FALSE);
return cinput;
static const char *wanted_headers[] = {
0, headers_ctx);
if (timeout) {
const char *host;
return ret;
int fd;
const unsigned char *data;
if (ret == 0)