#include "strescape.h"
#include "ioloop.h"
#include "master-service.h"
+#include "auth-master.h"
#include "mail-storage.h"
#include "mail-storage-service.h"
#include "server-connection.h"
!DOVEADM_MAIL_SERVER_FAILED());
}
-static const char *userdb_field_find(const char *const *fields, const char *key)
+static int
+doveadm_mail_server_user_get_host(struct doveadm_mail_cmd_context *ctx,
+ const char *username, const char **host_r,
+ const char **error_r)
{
- unsigned int i, len = strlen(key);
-
- if (fields == NULL)
- return NULL;
-
- for (i = 0; fields[i] != NULL; i++) {
- if (strncmp(fields[i], key, len) == 0) {
- if (fields[i][len] == '\0')
- return "";
- if (fields[i][len] == '=')
- return fields[i]+len+1;
+ struct mail_storage_service_input input;
+ struct auth_master_connection *auth_conn;
+ struct auth_user_info info;
+ pool_t pool;
+ const char *proxy_host, *const *fields;
+ unsigned int i;
+ bool proxying;
+ int ret;
+
+ *host_r = doveadm_settings->doveadm_socket_path;
+
+ if (doveadm_settings->doveadm_proxy_port == 0)
+ return 0;
+
+ /* make sure we have an auth connection */
+ memset(&input, 0, sizeof(input));
+ input.service = "doveadm";
+ mail_storage_service_init_settings(ctx->storage_service, &input);
+
+ memset(&info, 0, sizeof(info));
+ info.service = master_service_get_name(master_service);
+
+ pool = pool_alloconly_create("auth lookup", 1024);
+ auth_conn = mail_storage_service_get_auth_conn(ctx->storage_service);
+ ret = auth_master_pass_lookup(auth_conn, username, &info,
+ pool, &fields);
+ if (ret < 0) {
+ *error_r = fields[0] != NULL ?
+ t_strdup(fields[0]) : "passdb lookup failed";
+ } else if (ret == 0) {
+ /* user not found from passdb. it could be in userdb though,
+ so just continue with the default host */
+ } else {
+ proxy_host = NULL;
+ for (i = 0; fields[i] != NULL; i++) {
+ if (strncmp(fields[i], "proxy", 5) == 0 &&
+ (fields[i][5] == '\0' || fields[i][5] == '='))
+ proxying = TRUE;
+ else if (strncmp(fields[i], "host=", 5) == 0)
+ proxy_host = fields[i]+5;
+ }
+ if (!proxying)
+ ret = 0;
+ else if (proxy_host == NULL) {
+ *error_r = "Proxy is missing destination host";
+ ret = -1;
+ } else {
+ *host_r = t_strdup_printf("%s:%u", proxy_host,
+ doveadm_settings->doveadm_proxy_port);
}
}
- return NULL;
+ pool_unref(&pool);
+ return ret;
}
int doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
- struct mail_storage_service_user *user,
- const char **error_r)
+ const char *username, const char **error_r)
{
- const struct mail_storage_service_input *input;
struct doveadm_server *server;
struct server_connection *conn;
const char *host;
char *username_dup;
+ int ret;
i_assert(cmd_ctx == ctx || cmd_ctx == NULL);
cmd_ctx = ctx;
so undo any sticks we might have added already */
doveadm_print_unstick_headers();
- input = mail_storage_service_user_get_input(user);
- if (userdb_field_find(input->userdb_fields, "proxy") != NULL) {
- host = userdb_field_find(input->userdb_fields, "host");
- if (host == NULL) {
- *error_r = "Proxy is missing destination host";
- return -1;
- }
- } else {
- host = doveadm_settings->doveadm_socket_path;
+ ret = doveadm_mail_server_user_get_host(ctx, username, &host, error_r);
+ if (ret < 0)
+ return -1;
+ if (ret == 0 &&
+ (doveadm_settings->doveadm_worker_count == 0 || doveadm_server)) {
+ /* run it ourself */
+ return 0;
}
server = doveadm_server_get(host);
conn = doveadm_server_find_unused_conn(server);
if (conn != NULL)
- doveadm_mail_server_handle(conn, input->username);
+ doveadm_mail_server_handle(conn, username);
else if (array_count(&server->connections) <
- doveadm_settings->doveadm_worker_count) {
+ I_MAX(doveadm_settings->doveadm_worker_count, 1)) {
conn = server_connection_create(server);
- doveadm_mail_server_handle(conn, input->username);
+ doveadm_mail_server_handle(conn, username);
} else {
if (array_count(&server->queue) >= DOVEADM_SERVER_QUEUE_MAX)
doveadm_server_flush_one(server);
- username_dup = i_strdup(input->username);
+ username_dup = i_strdup(username);
array_append(&server->queue, &username_dup, 1);
}
*error_r = "doveadm server failure";
- return DOVEADM_MAIL_SERVER_FAILED() ? -1 : 0;
+ return DOVEADM_MAIL_SERVER_FAILED() ? -1 : 1;
}
static struct doveadm_server *doveadm_server_find_used(void)