bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen (internal_failure || master_service_is_killed(master_service))
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenstatic HASH_TABLE(char *, struct doveadm_server *) servers;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic struct doveadm_mail_cmd_context *cmd_ctx;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic void doveadm_mail_server_handle(struct server_connection *conn,
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainendoveadm_server_get(struct doveadm_mail_cmd_context *ctx, const char *name)
1b7459fda7de40f963e64da1886af68ad05fd10dTimo Sirainen const char *p;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen server_pool = pool_alloconly_create("doveadm servers", 1024*16);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&servers, server_pool, 0, str_hash, strcmp);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen server = p_new(server_pool, struct doveadm_server, 1);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen server->name = dup_name = p_strdup(server_pool, name);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen p_array_init(&server->connections, server_pool,
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainendoveadm_server_find_unused_conn(struct doveadm_server *server)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic bool doveadm_server_have_used_connections(struct doveadm_server *server)
956b8eea7ae479a38b25175447fc8eac2df30480Timo Sirainenstatic void doveadm_cmd_callback(int exit_code, const char *error,
ab530005cbeae9ea2301ef884c913e51870ea912Timo Sirainen struct doveadm_mail_server_cmd *servercmd = context;
ab530005cbeae9ea2301ef884c913e51870ea912Timo Sirainen server_connection_get_server(servercmd->conn);
ab530005cbeae9ea2301ef884c913e51870ea912Timo Sirainen const char *username = t_strdup(servercmd->username);
ecd14e4323bfe9953db9be89dc75858592018a75Timo Sirainen server->name, cmd_ctx->cmd->name, username, error);
ab530005cbeae9ea2301ef884c913e51870ea912Timo Sirainen i_error("%s: No such user: %s", server->name, username);
8ad7aa4ddf9e37fc1aefdf84f90071f49fc2619cTimo Sirainen if (cmd_ctx->exit_code == 0 || exit_code == EX_TEMPFAIL)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen char *const *usernamep = array_idx(&server->queue, 0);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen conn = doveadm_server_find_unused_conn(server);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic void doveadm_mail_server_handle(struct server_connection *conn,
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen unsigned int i;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen /* <flags> <username> <command> [<args>] */
d03a871a77f8ec36f48f5fea98d810e51b186fdbTimo Sirainen str_append_tabescaped(cmd, cmd_ctx->cmd->name);
10b8040903b1d1591f1d44552ff466c8789b8814Timo Sirainen for (i = 0; cmd_ctx->full_args[i] != NULL; i++) {
d03a871a77f8ec36f48f5fea98d810e51b186fdbTimo Sirainen str_append_tabescaped(cmd, cmd_ctx->full_args[i]);
ab530005cbeae9ea2301ef884c913e51870ea912Timo Sirainen servercmd = i_new(struct doveadm_mail_server_cmd, 1);
32c779d5d0b3dabc697408e6b5d9d2e652180b33Timo Sirainen server_connection_cmd(conn, str_c(cmd), cmd_ctx->cmd_input,
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic void doveadm_server_flush_one(struct doveadm_server *server)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen unsigned int count = array_count(&server->queue);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen } while (array_count(&server->queue) == count &&
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen doveadm_server_have_used_connections(server) &&
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainendoveadm_mail_server_user_get_host(struct doveadm_mail_cmd_context *ctx,
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen const struct mail_storage_service_input *input,
ae369149607cd8b9e3f6afdcf7c16cff1abdda54Timo Sirainen const char **error_r)
a07e0d83e1fd465d7ee13771ded72a8d152b5bbbTimo Sirainen const char *auth_socket_path, *proxy_host, *proxy_hostip, *const *fields;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch unsigned int i;
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen /* make sure we have an auth connection */
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen mail_storage_service_init_settings(ctx->storage_service, input);
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen info.service = master_service_get_name(master_service);
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen pool = pool_alloconly_create("auth lookup", 1024);
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen auth_conn = mail_storage_service_get_auth_conn(ctx->storage_service);
cd8bd47fd52b3835253b0f341c8cab3d40a50cecTimo Sirainen auth_socket_path = auth_master_get_socket_path(auth_conn);
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen ret = auth_master_pass_lookup(auth_conn, input->username, &info,
cd8bd47fd52b3835253b0f341c8cab3d40a50cecTimo Sirainen *error_r = t_strdup_printf("%s: %s (to see if user is proxied, "
7bf0bc502847098575465a650c5967d17bc0e6ceTimo Sirainen "because doveadm_port is set)",
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen } else if (ret == 0) {
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen /* user not found from passdb. it could be in userdb though,
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen so just continue with the default host */
a07e0d83e1fd465d7ee13771ded72a8d152b5bbbTimo Sirainen proxy_host = NULL; proxy_hostip = NULL; proxying = FALSE;
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen (fields[i][5] == '\0' || fields[i][5] == '='))
a07e0d83e1fd465d7ee13771ded72a8d152b5bbbTimo Sirainen else if (strncmp(fields[i], "hostip=", 7) == 0)
ae369149607cd8b9e3f6afdcf7c16cff1abdda54Timo Sirainen else if (strncmp(fields[i], "destuser=", 9) == 0)
22d87bd260a4476da878df48206eba0b37322a6cTimo Sirainen else if (strncmp(fields[i], "port=", 5) == 0) {
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (net_str2port(fields[i]+5, &proxy_port) < 0)
cd8bd47fd52b3835253b0f341c8cab3d40a50cecTimo Sirainen *error_r = t_strdup_printf("%s: Proxy is missing destination host",
cd8bd47fd52b3835253b0f341c8cab3d40a50cecTimo Sirainen if (strstr(auth_socket_path, "/auth-userdb") != NULL) {
cd8bd47fd52b3835253b0f341c8cab3d40a50cecTimo Sirainen "%s (maybe set auth_socket_path=director-userdb)",
22d87bd260a4476da878df48206eba0b37322a6cTimo Sirainen *host_r = t_strdup_printf("%s:%u", proxy_host, proxy_port);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenint doveadm_mail_server_user(struct doveadm_mail_cmd_context *ctx,
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen const struct mail_storage_service_input *input,
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen const char **error_r)
ae369149607cd8b9e3f6afdcf7c16cff1abdda54Timo Sirainen ret = doveadm_mail_server_user_get_host(ctx, input, &user, &host, error_r);
72bc08129fb0aaec8144cc183a998ccc426fef9eTimo Sirainen (ctx->set->doveadm_worker_count == 0 || doveadm_server)) {
67cc1d2d8495c3effad6f639cd8468d0ac7ff198Timo Sirainen /* run it ourself */
db4cad7df8f3a1a584b1f72a06995b188871dc5aTimo Sirainen /* server sends the sticky headers for each row as well,
db4cad7df8f3a1a584b1f72a06995b188871dc5aTimo Sirainen so undo any sticks we might have added already */
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen conn = doveadm_server_find_unused_conn(server);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (server_connection_create(server, &conn) < 0)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen if (array_count(&server->queue) >= DOVEADM_SERVER_QUEUE_MAX)
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen array_append(&server->queue, &username_dup, 1);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic struct doveadm_server *doveadm_server_find_used(void)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, servers, &key, &server)) {
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen if (doveadm_server_have_used_connections(server)) {
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic void doveadm_servers_destroy_all_connections(void)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen while (hash_table_iterate(iter, servers, &key, &server)) {
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen while (array_count(&server->connections) > 0) {
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen struct server_connection *const *connp, *conn;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen while ((server = doveadm_server_find_used()) != NULL &&