bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "lib.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "process-title.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "settings-parser.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "master-service.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "master-service-settings.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "doveadm.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "doveadm-settings.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "doveadm-server.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch#include "client-connection-private.h"
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Boschbool doveadm_client_is_allowed_command(const struct doveadm_settings *set,
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *cmd_name)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch{
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch bool ret = FALSE;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (*set->doveadm_allowed_commands == '\0')
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch return TRUE;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch T_BEGIN {
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *const *cmds =
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch t_strsplit(set->doveadm_allowed_commands, ",");
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch for (; *cmds != NULL; cmds++) {
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (strcmp(*cmds, cmd_name) == 0) {
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch ret = TRUE;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch break;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch }
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch }
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch } T_END;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch return ret;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Boschstatic int client_connection_read_settings(struct client_connection *conn)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch{
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const struct setting_parser_info *set_roots[] = {
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch &doveadm_setting_parser_info,
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch NULL
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch };
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch struct master_service_settings_input input;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch struct master_service_settings_output output;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *error;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch void *set;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch i_zero(&input);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch input.roots = set_roots;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch input.service = "doveadm";
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch input.local_ip = conn->local_ip;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch input.remote_ip = conn->remote_ip;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (master_service_settings_read(master_service, &input,
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch &output, &error) < 0) {
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch i_error("Error reading configuration: %s", error);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch return -1;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch }
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch set = master_service_settings_get_others(master_service)[0];
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch conn->set = settings_dup(&doveadm_setting_parser_info, set, conn->pool);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch return 0;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Boschint client_connection_init(struct client_connection *conn,
6fc40674e5a33787ae7fcd47a77a77ea20977994Aki Tuomi enum doveadm_client_type type, pool_t pool, int fd)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch{
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *ip;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
6fc40674e5a33787ae7fcd47a77a77ea20977994Aki Tuomi i_assert(type != DOVEADM_CONNECTION_TYPE_CLI);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch conn->type = type;
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch conn->pool = pool;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch (void)net_getsockname(fd, &conn->local_ip, &conn->local_port);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch (void)net_getpeername(fd, &conn->remote_ip, &conn->remote_port);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch ip = net_ip2addr(&conn->remote_ip);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (ip[0] != '\0')
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch i_set_failure_prefix("doveadm(%s): ", ip);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch conn->name = conn->remote_ip.family == 0 ? "<local>" :
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch p_strdup(pool, net_ip2addr(&conn->remote_ip));
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch return client_connection_read_settings(conn);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Boschvoid client_connection_destroy(struct client_connection **_conn)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch{
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch struct client_connection *conn = *_conn;
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch *_conn = NULL;
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch if (conn->free != NULL)
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch conn->free(conn);
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch doveadm_client = NULL;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch master_service_client_connection_destroyed(master_service);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (doveadm_verbose_proctitle)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch process_title_set("[idling]");
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch pool_unref(&conn->pool);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Boschvoid client_connection_set_proctitle(struct client_connection *conn,
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *text)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch{
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch const char *str;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (!doveadm_verbose_proctitle)
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch return;
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch if (text[0] == '\0')
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch str = t_strdup_printf("[%s]", conn->name);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch else
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch str = t_strdup_printf("[%s %s]", conn->name, text);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch process_title_set(str);
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Boschvoid doveadm_server_init(void)
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch{
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch doveadm_http_server_init();
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch}
4e08875e53e96c8af3bfcb7c4aaa9c3a132101f8Stephan Bosch
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Boschvoid doveadm_server_deinit(void)
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch{
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch if (doveadm_client != NULL)
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch client_connection_destroy(&doveadm_client);
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch doveadm_http_server_deinit();
80a225c0b1f4bf322a562cc7c21d5891fb6895eeStephan Bosch}