void mail_storage_service_all_init(struct mail_storage_service_ctx *ctx) { enum auth_master_flags flags = 0; (void)mail_storage_service_all_iter_deinit(ctx); mail_storage_service_init_settings(ctx, NULL); /* create a new connection, because the iteration might take a while and we might want to do USER lookups during it, which don't mix well in the same connection. */ if (ctx->debug) flags |= AUTH_MASTER_FLAG_DEBUG; ctx->iter_conn = auth_master_init(auth_master_get_socket_path(ctx->conn), flags); ctx->auth_list = auth_master_user_list_init(ctx->iter_conn, "", NULL); }
static bool client_proxy_rcpt(struct client *client, const char *address, const char *username, const char *detail) { struct auth_master_connection *auth_conn; struct lmtp_proxy_rcpt_settings set; struct auth_user_info info; struct mail_storage_service_input input; const char *args, *const *fields, *errstr, *orig_username = username; pool_t pool; int ret; memset(&input, 0, sizeof(input)); input.module = input.service = "lmtp"; mail_storage_service_init_settings(storage_service, &input); memset(&info, 0, sizeof(info)); info.service = master_service_get_name(master_service); info.local_ip = client->local_ip; info.remote_ip = client->remote_ip; info.local_port = client->local_port; info.remote_port = client->remote_port; pool = pool_alloconly_create("auth lookup", 1024); auth_conn = mail_storage_service_get_auth_conn(storage_service); ret = auth_master_pass_lookup(auth_conn, username, &info, pool, &fields); if (ret <= 0) { errstr = ret < 0 && fields[0] != NULL ? t_strdup(fields[0]) : t_strdup_printf(ERRSTR_TEMP_USERDB_FAIL, address); pool_unref(&pool); if (ret < 0) { client_send_line(client, "%s", errstr); return TRUE; } else { /* user not found from passdb. try userdb also. */ return FALSE; } } memset(&set, 0, sizeof(set)); set.port = client->local_port; set.protocol = LMTP_CLIENT_PROTOCOL_LMTP; set.timeout_msecs = LMTP_PROXY_DEFAULT_TIMEOUT_MSECS; if (!client_proxy_rcpt_parse_fields(&set, fields, &username)) { /* not proxying this user */ pool_unref(&pool); return FALSE; } if (strcmp(username, orig_username) != 0) { /* username changed. change the address as well */ if (*detail == '\0') address = username; else address = address_add_detail(client, username, detail); } else if (client_proxy_is_ourself(client, &set)) { 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 TRUE; } if (client->proxy_ttl <= 1) { i_error("Proxying to <%s> appears to be looping (TTL=0)", username); client_send_line(client, "554 5.4.6 <%s> " "Proxying appears to be looping (TTL=0)", username); pool_unref(&pool); return TRUE; } if (array_count(&client->state.rcpt_to) != 0) { client_send_line(client, "451 4.3.0 <%s> " "Can't handle mixed proxy/non-proxy destinations", address); pool_unref(&pool); return TRUE; } if (client->proxy == NULL) { struct lmtp_proxy_settings proxy_set; memset(&proxy_set, 0, sizeof(proxy_set)); proxy_set.my_hostname = client->my_domain; proxy_set.dns_client_socket_path = dns_client_socket_path; proxy_set.session_id = client->state.session_id; proxy_set.source_ip = client->remote_ip; proxy_set.source_port = client->remote_port; proxy_set.proxy_ttl = client->proxy_ttl-1; client->proxy = lmtp_proxy_init(&proxy_set, client->output); if (client->state.mail_body_8bitmime) args = " BODY=8BITMIME"; else if (client->state.mail_body_7bit) args = " BODY=7BIT"; else args = ""; lmtp_proxy_mail_from(client->proxy, t_strdup_printf( "<%s>%s", client->state.mail_from, args)); } if (lmtp_proxy_add_rcpt(client->proxy, address, &set) < 0) client_send_line(client, ERRSTR_TEMP_REMOTE_FAILURE); else client_send_line(client, "250 2.1.5 OK"); pool_unref(&pool); return TRUE; }