bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#include "ioloop.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "array.h"
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen#include "base64.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "hostpid.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "module-dir.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "restrict-access.h"
abf015c9682f0f723db87a7c97bc284ef814818fTimo Sirainen#include "eacces-error.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "ipwd.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "str.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "var-expand.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "dict.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "settings-parser.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "auth-master.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service-private.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service-settings.h"
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen#include "master-service-settings-cache.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-user.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-namespace.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage-service.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <sys/stat.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#ifdef HAVE_SYS_TIME_H
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen# include <sys/time.h>
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#endif
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#ifdef HAVE_SYS_RESOURCE_H
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen# include <sys/resource.h>
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#endif
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#define MAX_TIME_BACKWARDS_SLEEP 5
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#define MAX_NOWARN_FORWARD_SECS 10
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen#define ERRSTR_INVALID_USER_SETTINGS \
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen "Invalid user settings. Refer to server log for more information."
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstruct mail_storage_service_privileges {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen uid_t uid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen gid_t gid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *uid_source, *gid_source;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *home;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *chroot;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen};
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct mail_storage_service_ctx {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_t pool;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct master_service *service;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen const char *default_log_prefix;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen struct auth_master_connection *conn, *iter_conn;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen struct auth_master_user_list_ctx *auth_list;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct setting_parser_info **set_roots;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen enum mail_storage_service_flags flags;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const char *set_cache_module, *set_cache_service;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_cache *set_cache;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen pool_t userdb_next_pool;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen const char *const **userdb_next_fieldsp;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool debug:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool log_initialized:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool config_permission_denied:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct mail_storage_service_user {
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen pool_t pool;
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen int refcount;
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen struct mail_storage_service_ctx *service_ctx;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen struct mail_storage_service_input input;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen enum mail_storage_service_flags flags;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen struct event *event;
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen ARRAY(struct event *) event_stack;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen struct ioloop_context *ioloop_ctx;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen const char *log_prefix, *auth_token, *auth_user;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen const char *system_groups_user, *uid_source, *gid_source;
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen const char *chdir_path;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const struct mail_user_settings *user_set;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info *user_info;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen struct setting_parser_context *set_parser;
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch
c977ee6ce06cbc0b4668fde1ec34f2f5e1773684Timo Sirainen unsigned int session_id_counter;
c977ee6ce06cbc0b4668fde1ec34f2f5e1773684Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool anonymous:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool admin:1;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen};
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainenstruct module *mail_storage_service_modules = NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenstatic int
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainenmail_storage_service_var_expand(struct mail_storage_service_ctx *ctx,
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainen string_t *str, const char *format,
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainen struct mail_storage_service_user *user,
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainen const struct mail_storage_service_input *input,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct mail_storage_service_privileges *priv,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char **error_r);
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic bool
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_user_set_get_mail_debug(const struct setting_parser_info *user_info,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const struct mail_user_settings *user_set)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const struct mail_storage_settings *mail_set;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen MAIL_STORAGE_SET_DRIVER_NAME);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return mail_set->mail_debug;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void set_keyval(struct mail_storage_service_ctx *ctx,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct mail_storage_service_user *user,
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen const char *key, const char *value)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* this setting was already overridden with -o parameter */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_user_set_get_mail_debug(user->user_info,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user->user_set)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen key);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
096e109f9f332bc758ca5e22ec64337379c5f231Timo Sirainen if (settings_parse_keyvalue(set_parser, key, value) < 0) {
096e109f9f332bc758ca5e22ec64337379c5f231Timo Sirainen i_fatal("Invalid userdb input %s=%s: %s", key, value,
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen settings_parser_get_error(set_parser));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic int set_line(struct mail_storage_service_ctx *ctx,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct mail_storage_service_user *user,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *line)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen bool mail_debug;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen const char *key, *orig_key, *append_value = NULL;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t len;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen int ret;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_debug = mail_user_set_get_mail_debug(user->user_info,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user->user_set);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (strchr(line, '=') == NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen line = t_strconcat(line, "=yes", NULL);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen orig_key = key = t_strcut(line, '=');
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen len = strlen(key);
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen if (len > 0 && key[len-1] == '+') {
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen /* key+=value */
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen append_value = line + len + 1;
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen key = t_strndup(key, len-1);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* assume it's a plugin setting */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen key = t_strconcat("plugin/", key, NULL);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen line = t_strconcat("plugin/", line, NULL);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* this setting was already overridden with -o parameter */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_debug) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen key);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return 1;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen if (append_value != NULL) {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen const void *value;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen enum setting_type type;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen value = settings_parse_get_value(set_parser, key, &type);
79fff45046397ba48c8693d5f37a1fd93096987fTimo Sirainen if (value != NULL && type == SET_STR) {
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen const char *const *strp = value;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen line = t_strdup_printf("%s=%s%s",
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen key, *strp, append_value);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen } else {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen i_error("Ignoring %s userdb setting. "
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen "'+' can only be used for strings.", orig_key);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen }
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen }
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = settings_parse_line(set_parser, line);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_debug && ret >= 0) {
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen if (strstr(key, "pass") != NULL) {
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen /* possibly a password field (e.g. imapc_password).
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen hide the value. */
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen line = t_strconcat(key, "=<hidden>", NULL);
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_debug(ret == 0 ?
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen "Unknown userdb setting: %s" :
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen "Added userdb setting: %s", line);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return ret;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *dir)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *const *chroot_dirs;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*dir == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*user_set->valid_chroot_dirs == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while (*chroot_dirs != NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (**chroot_dirs != '\0' &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen chroot_dirs++;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenuser_reply_handle(struct mail_storage_service_ctx *ctx,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct mail_storage_service_user *user,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct auth_user_reply *reply,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen const char *home = reply->home;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen const char *chroot = reply->chroot;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen const char *const *str, *line, *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i, count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->uid != (uid_t)-1) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->uid == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = "userdb returned 0 as uid";
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen user->uid_source = "userdb lookup";
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_uid", dec2str(reply->uid));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen if (reply->gid != (uid_t)-1) {
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen user->gid_source = "userdb lookup";
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_gid", dec2str(reply->gid));
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (home != NULL && chroot == NULL &&
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen *user->user_set->valid_chroot_dirs != '\0' &&
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen (p = strstr(home, "/./")) != NULL) {
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen /* wu-ftpd like <chroot>/./<home> - check only if there's even
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen a possibility of using them (non-empty valid_chroot_dirs) */
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen chroot = t_strdup_until(home, p);
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen home = p + 2;
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen }
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (home != NULL)
e30b9e07f9657c35ca09ac36d57d60cbe2ebbc66Timo Sirainen set_keyval(ctx, user, "mail_home", home);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (chroot != NULL) {
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen if (!validate_chroot(user->user_set, chroot)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "userdb returned invalid chroot directory: %s "
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen "(see valid_chroot_dirs setting)", chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen set_keyval(ctx, user, "mail_chroot", chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch user->anonymous = reply->anonymous;
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str = array_get(&reply->extra_fields, &count);
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen for (i = 0; i < count; i++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen line = str[i];
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->system_groups_user =
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen p_strdup(user->pool, line + 19);
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen } else if (strncmp(line, "chdir=", 6) == 0) {
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen user->chdir_path = p_strdup(user->pool, line+6);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen } else if (strncmp(line, "nice=", 5) == 0) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#ifdef HAVE_SETPRIORITY
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch int n;
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (str_to_int(line + 5, &n) < 0) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch i_error("userdb returned invalid nice value %s",
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch line + 5);
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch } else if (n != 0) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (setpriority(PRIO_PROCESS, 0, n) < 0)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen i_error("setpriority(%d) failed: %m", n);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen }
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#endif
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch } else if (strncmp(line, "auth_token=", 11) == 0) {
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch user->auth_token = p_strdup(user->pool, line+11);
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen } else if (strncmp(line, "auth_user=", 10) == 0) {
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen user->auth_user = p_strdup(user->pool, line+10);
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen } else if (strncmp(line, "admin=", 6) == 0) {
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen user->admin = line[6] == 'y' || line[6] == 'Y' ||
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen line[6] == '1';
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen } else T_BEGIN {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = set_line(ctx, user, line);
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen } T_END;
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen if (ret < 0)
4c261fb48e6e36570a0841aa51ca483024d6a0a6Timo Sirainen break;
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (ret < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen str[i], settings_parser_get_error(user->set_parser));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen const struct mail_storage_service_input *input,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen pool_t pool, const char **user,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *const **fields_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen struct auth_user_info info;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *new_username;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&info);
b9dc21a94401638c00e40b695998875e1563ce77Timo Sirainen info.service = input->service != NULL ? input->service :
b9dc21a94401638c00e40b695998875e1563ce77Timo Sirainen ctx->service->name;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.local_ip = input->local_ip;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.remote_ip = input->remote_ip;
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainen info.local_port = input->local_port;
27ca6cb0548c6478005c77d04be641356ec7d83cTimo Sirainen info.remote_port = input->remote_port;
11120acd01d43973cd504952d691a2ae1c546ee2Timo Sirainen info.debug = input->debug;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen &new_username, fields_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (ret > 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (strcmp(*user, new_username) != 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (ctx->debug)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_debug("changed username to %s", new_username);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *user = t_strdup(new_username);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *user = new_username;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen } else if (ret == 0)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = "Unknown user";
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen else if (**fields_r != NULL) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = t_strdup(**fields_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ret = -2;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen } else {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = MAIL_ERRSTR_CRITICAL_MSG;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r, const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct passwd pw;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_uid(str, uid_r) == 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen switch (i_getpwnam(str, &pw)) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case -1:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *error_r = t_strdup_printf("getpwnam(%s) failed: %m", str);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case 0:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *error_r = t_strconcat("Unknown UNIX UID user: ", str, NULL);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return FALSE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen default:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *uid_r = pw.pw_uid;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return TRUE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r, const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen struct group gr;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen if (str_to_gid(str, gid_r) == 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen switch (i_getgrnam(str, &gr)) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case -1:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *error_r = t_strdup_printf("getgrnam(%s) failed: %m", str);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen case 0:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *error_r = t_strconcat("Unknown UNIX GID group: ", str, NULL);
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return FALSE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen default:
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *gid_r = gr.gr_gid;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return TRUE;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic const struct var_expand_table *
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenget_var_expand_table(struct master_service *service,
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen struct mail_storage_service_user *user,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_input *input,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_privileges *priv)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen{
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *username = t_strcut(input->username, '@');
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *domain = i_strchr_to_next(input->username, '@');
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *uid = priv == NULL ? NULL :
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *gid = priv == NULL ? NULL :
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const char *auth_user, *auth_username, *auth_domain;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen if (user == NULL || user->auth_user == NULL) {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_user = input->username;
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_username = username;
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_domain = domain;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen } else {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_user = user->auth_user;
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_username = t_strcut(user->auth_user, '@');
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen auth_domain = i_strchr_to_next(user->auth_user, '@');
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen }
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen const struct var_expand_table stack_tab[] = {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'u', input->username, "user" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'n', username, "username" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'd', domain, "domain" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 's', service->name, "service" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'l', net_ip2addr(&input->local_ip), "lip" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'r', net_ip2addr(&input->remote_ip), "rip" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'p', my_pid, "pid" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { 'i', uid, "uid" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', gid, "gid" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', input->session_id, "session" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', auth_user, "auth_user" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', auth_username, "auth_username" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', auth_domain, "auth_domain" },
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen { '\0', NULL, NULL }
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen };
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen struct var_expand_table *tab;
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen tab = t_malloc_no0(sizeof(stack_tab));
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen memcpy(tab, stack_tab, sizeof(stack_tab));
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return tab;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainenconst struct var_expand_table *
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainenmail_storage_service_get_var_expand_table(struct mail_storage_service_ctx *ctx,
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct mail_storage_service_input *input)
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen{
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen struct mail_storage_service_privileges priv;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&priv);
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen priv.uid = (uid_t)-1;
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen priv.gid = (gid_t)-1;
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen return get_var_expand_table(ctx->service, NULL, input, &priv);
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen}
19cadcc25c26af7afea1355d78e20ad64eaad263Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenstatic bool
265cb53cf8d5cb35edd4c4ff086ca6165605b708Timo Sirainenuser_expand_varstr(struct mail_storage_service_ctx *ctx,
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen struct mail_storage_service_user *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges *priv,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *str, const char **value_r, const char **error_r)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen{
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen string_t *value;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen int ret;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (*str == SETTING_STRVAR_EXPANDED[0]) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen *value_r = str + 1;
c73ede1a6685975eb21eecf2fb5af79854867f9bTimo Sirainen return TRUE;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen value = t_str_new(256);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen ret = mail_storage_service_var_expand(ctx, value, str + 1, user,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen &user->input, priv, error_r);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen *value_r = str_c(value);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return ret > 0;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainenstatic int
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenservice_parse_privileges(struct mail_storage_service_ctx *ctx,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_user *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges *priv_r,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const struct mail_user_settings *set = user->user_set;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen uid_t uid = (uid_t)-1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen gid_t gid = (gid_t)-1;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(priv_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_uid != '\0') {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!parse_uid(set->mail_uid, &uid, error_r)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen *error_r = t_strdup_printf("%s (from %s)", *error_r,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen user->uid_source);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (uid < (uid_t)set->first_valid_uid ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (set->last_valid_uid != 0 &&
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen uid > (uid_t)set->last_valid_uid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen "Mail access for users with UID %s not permitted "
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen "(see first_valid_uid in config file, uid from %s).",
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen dec2str(uid), user->uid_source);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv_r->uid = uid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv_r->uid_source = user->uid_source;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_gid != '\0') {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (!parse_gid(set->mail_gid, &gid, error_r)) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen *error_r = t_strdup_printf("%s (from %s)", *error_r,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen user->gid_source);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (gid < (gid_t)set->first_valid_gid ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (set->last_valid_gid != 0 &&
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen gid > (gid_t)set->last_valid_gid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen "Mail access for users with GID %s not permitted "
216cd45a5f47c9bd46fe67c1b3bd6b1a42f6e39cTimo Sirainen "(see first_valid_gid in config file, gid from %s).",
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen dec2str(gid), user->gid_source);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv_r->gid = gid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv_r->gid_source = user->gid_source;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen /* variable strings are expanded in mail_user_init(),
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen but we need the home and chroot sooner so do them separately here. */
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (!user_expand_varstr(ctx, user, priv_r, user->user_set->mail_home,
c73ede1a6685975eb21eecf2fb5af79854867f9bTimo Sirainen &priv_r->home, &error)) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen *error_r = t_strdup_printf(
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen "Failed to expand mail_home '%s': %s",
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen user->user_set->mail_home, error);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return -1;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen }
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (!user_expand_varstr(ctx, user, priv_r, user->user_set->mail_chroot,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen &priv_r->chroot, &error)) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen *error_r = t_strdup_printf(
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen "Failed to expand mail_chroot '%s': %s",
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen user->user_set->mail_chroot, error);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return -1;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return 0;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen}
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainenstatic void mail_storage_service_seteuid_root(void)
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen{
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen if (seteuid(0) < 0) {
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen i_fatal("mail-storage-service: "
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen "Failed to restore temporarily dropped root privileges: "
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen "seteuid(0) failed: %m");
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen }
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen}
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic int
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenservice_drop_privileges(struct mail_storage_service_user *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges *priv,
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi bool allow_root, bool keep_setuid_root,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen bool setenv_only, const char **error_r)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const struct mail_user_settings *set = user->user_set;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct restrict_access_settings rset;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen uid_t current_euid, setuid_uid = 0;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *cur_chroot, *error;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen current_euid = geteuid();
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen restrict_access_init(&rset);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen restrict_access_get_env(&rset);
de0034cc6bb52585bc82289801435418a7ee7298Martti Rannanjärvi rset.allow_setuid_root = keep_setuid_root;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (priv->uid != (uid_t)-1) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen rset.uid = priv->uid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen rset.uid_source = priv->uid_source;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen } else if (rset.uid == (uid_t)-1 &&
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi !allow_root && current_euid == 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen *error_r = "User is missing UID (see mail_uid setting)";
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -1;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen }
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (priv->gid != (gid_t)-1) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen rset.gid = priv->gid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen rset.gid_source = priv->gid_source;
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi } else if (rset.gid == (gid_t)-1 && !allow_root &&
7f472e15b5f19a3536634863950c80a88079da23Timo Sirainen set->first_valid_gid > 0 && getegid() == 0) {
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen *error_r = "User is missing GID (see mail_gid setting)";
0139fcb57a88f6ed27a1bb4a1bd537b04fd2b5d6Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_privileged_group != '\0') {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid,
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen &error)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen "%s (in mail_privileged_group setting)", error);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen if (*set->mail_access_groups != '\0') {
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen rset.extra_groups = t_strconcat(set->mail_access_groups, ",",
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen rset.extra_groups, NULL);
1503ac7619d97193d6690292b5f9523552c5d6ceTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.first_valid_gid = set->first_valid_gid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.last_valid_gid = set->last_valid_gid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen rset.chroot_dir = *priv->chroot == '\0' ? NULL : priv->chroot;
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen rset.system_groups_user = user->system_groups_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen cur_chroot = restrict_access_get_current_chroot();
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen if (cur_chroot != NULL) {
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen /* we're already chrooted. make sure the chroots are equal. */
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen if (rset.chroot_dir == NULL) {
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen *error_r = "Process is already chrooted, "
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen "can't un-chroot for this user";
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen return -1;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen if (strcmp(rset.chroot_dir, cur_chroot) != 0) {
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen *error_r = t_strdup_printf(
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen "Process is already chrooted to %s, "
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen "can't chroot to %s", cur_chroot, priv->chroot);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen return -1;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen /* chrooting to same directory where we're already chrooted */
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen rset.chroot_dir = NULL;
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi if (!allow_root &&
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = "Mail access not allowed for root";
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (keep_setuid_root) {
8c81109dca287f1830aac57bae61e57260248941Timo Sirainen if (current_euid != rset.uid && rset.uid != (uid_t)-1) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (current_euid != 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* we're changing the UID,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen switch back to root first */
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen mail_storage_service_seteuid_root();
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen }
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen setuid_uid = rset.uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.uid = (uid_t)-1;
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi allow_root = TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen if (!setenv_only) {
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi restrict_access(&rset, allow_root ? RESTRICT_ACCESS_FLAG_ALLOW_ROOT : 0,
816d20be0cf95fc4eb1a8aa716639e73b8ba525eMartti Rannanjärvi *priv->home == '\0' ? NULL : priv->home);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen } else {
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen restrict_access_set_env(&rset);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen }
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen if (setuid_uid != 0 && !setenv_only) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (seteuid(setuid_uid) < 0)
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen i_fatal("mail-storage-service: seteuid(%s) failed: %m",
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen dec2str(setuid_uid));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic int
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct mail_storage_service_user *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges *priv,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov const char *session_id_suffix,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_user **mail_user_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mail_storage_settings *mail_set;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *home = priv->home;
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch struct mail_user_connection_data conn_data;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_user *mail_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch i_zero(&conn_data);
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch conn_data.local_ip = &user->input.local_ip;
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch conn_data.remote_ip = &user->input.remote_ip;
211caf3c233d562b0c8137e5eefae3cb1ef13003Stephan Bosch conn_data.local_port = user->input.local_port;
211caf3c233d562b0c8137e5eefae3cb1ef13003Stephan Bosch conn_data.remote_port = user->input.remote_port;
211caf3c233d562b0c8137e5eefae3cb1ef13003Stephan Bosch conn_data.secured = user->input.conn_secured;
211caf3c233d562b0c8137e5eefae3cb1ef13003Stephan Bosch conn_data.ssl_secured = user->input.conn_ssl_secured;
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen /* NOTE: if more user initialization is added, add it also to
1e40531c1de45bc87e72a9d5866ff2af79b63cebTimo Sirainen mail_user_dup() */
677cc0d62b41c7506246bf1b992a400a11896474Timo Sirainen mail_user = mail_user_alloc_nodup_set(user->event, user->input.username,
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen user->user_info, user->user_set);
691f802ef6ec2105079d420ba26b21088402c6daTimo Sirainen mail_user->_service_user = user;
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen mail_storage_service_user_ref(user);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
ff4ba036fcdf28d4a1a7e3c1c6c0c71793547bd6Stephan Bosch mail_user_set_vars(mail_user, ctx->service->name, &conn_data);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_user->uid = priv->uid == (uid_t)-1 ? geteuid() : priv->uid;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_user->gid = priv->gid == (gid_t)-1 ? getegid() : priv->gid;
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch mail_user->anonymous = user->anonymous;
5a9912dcadfd467c5ea54bdc3331eef359f0b1c5Timo Sirainen mail_user->admin = user->admin;
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token);
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user);
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen if (user->input.session_create_time != 0) {
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen mail_user->session_create_time =
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen user->input.session_create_time;
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen mail_user->session_restored = TRUE;
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen }
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov if (session_id_suffix == NULL) {
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov if (user->session_id_counter++ == 0) {
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov mail_user->session_id =
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov p_strdup(mail_user->pool, user->input.session_id);
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov } else {
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov mail_user->session_id =
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov p_strdup_printf(mail_user->pool, "%s:%u",
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov user->input.session_id,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov user->session_id_counter);
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov }
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov } else
c977ee6ce06cbc0b4668fde1ec34f2f5e1773684Timo Sirainen mail_user->session_id =
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov p_strdup_printf(mail_user->pool, "%s:%s",
c977ee6ce06cbc0b4668fde1ec34f2f5e1773684Timo Sirainen user->input.session_id,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov session_id_suffix);
677cc0d62b41c7506246bf1b992a400a11896474Timo Sirainen event_add_str(user->event, "session", mail_user->session_id);
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL :
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen p_strarray_dup(mail_user->pool, user->input.userdb_fields);
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen if (mail_set->mail_debug) {
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen string_t *str = t_str_new(64);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen str_printfa(str, "Effective uid=%s, gid=%s, home=%s",
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen if (*priv->chroot != '\0')
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen str_printfa(str, ", chroot=%s", priv->chroot);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen i_debug("%s", str_c(str));
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen }
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* we don't want to write core files to any users' home
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen directories since they could contain information about other
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen users' mails as well. so do no chdiring to home. */
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen } else if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* If possible chdir to home directory, so that core file
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen could be written in case we crash.
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen fallback to chdir()ing to root directory. this is needed
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen because the current directory may not be accessible after
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen dropping privileges, and for example unlink_directory()
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen requires ability to open the current directory. */
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen const char *chdir_path = user->chdir_path != NULL ?
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen user->chdir_path : home;
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen if (chdir_path[0] == '\0') {
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen if (chdir("/") < 0)
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen i_error("chdir(/) failed: %m");
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen } else if (chdir(chdir_path) < 0) {
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen if (errno == EACCES) {
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen i_error("%s", eacces_error_get("chdir",
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen t_strconcat(chdir_path, "/", NULL)));
1fe027b2cac9fd227e7bf639cf0dcba27b47f65cTimo Sirainen } else if (errno != ENOENT)
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen i_error("chdir(%s) failed: %m", chdir_path);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else if (mail_set->mail_debug)
baf97389e203e105b97a8183b2893740691f8c63Timo Sirainen i_debug("Home dir not found: %s", chdir_path);
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen if (chdir("/") < 0)
2e441a8e3d694820a82d887dcdc4d2d568e428a8Timo Sirainen i_error("chdir(/) failed: %m");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen if (mail_user_init(mail_user, error_r) < 0) {
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen mail_user_unref(&mail_user);
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen return -1;
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen }
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES) == 0) {
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen if (mail_namespaces_init(mail_user, error_r) < 0) {
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen mail_user_unref(&mail_user);
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen return -1;
303e375b7e76278f4ec541f49af0476d3e4ee710Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *mail_user_r = mail_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
85779ec11f23eb8efeb8993b1e0b9aad62c4122aTimo Sirainenvoid mail_storage_service_io_activate_user(struct mail_storage_service_user *user)
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen{
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen io_loop_context_activate(user->ioloop_ctx);
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen}
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainenvoid mail_storage_service_io_deactivate_user(struct mail_storage_service_user *user)
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen{
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen io_loop_context_deactivate(user->ioloop_ctx);
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen}
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainenstatic void
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainenmail_storage_service_io_activate_user_cb(struct mail_storage_service_user *user)
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen{
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_push_global(user->event);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (array_is_created(&user->event_stack)) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen struct event *const *events;
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen unsigned int i, count;
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen /* push the global events from stack in reverse order */
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen events = array_get(&user->event_stack, &count);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen for (i = count; i > 0; i--)
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_push_global(events[i-1]);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen array_clear(&user->event_stack);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen if (user->log_prefix != NULL)
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen i_set_failure_prefix("%s", user->log_prefix);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen}
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainenstatic void
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainenmail_storage_service_io_deactivate_user_cb(struct mail_storage_service_user *user)
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen{
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen struct event *event;
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen /* ioloop context is always global, so we can't push one ioloop context
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen on top of another one. We'll need to rewind the global event stack
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen until we've reached the event that started this context. We'll push
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen these global events back when the user's context is activated
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen again. (We'll assert-crash if the user is freed before these
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen global events have been popped.) */
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen while ((event = event_get_global()) != user->event) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen i_assert(event != NULL);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (!array_is_created(&user->event_stack))
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen i_array_init(&user->event_stack, 4);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen array_append(&user->event_stack, &event, 1);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_pop_global(event);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_pop_global(user->event);
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen if (user->log_prefix != NULL)
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen i_set_failure_prefix("%s", user->service_ctx->default_log_prefix);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen}
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainenstatic const char *field_get_default(const char *data)
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen{
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen const char *p;
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen p = strchr(data, ':');
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen if (p == NULL)
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen return "";
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen else {
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen /* default value given */
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen return p+1;
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen }
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen}
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainenconst char *mail_storage_service_fields_var_expand(const char *data,
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen const char *const *fields)
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen{
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen const char *field_name = t_strcut(data, ':');
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int i;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t field_name_len;
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen if (fields == NULL)
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen return field_get_default(data);
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen field_name_len = strlen(field_name);
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen for (i = 0; fields[i] != NULL; i++) {
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen if (strncmp(fields[i], field_name, field_name_len) == 0 &&
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen fields[i][field_name_len] == '=')
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen return fields[i] + field_name_len+1;
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen }
38dac3030bdd74acba0a60edd54b2db6d914fde2Timo Sirainen return field_get_default(data);
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen}
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenmail_storage_service_input_var_userdb(const char *data, void *context,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen{
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen struct mail_storage_service_user *user = context;
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = mail_storage_service_fields_var_expand(data,
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen user == NULL ? NULL : user->input.userdb_fields);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen}
d23dfc385f22d7a2c466d29501c9e0ce5a243deeTimo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenstatic int
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainenmail_storage_service_var_expand(struct mail_storage_service_ctx *ctx,
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen string_t *str, const char *format,
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen struct mail_storage_service_user *user,
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen const struct mail_storage_service_input *input,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const struct mail_storage_service_privileges *priv,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char **error_r)
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen{
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen static const struct var_expand_func_table func_table[] = {
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen { "userdb", mail_storage_service_input_var_userdb },
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen { NULL, NULL }
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen };
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen return var_expand_with_funcs(str, format,
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen get_var_expand_table(ctx->service, user, input, priv),
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen func_table, user, error_r);
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen}
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainenmail_storage_service_init_log(struct mail_storage_service_ctx *ctx,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_user *user,
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges *priv)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen{
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen ctx->log_initialized = TRUE;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen T_BEGIN {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen string_t *str;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen str = t_str_new(256);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen (void)mail_storage_service_var_expand(ctx, str,
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen user->user_set->mail_log_prefix,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen user, &user->input, priv, &error);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen user->log_prefix = p_strdup(user->pool, str_c(str));
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen } T_END;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen master_service_init_log(ctx->service, user->log_prefix);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen /* replace the whole log prefix with mail_log_prefix */
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_replace_log_prefix(user->event, user->log_prefix);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
8abe071cb14a622b9d84b00a9269f96d01a576f6Timo Sirainen if (master_service_get_client_limit(master_service) == 1)
8abe071cb14a622b9d84b00a9269f96d01a576f6Timo Sirainen i_set_failure_send_prefix(user->log_prefix);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen}
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenstatic void mail_storage_service_time_moved(time_t old_time, time_t new_time)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen{
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen long diff = new_time - old_time;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen if (diff > 0) {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen if (diff > MAX_NOWARN_FORWARD_SECS)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen i_warning("Time jumped forwards %ld seconds", diff);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen return;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen }
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen diff = -diff;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen if (diff > MAX_TIME_BACKWARDS_SLEEP) {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen i_fatal("Time just moved backwards by %ld seconds. "
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen "This might cause a lot of problems, "
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen "so I'll just kill myself now. "
0992011130e9d0a498ca860ddbe4028398a530c5Timo Sirainen "http://wiki2.dovecot.org/TimeMovedBackwards", diff);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen } else {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen i_error("Time just moved backwards by %ld seconds. "
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen "I'll sleep now until we're back in present. "
0992011130e9d0a498ca860ddbe4028398a530c5Timo Sirainen "http://wiki2.dovecot.org/TimeMovedBackwards", diff);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen /* Sleep extra second to make sure usecs also grows. */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen diff++;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen while (diff > 0 && sleep(diff) != 0) {
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen /* don't use sleep()'s return value, because
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen it could get us to a long loop in case
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen interrupts just keep coming */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen diff = old_time - time(NULL) + 1;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen }
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen }
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen}
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct mail_storage_service_ctx *
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_init(struct master_service *service,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct setting_parser_info *set_roots[],
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen enum mail_storage_service_flags flags)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_ctx *ctx;
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen const char *version;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_t pool;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen version = master_service_get_version_string(service);
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen if (version != NULL && strcmp(version, PACKAGE_VERSION) != 0) {
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen i_fatal("Version mismatch: libdovecot-storage.so is '%s', "
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen "while the running Dovecot binary is '%s'",
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen PACKAGE_VERSION, version);
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen }
3c932c0a21349f23dd38c50c12b3a24717dfbc28Timo Sirainen
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
32223e1a31b6f060ab3abcc26a630e7cca0abc89Timo Sirainen getuid() != 0) {
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen /* service { user } isn't root. the permission drop can't be
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen temporary. */
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen flags &= ~MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP;
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen }
1cb065514fcfe00b684ee274239e3f0390c7fc47Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen (void)umask(0077);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen io_loop_set_time_moved_callback(current_ioloop,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen mail_storage_service_time_moved);
f934b271c69c7b3e5e3bca23ff9b3ab6187262c2Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_storage_init();
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool = pool_alloconly_create("mail storage service", 2048);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx = p_new(pool, struct mail_storage_service_ctx, 1);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->pool = pool;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->service = service;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->flags = flags;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* @UNSAFE */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (set_roots == NULL)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen count = 0;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen else
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
878a83a906e1be6354b563ead096955a22ad5fbeTimo Sirainen ctx->set_roots =
878a83a906e1be6354b563ead096955a22ad5fbeTimo Sirainen p_new(pool, const struct setting_parser_info *, count + 2);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen if (set_roots != NULL) {
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen memcpy(ctx->set_roots + 1, set_roots,
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen sizeof(*ctx->set_roots) * count);
b879ed8dd4b5850987e6b89a92f794d87c6be7d7Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* do all the global initialization. delay initializing plugins until
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen we drop privileges the first time. */
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) {
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen /* note: we may not have read any settings yet, so this logging
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen may still be going to wrong location */
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen ctx->default_log_prefix =
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen p_strconcat(pool, service->name, ": ", NULL);
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen master_service_init_log(service, ctx->default_log_prefix);
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen dict_drivers_register_builtin();
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ctx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct auth_master_connection *
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen{
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen i_assert(ctx->conn != NULL);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ctx->conn;
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen}
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainenstatic enum mail_storage_service_flags
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainenmail_storage_service_input_get_flags(struct mail_storage_service_ctx *ctx,
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen const struct mail_storage_service_input *input)
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen{
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen enum mail_storage_service_flags flags;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen flags = (ctx->flags & ~input->flags_override_remove) |
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen input->flags_override_add;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if (input->no_userdb_lookup) {
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen /* FIXME: for API backwards compatibility only */
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen flags &= ~MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen }
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen return flags;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen}
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenint mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct mail_storage_service_input *input,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen pool_t pool,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info **user_info_r,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const struct setting_parser_context **parser_r,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct master_service_settings_input set_input;
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen const struct setting_parser_info *const *roots;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_output set_output;
dbe06905918a415a34c5621b9fdf45be0b9c8e64Timo Sirainen const struct dynamic_settings_parser *dyn_parsers;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen enum mail_storage_service_flags flags;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen unsigned int i;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen ctx->config_permission_denied = FALSE;
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen
8d5c97bf940e43e8ec6e9f1ec8655f3b20edafbeTimo Sirainen flags = input == NULL ? ctx->flags :
8d5c97bf940e43e8ec6e9f1ec8655f3b20edafbeTimo Sirainen mail_storage_service_input_get_flags(ctx, input);
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&set_input);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.roots = ctx->set_roots;
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen set_input.preserve_user = TRUE;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* settings reader may exec doveconf, which is going to clear
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen environment, and if we're not doing a userdb lookup we want to
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen use $HOME */
762e17079d29d9f1838114ff5fec9ceaba8eb6a8Timo Sirainen set_input.preserve_home =
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen (flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
50349cd047ca9e7c100cbeb70acfe26672649959Timo Sirainen set_input.use_sysexits =
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen (flags & MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS) != 0;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (input != NULL) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.module = input->module;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.service = input->service;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.username = input->username;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.local_ip = input->local_ip;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.remote_ip = input->remote_ip;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
d2ca20a479e76af8557b4a74b0b51e4de0e3c9e3Timo Sirainen if (input == NULL) {
d2ca20a479e76af8557b4a74b0b51e4de0e3c9e3Timo Sirainen /* global settings read - don't create a cache for thi */
d2ca20a479e76af8557b4a74b0b51e4de0e3c9e3Timo Sirainen } else if (ctx->set_cache == NULL) {
674f541b16689c0ed090dac32db94463c5af3977Timo Sirainen ctx->set_cache_module = p_strdup(ctx->pool, set_input.module);
674f541b16689c0ed090dac32db94463c5af3977Timo Sirainen ctx->set_cache_service = p_strdup(ctx->pool, set_input.service);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx->set_cache = master_service_settings_cache_init(
674f541b16689c0ed090dac32db94463c5af3977Timo Sirainen ctx->service, set_input.module, set_input.service);
faca2afa3576c50caf28e0f009555325d2a49e0bTimo Sirainen } else {
faca2afa3576c50caf28e0f009555325d2a49e0bTimo Sirainen /* already looked up settings at least once.
faca2afa3576c50caf28e0f009555325d2a49e0bTimo Sirainen we really shouldn't be execing anymore. */
faca2afa3576c50caf28e0f009555325d2a49e0bTimo Sirainen set_input.never_exec = TRUE;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
dbe06905918a415a34c5621b9fdf45be0b9c8e64Timo Sirainen dyn_parsers = mail_storage_get_dynamic_parsers(pool);
674f541b16689c0ed090dac32db94463c5af3977Timo Sirainen if (null_strcmp(set_input.module, ctx->set_cache_module) == 0 &&
d2ca20a479e76af8557b4a74b0b51e4de0e3c9e3Timo Sirainen null_strcmp(set_input.service, ctx->set_cache_service) == 0 &&
d2ca20a479e76af8557b4a74b0b51e4de0e3c9e3Timo Sirainen ctx->set_cache != NULL) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (master_service_settings_cache_read(ctx->set_cache,
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen &set_input, dyn_parsers,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen parser_r, error_r) < 0) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = t_strdup_printf(
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen "Error reading configuration: %s", *error_r);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen return -1;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen } else {
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen settings_parser_dyn_update(pool, &set_input.roots, dyn_parsers);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &set_output, error_r) < 0) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen *error_r = t_strdup_printf(
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen "Error reading configuration: %s", *error_r);
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen ctx->config_permission_denied =
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen set_output.permission_denied;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen return -1;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen *parser_r = ctx->service->set_parser;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen roots = settings_parser_get_roots(*parser_r);
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen for (i = 0; roots[i] != NULL; i++) {
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen if (strcmp(roots[i]->module_name,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen mail_user_setting_parser_info.module_name) == 0) {
9b78c0d5e13141f4df6c6e483f854e5acb861288Timo Sirainen *user_info_r = roots[i];
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen return 0;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen i_unreached();
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainenvoid mail_storage_service_set_auth_conn(struct mail_storage_service_ctx *ctx,
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen struct auth_master_connection *conn)
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen{
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen i_assert(ctx->conn == NULL);
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen i_assert(mail_user_auth_master_conn == NULL);
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen ctx->conn = conn;
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen mail_user_auth_master_conn = conn;
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen}
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstatic void
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info *user_info,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct mail_user_settings *user_set)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen enum auth_master_flags flags = 0;
f934b271c69c7b3e5e3bca23ff9b3ab6187262c2Timo Sirainen
72f2a851238e5661695c63bff0e9a9e800ba577aTimo Sirainen ctx->debug = mail_user_set_get_mail_debug(user_info, user_set);
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen if (ctx->debug)
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen flags |= AUTH_MASTER_FLAG_DEBUG;
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT) != 0)
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen flags |= AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT;
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen mail_storage_service_set_auth_conn(ctx,
50b9773bebe5c66485728e21e4da6e99db388c92Timo Sirainen auth_master_init(user_set->auth_socket_path, flags));
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen}
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainenstatic int
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen const struct setting_parser_info *user_info,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen const struct mail_user_settings *user_set,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen const char **error_r)
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen{
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen struct module_dir_load_settings mod_set;
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen if (*user_set->mail_plugins == '\0')
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen return 0;
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen return 0;
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&mod_set);
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainen mod_set.abi_version = DOVECOT_ABI_VERSION;
8552b0cad8ffe9ccb8270577ba28b8010c89af11Timo Sirainen mod_set.binary_name = master_service_get_name(ctx->service);
98c3aa2587ad3e81e1548a3a4f79b2a24566cec3Timo Sirainen mod_set.setting_name = "mail_plugins";
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen mod_set.require_init_funcs = TRUE;
72f2a851238e5661695c63bff0e9a9e800ba577aTimo Sirainen mod_set.debug = mail_user_set_get_mail_debug(user_info, user_set);
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen return module_dir_try_load_missing(&mail_storage_service_modules,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen user_set->mail_plugin_dir,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen user_set->mail_plugins,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen &mod_set, error_r);
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen}
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainenstatic int extra_field_key_cmp_p(const char *const *s1, const char *const *s2)
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen{
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen const char *p1 = *s1, *p2 = *s2;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen for (; *p1 == *p2; p1++, p2++) {
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen if (*p1 == '\0')
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen return 0;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen }
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen if (*p1 == '=')
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen return -1;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen if (*p2 == '=')
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen return 1;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen return *p1 - *p2;
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen}
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenstatic void
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenmail_storage_service_set_log_prefix(struct mail_storage_service_ctx *ctx,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_user_settings *user_set,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen struct mail_storage_service_user *user,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_input *input,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_privileges *priv)
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen{
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen string_t *str;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen str = t_str_new(256);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen (void)mail_storage_service_var_expand(ctx, str, user_set->mail_log_prefix,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen user, input, priv, &error);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%s", str_c(str));
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen}
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainenstatic const char *
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainenmail_storage_service_generate_session_id(pool_t pool, const char *prefix)
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen{
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen guid_128_t guid;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t prefix_len = prefix == NULL ? 0 : strlen(prefix);
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen string_t *str = str_new(pool, MAX_BASE64_ENCODED_SIZE(prefix_len + 1 + sizeof(guid)));
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen if (prefix != NULL)
6cb874b7e9239922e509fc91c0567cd266904a4cTimo Sirainen str_printfa(str, "%s:", prefix);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen guid_128_generate(guid);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen base64_encode(guid, sizeof(guid), str);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen /* remove the trailing "==" */
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen i_assert(str_data(str)[str_len(str)-2] == '=');
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen str_truncate(str, str_len(str)-2);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen return str_c(str);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen}
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenstatic int
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenmail_storage_service_lookup_real(struct mail_storage_service_ctx *ctx,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_input *input,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen bool update_log_prefix,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen struct mail_storage_service_user **user_r,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const char **error_r)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen enum mail_storage_service_flags flags;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char *username = input->username;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info *user_info;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct mail_user_settings *user_set;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen const char *const *userdb_fields, *error;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct auth_user_reply reply;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const struct setting_parser_context *set_parser;
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen void **sets;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_t user_pool, temp_pool;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen int ret = 1;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
33bd898e7756b289e65f43133312d9637afc1371Timo Sirainen user_pool = pool_alloconly_create(MEMPOOL_GROWING"mail storage service user", 1024*6);
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen flags = mail_storage_service_input_get_flags(ctx, input);
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen geteuid() != 0) {
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen /* we dropped privileges only temporarily. switch back to root
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen before reading settings, so we'll definitely have enough
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen permissions to connect to the config socket. */
20dca965f48c1d7600a268d380c0b5fb5f1011d5Timo Sirainen mail_storage_service_seteuid_root();
984e5c91288139f8a2582be705ee7ef0d157a3f6Timo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &user_info, &set_parser,
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen error_r) < 0) {
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen if (ctx->config_permission_denied) {
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen /* just restart and maybe next time we will open the
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen config socket before dropping privileges */
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen i_fatal("%s", *error_r);
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen pool_unref(&user_pool);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return -1;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0 &&
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen !ctx->log_initialized) {
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen /* initialize logging again, in case we only read the
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen settings for the first above */
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen ctx->log_initialized = TRUE;
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen master_service_init_log(ctx->service,
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen t_strconcat(ctx->service->name, ": ", NULL));
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen update_log_prefix = TRUE;
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen }
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen sets = master_service_settings_parser_get_others(master_service,
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen set_parser);
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen user_set = sets[0];
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen if (update_log_prefix)
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen mail_storage_service_set_log_prefix(ctx, user_set, NULL, input, NULL);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (ctx->conn == NULL)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* load global plugins */
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen if (mail_storage_service_load_modules(ctx, user_info, user_set, error_r) < 0) {
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen pool_unref(&user_pool);
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen return -1;
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen if (ctx->userdb_next_pool == NULL)
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen temp_pool = pool_alloconly_create("userdb lookup", 2048);
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen else {
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen temp_pool = ctx->userdb_next_pool;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen ctx->userdb_next_pool = NULL;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen pool_ref(temp_pool);
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen }
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = service_auth_userdb_lookup(ctx, input, temp_pool,
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen &username, &userdb_fields, error_r);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (ret <= 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_unref(&temp_pool);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen pool_unref(&user_pool);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ret;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
6494ec1398bbc56e63beba727e2c4538ba5521a7Timo Sirainen if (ctx->userdb_next_fieldsp != NULL)
6494ec1398bbc56e63beba727e2c4538ba5521a7Timo Sirainen *ctx->userdb_next_fieldsp = userdb_fields;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen } else {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen userdb_fields = input->userdb_fields;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user = p_new(user_pool, struct mail_storage_service_user, 1);
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen user->refcount = 1;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen user->service_ctx = ctx;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->pool = user_pool;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen user->input = *input;
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen user->input.userdb_fields = userdb_fields == NULL ? NULL :
23152672e3ad7f3512c11df43e8dabba4fe6407dTimo Sirainen p_strarray_dup(user_pool, userdb_fields);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->input.username = p_strdup(user_pool, username);
bff606130fa332dbf837569f922028b68f45fd61Timo Sirainen user->input.session_id = p_strdup(user_pool, input->session_id);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen if (user->input.session_id == NULL) {
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen user->input.session_id =
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen mail_storage_service_generate_session_id(user_pool,
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen input->session_id_prefix);
d6601a0bc4fd60e58bedbddf2481abd82cba76d7Timo Sirainen }
a020eb653b2620a989e4795adceb6136037327b2Timo Sirainen user->input.session_create_time = input->session_create_time;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->user_info = user_info;
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen user->flags = flags;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
abb9b8f14e83baca887cf12210bfe480f6cde7a6Timo Sirainen
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen sets = master_service_settings_parser_get_others(master_service,
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen user->set_parser);
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen user->user_set = sets[0];
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen user->gid_source = "mail_gid setting";
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen user->uid_source = "mail_uid setting";
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen /* Create an event that will be used as the default event for logging.
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen This event won't be a parent to any other events - mail_user.event
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen will be used for that. */
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen user->event = event_create(input->parent_event);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_add_fields(user->event, (const struct event_add_field []){
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen { .key = "user", .value = user->input.username },
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen { .key = "service", .value = ctx->service->name },
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen { .key = "session", .value = user->input.session_id },
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen { .key = NULL }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen });
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (user->input.local_ip.family != 0) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_add_str(user->event, "local_ip",
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen net_ip2addr(&user->input.local_ip));
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (user->input.local_port != 0) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_add_int(user->event, "local_port",
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen user->input.local_port);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (user->input.remote_ip.family != 0) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_add_str(user->event, "remote_ip",
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen net_ip2addr(&user->input.remote_ip));
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (user->input.remote_port != 0) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_add_int(user->event, "remote_port",
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen user->input.remote_port);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_DEBUG) != 0)
44fea1d434a885f08b399459748b001a89f61c77Timo Sirainen (void)settings_parse_line(user->set_parser, "mail_debug=yes");
44fea1d434a885f08b399459748b001a89f61c77Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char *home = getenv("HOME");
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (home != NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_home", home);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (userdb_fields != NULL) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen auth_user_fields_parse(userdb_fields, temp_pool, &reply);
c56500d4363beba4ffa954069ab30f4401849156Timo Sirainen array_sort(&reply.extra_fields, extra_field_key_cmp_p);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (user_reply_handle(ctx, user, &reply, &error) < 0) {
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen *error_r = t_strdup_printf(
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen "Invalid settings in userdb: %s", error);
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen ret = -2;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
07448eb01d5111f050a0940534111f5a938bd20dTimo Sirainen if (ret > 0 && !settings_parser_check(user->set_parser, user_pool, &error)) {
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen *error_r = t_strdup_printf(
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen "Invalid settings (probably caused by userdb): %s", error);
07448eb01d5111f050a0940534111f5a938bd20dTimo Sirainen ret = -2;
07448eb01d5111f050a0940534111f5a938bd20dTimo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_unref(&temp_pool);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* load per-user plugins */
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen if (ret > 0) {
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen if (mail_storage_service_load_modules(ctx, user_info,
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen user->user_set,
6dc2060d6e0261e4bfd453f1eb1c165cc8d905c1Timo Sirainen error_r) < 0) {
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen ret = -2;
351668ae6972c9f55059501ddb2ed6e70afa2f31Timo Sirainen }
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen }
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0 &&
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen user_set->mail_plugins[0] != '\0') {
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen /* mail_storage_service_load_modules() already avoids loading
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen plugins when the _NO_PLUGINS flag is set. However, it's
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen possible that the plugins are already loaded, because the
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen plugin loading is a global state. This is especially true
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen with doveadm, which loads the mail_plugins immediately at
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen startup so it can find commands registered by plugins. It's
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen fine that extra plugins are loaded - we'll just need to
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen prevent any of their hooks from being called. One easy way
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen to do this is just to clear out the mail_plugins setting: */
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen (void)settings_parse_line(user->set_parser, "mail_plugins=");
38cf8e6fc69413632af2f27702acf2b36449c62fTimo Sirainen }
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen *user_r = user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ret;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen}
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenint mail_storage_service_lookup(struct mail_storage_service_ctx *ctx,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const struct mail_storage_service_input *input,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen struct mail_storage_service_user **user_r,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen const char **error_r)
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen{
a48ccadf62d342063d0fff00fadc791423cc915fTimo Sirainen char *old_log_prefix = i_strdup(i_get_failure_prefix());
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen bool update_log_prefix;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen int ret;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen if (io_loop_get_current_context(current_ioloop) == NULL) {
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen /* no user yet. log prefix should be just "imap:" or something
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen equally unhelpful. we don't know the proper log format yet,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen but initialize it to something better until we know it. */
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen const char *session_id =
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen input->session_id != NULL ? input->session_id :
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen (input->session_id_prefix != NULL ?
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen input->session_id_prefix : NULL);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%s(%s%s,%s)",
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen master_service_get_name(ctx->service), input->username,
1959accd3886d99efccd9f98247f21e8fd54da66Timo Sirainen session_id == NULL ? "" : t_strdup_printf(",%s", session_id),
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen input->remote_ip.family == 0 ? "" :
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen t_strdup_printf(",%s", net_ip2addr(&input->remote_ip)));
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen update_log_prefix = TRUE;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen } else {
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen /* we might be here because we're doing a user lookup for a
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen shared user. the log prefix is likely already usable, so
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen just append our own without replacing the whole thing. */
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%suser-lookup(%s)",
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen old_log_prefix, input->username);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen update_log_prefix = FALSE;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen }
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen ret = mail_storage_service_lookup_real(ctx, input, update_log_prefix,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen user_r, error_r);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%s", old_log_prefix);
a48ccadf62d342063d0fff00fadc791423cc915fTimo Sirainen i_free(old_log_prefix);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen return ret;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen}
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainenvoid mail_storage_service_save_userdb_fields(struct mail_storage_service_ctx *ctx,
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen pool_t pool, const char *const **userdb_fields_r)
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen{
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen i_assert(pool != NULL);
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen i_assert(userdb_fields_r != NULL);
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen ctx->userdb_next_pool = pool;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen ctx->userdb_next_fieldsp = userdb_fields_r;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen *userdb_fields_r = NULL;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen}
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenstatic int
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenmail_storage_service_next_real(struct mail_storage_service_ctx *ctx,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen struct mail_storage_service_user *user,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov const char *session_id_suffix,
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen struct mail_user **mail_user_r,
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen const char **error_r)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges priv;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *error;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t len;
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi bool allow_root =
e0dae5d76ea0a4aef849602750ce73dfae995bc8Martti Rannanjärvi (user->flags & MAIL_STORAGE_SERVICE_FLAG_ALLOW_ROOT) != 0;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen bool temp_priv_drop =
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen bool use_chroot;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen if (service_parse_privileges(ctx, user, &priv, error_r) < 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen return -2;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (*priv.home != '/' && *priv.home != '\0') {
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen *error_r = t_strdup_printf(
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen "Relative home directory paths not supported: %s",
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen priv.home);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return -2;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen /* we can't chroot if we want to switch between users. there's
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen not much point either (from security point of view). but if we're
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen already chrooted, we'll just have to continue and hope that the
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen current chroot is the same as the wanted chroot */
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen use_chroot = !temp_priv_drop ||
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen restrict_access_get_current_chroot() != NULL;
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen len = strlen(priv.chroot);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (len > 2 && strcmp(priv.chroot + len - 2, "/.") == 0 &&
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen strncmp(priv.home, priv.chroot, len - 2) == 0) {
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen /* mail_chroot = /chroot/. means that the home dir already
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen contains the chroot dir. remove it from home. */
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen if (use_chroot) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.home += len - 2;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (*priv.home == '\0')
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.home = "/";
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.chroot = t_strndup(priv.chroot, len - 2);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen set_keyval(ctx, user, "mail_home", priv.home);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen set_keyval(ctx, user, "mail_chroot", priv.chroot);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen } else if (len > 0 && !use_chroot) {
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen /* we're not going to chroot. fix home directory so we can
b00c511e4675c4a1270d92924fc445cfb8631cf3Timo Sirainen access it. */
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (*priv.home == '\0' || strcmp(priv.home, "/") == 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.home = priv.chroot;
ba02cf1dae8acbe439f79085603bb93a870cce34Timo Sirainen else
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.home = t_strconcat(priv.chroot, priv.home, NULL);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen priv.chroot = "";
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen set_keyval(ctx, user, "mail_home", priv.home);
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen }
3c652e7a569c2623d22b4ab30279aebddce4d396Timo Sirainen
c85e266e4d7214adb6f7c65fbbc7d312c5a35dcbTimo Sirainen /* create ioloop context regardless of logging. it's also used by
c85e266e4d7214adb6f7c65fbbc7d312c5a35dcbTimo Sirainen stats plugin. */
c85e266e4d7214adb6f7c65fbbc7d312c5a35dcbTimo Sirainen user->ioloop_ctx = io_loop_context_new(current_ioloop);
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen io_loop_context_add_callbacks(user->ioloop_ctx,
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen mail_storage_service_io_activate_user_cb,
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen mail_storage_service_io_deactivate_user_cb,
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen user);
c85e266e4d7214adb6f7c65fbbc7d312c5a35dcbTimo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen mail_storage_service_init_log(ctx, user, &priv);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (service_drop_privileges(user, &priv,
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi allow_root, temp_priv_drop,
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen FALSE, &error) < 0) {
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen *error_r = t_strdup_printf(
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen "Couldn't drop privileges: %s", error);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
95d9395d15540b3a96f75c7f9fd73e6d8ad5e897Timo Sirainen if (!temp_priv_drop ||
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) != 0)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen restrict_access_allow_coredumps(TRUE);
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen }
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* privileges are dropped. initialize plugins that haven't been
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen initialized yet. */
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen module_dir_init(mail_storage_service_modules);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (mail_storage_service_init_post(ctx, user, &priv,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov session_id_suffix,
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen mail_user_r, error_r) < 0)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return -2;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen struct mail_storage_service_user *user,
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen struct mail_user **mail_user_r,
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen const char **error_r)
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov{
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov return mail_storage_service_next_with_session_suffix(ctx,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov user,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov NULL,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov mail_user_r,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov error_r);
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov}
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitovint mail_storage_service_next_with_session_suffix(struct mail_storage_service_ctx *ctx,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov struct mail_storage_service_user *user,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov const char *session_id_suffix,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov struct mail_user **mail_user_r,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov const char **error_r)
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen{
a48ccadf62d342063d0fff00fadc791423cc915fTimo Sirainen char *old_log_prefix = i_strdup(i_get_failure_prefix());
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen int ret;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen mail_storage_service_set_log_prefix(ctx, user->user_set, user,
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen &user->input, NULL);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%s", old_log_prefix);
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov ret = mail_storage_service_next_real(ctx, user,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov session_id_suffix,
2092da86f3a332e8d7eae1300a3b9852fed8f2f8Sergey Kitov mail_user_r, error_r);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) != 0)
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen i_set_failure_prefix("%s", old_log_prefix);
a48ccadf62d342063d0fff00fadc791423cc915fTimo Sirainen i_free(old_log_prefix);
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen return ret;
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen}
39f5c2b2143842ff6f827b7198cae8853b8c5bbaTimo Sirainen
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainenvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen struct mail_storage_service_user *user)
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen{
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen struct mail_storage_service_privileges priv;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen const char *error;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (service_parse_privileges(ctx, user, &priv, &error) < 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen i_fatal("user %s: %s", user->input.username, error);
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen if (service_drop_privileges(user, &priv,
57316ab705807ac3a433e2ec9b8b6ff5d090c3d7Martti Rannanjärvi TRUE, FALSE, TRUE, &error) < 0)
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen i_fatal("user %s: %s", user->input.username, error);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen}
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct mail_storage_service_input *input,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user **user_r,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_user **mail_user_r,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen int ret;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, error_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (ret <= 0)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ret;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen
61d3fd14828b68d789f3df73d1dbed56e37b7931Timo Sirainen ret = mail_storage_service_next(ctx, user, mail_user_r, error_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (ret < 0) {
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen mail_storage_service_user_unref(&user);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return ret;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *user_r = user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return 1;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen}
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainenvoid mail_storage_service_user_ref(struct mail_storage_service_user *user)
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen{
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen i_assert(user->refcount > 0);
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen user->refcount++;
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen}
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainenvoid mail_storage_service_user_unref(struct mail_storage_service_user **_user)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user = *_user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *_user = NULL;
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen i_assert(user->refcount > 0);
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen if (--user->refcount > 0)
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen return;
d1bf4ae66b8bf3b9e28df1823d6d4adda2b923b6Timo Sirainen
6727b100f6afdde039efc755a7cf45c93362f347Timo Sirainen if (user->ioloop_ctx != NULL) {
b758c60275e9862515510949939aba7a15c6e296Timo Sirainen if (io_loop_get_current_context(current_ioloop) == user->ioloop_ctx)
b758c60275e9862515510949939aba7a15c6e296Timo Sirainen mail_storage_service_io_deactivate_user(user);
0f8663fcdbb10c162113c76b53a309b59b3bd500Timo Sirainen io_loop_context_remove_callbacks(user->ioloop_ctx,
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen mail_storage_service_io_activate_user_cb,
cafe72dae0fd4dc48025e0c8dc189bf4901e9f70Timo Sirainen mail_storage_service_io_deactivate_user_cb, user);
6727b100f6afdde039efc755a7cf45c93362f347Timo Sirainen io_loop_context_unref(&user->ioloop_ctx);
6727b100f6afdde039efc755a7cf45c93362f347Timo Sirainen }
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen if (array_is_created(&user->event_stack)) {
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen i_assert(array_count(&user->event_stack) == 0);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen array_free(&user->event_stack);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen }
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen settings_parser_deinit(&user->set_parser);
d2729522f8b4754b66be7e16548ede39b033fb04Timo Sirainen event_unref(&user->event);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_unref(&user->pool);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen}
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainenvoid mail_storage_service_init_settings(struct mail_storage_service_ctx *ctx,
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen const struct mail_storage_service_input *input)
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen{
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen const struct setting_parser_info *user_info;
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen const struct mail_user_settings *user_set;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const struct setting_parser_context *set_parser;
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen const char *error;
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen pool_t temp_pool;
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen void **sets;
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen if (ctx->conn != NULL)
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen return;
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen temp_pool = pool_alloconly_create("service all settings", 4096);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen if (mail_storage_service_read_settings(ctx, input, temp_pool,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &user_info, &set_parser,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &error) < 0)
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen i_fatal("%s", error);
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen sets = master_service_settings_parser_get_others(master_service,
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen set_parser);
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen user_set = sets[0];
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen pool_unref(&temp_pool);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen}
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainenstatic int
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainenmail_storage_service_all_iter_deinit(struct mail_storage_service_ctx *ctx)
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen{
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen int ret = 0;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen if (ctx->auth_list != NULL) {
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen ret = auth_master_user_list_deinit(&ctx->auth_list);
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen auth_master_deinit(&ctx->iter_conn);
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen }
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen return ret;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen}
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen
55e04e5659b27c520633835d3f04e2eca7f21117Timo Sirainenvoid mail_storage_service_all_init_mask(struct mail_storage_service_ctx *ctx,
55e04e5659b27c520633835d3f04e2eca7f21117Timo Sirainen const char *user_mask_hint)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen{
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen enum auth_master_flags flags = 0;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen (void)mail_storage_service_all_iter_deinit(ctx);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen mail_storage_service_init_settings(ctx, NULL);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen /* create a new connection, because the iteration might take a while
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen and we might want to do USER lookups during it, which don't mix
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen well in the same connection. */
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen if (ctx->debug)
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen flags |= AUTH_MASTER_FLAG_DEBUG;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen ctx->iter_conn = auth_master_init(auth_master_get_socket_path(ctx->conn),
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen flags);
55e04e5659b27c520633835d3f04e2eca7f21117Timo Sirainen ctx->auth_list = auth_master_user_list_init(ctx->iter_conn,
55e04e5659b27c520633835d3f04e2eca7f21117Timo Sirainen user_mask_hint, NULL);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen}
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_all_next(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **username_r)
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen{
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen i_assert((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen *username_r = auth_master_user_list_next(ctx->auth_list);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen if (*username_r != NULL)
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen return 1;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen return mail_storage_service_all_iter_deinit(ctx);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen}
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid mail_storage_service_deinit(struct mail_storage_service_ctx **_ctx)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_ctx *ctx = *_ctx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *_ctx = NULL;
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen (void)mail_storage_service_all_iter_deinit(ctx);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (ctx->conn != NULL) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (mail_user_auth_master_conn == ctx->conn)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_user_auth_master_conn = NULL;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen auth_master_deinit(&ctx->conn);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (ctx->set_cache != NULL)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen master_service_settings_cache_deinit(&ctx->set_cache);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_unref(&ctx->pool);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen module_dir_unload(&mail_storage_service_modules);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_storage_deinit();
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dict_drivers_unregister_builtin();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid **mail_storage_service_user_get_set(struct mail_storage_service_user *user)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen{
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen return master_service_settings_parser_get_others(master_service,
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen user->set_parser);
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen}
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainenconst struct mail_storage_settings *
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainenmail_storage_service_user_get_mail_set(struct mail_storage_service_user *user)
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen{
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen return mail_user_set_get_driver_settings(
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen user->user_info, user->user_set,
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen MAIL_STORAGE_SET_DRIVER_NAME);
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen}
544a946df4de398125bafb51f26d5e3697bde649Timo Sirainen
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainenconst struct mail_storage_service_input *
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainenmail_storage_service_user_get_input(struct mail_storage_service_user *user)
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainen{
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainen return &user->input;
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainen}
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainen
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainenstruct setting_parser_context *
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainenmail_storage_service_user_get_settings_parser(struct mail_storage_service_user *user)
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainen{
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainen return user->set_parser;
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainen}
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainen
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainenstruct mail_storage_service_ctx *
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainenmail_storage_service_user_get_service_ctx(struct mail_storage_service_user *user)
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainen{
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainen return user->service_ctx;
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainen}
95dcc0f8e80cc8c9278c904c3cd06dcc4a6d2d33Timo Sirainen
30b849c26358317b4e25b19ced4b7deb55f59c0aTimo Sirainenpool_t mail_storage_service_user_get_pool(struct mail_storage_service_user *user)
30b849c26358317b4e25b19ced4b7deb55f59c0aTimo Sirainen{
30b849c26358317b4e25b19ced4b7deb55f59c0aTimo Sirainen return user->pool;
30b849c26358317b4e25b19ced4b7deb55f59c0aTimo Sirainen}
30b849c26358317b4e25b19ced4b7deb55f59c0aTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid *mail_storage_service_get_settings(struct master_service *service)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen void **sets, *set;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen T_BEGIN {
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen sets = master_service_settings_get_others(service);
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen set = sets[1];
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen } T_END;
2eb0402a28bd0422e0170160808c67d6c7274689Timo Sirainen return set;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitovint mail_storage_service_user_set_setting(struct mail_storage_service_user *user,
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov const char *key,
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov const char *value,
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov const char **error_r)
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov{
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov int ret = settings_parse_keyvalue(user->set_parser, key, value);
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov *error_r = settings_parser_get_error(user->set_parser);
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov return ret;
24ff040448e018738515f7bfcc6f1a6e5d08c10dSergey Kitov}