mail-storage-service.c revision 878a83a906e1be6354b563ead096955a22ad5fbe
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "lib.h"
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen#include "ioloop.h"
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen#include "array.h"
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen#include "hostpid.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "module-dir.h"
6dc4af35c045e10609b13fe80f9cf33f3a06c3ceTimo Sirainen#include "restrict-access.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "eacces-error.h"
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen#include "str.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "var-expand.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "dict.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "settings-parser.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "auth-master.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "master-service-private.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "master-service-settings.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "master-service-settings-cache.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-user.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-namespace.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-storage.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-storage-service.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <stdlib.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <sys/stat.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <pwd.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <grp.h>
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen#ifdef HAVE_SYS_TIME_H
9d6dec796909384293006e4289436579089d88d5Timo Sirainen# include <sys/time.h>
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen#endif
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen#ifdef HAVE_SYS_RESOURCE_H
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen# include <sys/resource.h>
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen#endif
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen#define MAX_TIME_BACKWARDS_SLEEP 5
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen#define MAX_NOWARN_FORWARD_SECS 10
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenstruct mail_storage_service_ctx {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen pool_t pool;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen struct master_service *service;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen struct auth_master_connection *conn;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct auth_master_user_list_ctx *auth_list;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen const struct setting_parser_info **set_roots;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen enum mail_storage_service_flags flags;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const char *set_cache_module, *set_cache_service;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct master_service_settings_cache *set_cache;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen const struct dynamic_settings_parser *set_cache_dyn_parsers;
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen struct setting_parser_info *set_cache_dyn_parsers_parent;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const struct setting_parser_info **set_cache_roots;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen unsigned int debug:1;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen};
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstruct mail_storage_service_user {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen pool_t pool;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen struct mail_storage_service_input input;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *system_groups_user;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct mail_user_settings *user_set;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct setting_parser_info *user_info;
9d6dec796909384293006e4289436579089d88d5Timo Sirainen struct setting_parser_context *set_parser;
9d6dec796909384293006e4289436579089d88d5Timo Sirainen};
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstatic struct module *modules = NULL;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic void set_keyval(struct setting_parser_context *set_parser,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *key, const char *value)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen{
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *str;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen str = t_strconcat(key, "=", value, NULL);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen i_fatal("Invalid userdb input '%s': %s", str,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen settings_parser_get_error(set_parser));
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen}
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const char *dir)
9d6dec796909384293006e4289436579089d88d5Timo Sirainen{
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *const *chroot_dirs;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (*dir == '\0')
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return FALSE;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (*user_set->valid_chroot_dirs == '\0')
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen return FALSE;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen while (*chroot_dirs != NULL) {
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen if (**chroot_dirs != '\0' &&
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return TRUE;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen chroot_dirs++;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return FALSE;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenstatic int
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenuser_reply_handle(struct mail_storage_service_user *user,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const struct auth_user_reply *reply,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char **error_r)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen{
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *const *str, *p, *line, *key;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen unsigned int i, count;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen int ret = 0;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (reply->uid != (uid_t)-1) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (reply->uid == 0) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen *error_r = "userdb returned 0 as uid";
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_uid", dec2str(reply->uid));
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (reply->gid != (uid_t)-1)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_gid", dec2str(reply->gid));
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (reply->home != NULL)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_home", reply->home);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (reply->chroot != NULL) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (!validate_chroot(user->user_set, reply->chroot)) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen *error_r = t_strdup_printf(
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "userdb returned invalid chroot directory: %s "
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen "(see valid_chroot_dirs setting)",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen reply->chroot);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return -1;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_chroot", reply->chroot);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str = array_get(&reply->extra_fields, &count);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen for (i = 0; i < count && ret == 0; i++) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen line = str[i];
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->system_groups_user =
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen p_strdup(user->pool, line + 19);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen } else if (strncmp(line, "nice=", 5) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen#ifdef HAVE_SETPRIORITY
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen int n = atoi(line + 5);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (n != 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (setpriority(PRIO_PROCESS, 0, n) < 0)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen i_error("setpriority(%d) failed: %m", n);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen#endif
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen } else T_BEGIN {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if ((p = strchr(str[i], '=')) == NULL)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen line = t_strconcat(str[i], "=yes", NULL);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen line = str[i];
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen key = t_strcut(line, '=');
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* assume it's a plugin setting */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen line = t_strconcat("plugin/", line, NULL);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ret = settings_parse_line(set_parser, line);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen } T_END;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (ret < 0) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen str[i], settings_parser_get_error(set_parser));
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen }
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return ret;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen}
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic int
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const struct mail_storage_service_input *input,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen pool_t pool, const char **user,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const char *const **fields_r,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const char **error_r)
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen{
145ecefd208f5d7f6a52cb326a85f28d2154e217Timo Sirainen struct auth_user_info info;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen const char *new_username;
145ecefd208f5d7f6a52cb326a85f28d2154e217Timo Sirainen int ret;
145ecefd208f5d7f6a52cb326a85f28d2154e217Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen memset(&info, 0, sizeof(info));
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen info.service = ctx->service->name;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen info.local_ip = input->local_ip;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen info.remote_ip = input->remote_ip;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen &new_username, fields_r);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (ret > 0) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (strcmp(*user, new_username) != 0) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (ctx->debug)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_debug("changed username to %s", new_username);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *user = t_strdup(new_username);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen }
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *user = new_username;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen } else if (ret == 0)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *error_r = "unknown user";
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen else
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen *error_r = "userdb lookup failed";
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return ret;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen}
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen{
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen struct passwd *pw;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen char *p;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (*str >= '0' && *str <= '9') {
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen *uid_r = (uid_t)strtoul(str, &p, 10);
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen if (*p == '\0')
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen return TRUE;
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen }
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen pw = getpwnam(str);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (pw == NULL)
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen return FALSE;
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen *uid_r = pw->pw_uid;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return TRUE;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen}
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r)
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen{
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen struct group *gr;
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen char *p;
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen if (*str >= '0' && *str <= '9') {
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen *gid_r = (gid_t)strtoul(str, &p, 10);
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen if (*p == '\0')
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen return TRUE;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen }
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen gr = getgrnam(str);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (gr == NULL)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return FALSE;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *gid_r = gr->gr_gid;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return TRUE;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen}
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenstatic void
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenservice_drop_privileges(const struct mail_user_settings *set,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const char *system_groups_user,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const char *home, const char *chroot,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen bool disallow_root, bool keep_setuid_root,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen bool setenv_only)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen{
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct restrict_access_settings rset;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen uid_t current_euid, setuid_uid = 0;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen current_euid = geteuid();
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen restrict_access_init(&rset);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (*set->mail_uid != '\0') {
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen if (!parse_uid(set->mail_uid, &rset.uid))
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen i_fatal("Unknown mail_uid user: %s", set->mail_uid);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (rset.uid < (uid_t)set->first_valid_uid ||
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen (set->last_valid_uid != 0 &&
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.uid > (uid_t)set->last_valid_uid)) {
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen i_fatal("Mail access for users with UID %s "
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen "not permitted (see first_valid_uid in config file).",
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen dec2str(rset.uid));
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (*set->mail_gid != '\0') {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (!parse_gid(set->mail_gid, &rset.gid))
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("Unknown mail_gid group: %s", set->mail_gid);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (rset.gid < (gid_t)set->first_valid_gid ||
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen (set->last_valid_gid != 0 &&
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.gid > (gid_t)set->last_valid_gid)) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("Mail access for users with GID %s "
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen "not permitted (see first_valid_gid in config file).",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen dec2str(rset.gid));
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (*set->mail_privileged_group != '\0') {
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid)) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("Unknown mail_privileged_group: %s",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen set->mail_gid);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen }
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen if (*set->mail_access_groups != '\0')
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen rset.extra_groups = set->mail_access_groups;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.first_valid_gid = set->first_valid_gid;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.last_valid_gid = set->last_valid_gid;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen /* we can't chroot if we want to switch between users. there's not
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen much point either (from security point of view) */
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.chroot_dir = *chroot == '\0' || keep_setuid_root ? NULL : chroot;
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen rset.system_groups_user = system_groups_user;
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (disallow_root &&
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0)))
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("Mail access not allowed for root");
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (keep_setuid_root) {
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen if (current_euid != rset.uid) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (current_euid != 0) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen /* we're changing the UID,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen switch back to root first */
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (seteuid(0) < 0)
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("seteuid(0) failed: %m");
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen setuid_uid = rset.uid;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.uid = (uid_t)-1;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen disallow_root = FALSE;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen }
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if (!setenv_only) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen disallow_root);
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen } else {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen restrict_access_set_env(&rset);
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen }
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if (setuid_uid != 0 && !setenv_only) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (seteuid(setuid_uid) < 0)
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(setuid_uid));
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen}
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainenstatic int
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen struct mail_storage_service_user *user,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const char *home, struct mail_user **mail_user_r,
0ff28df76775a0740faa4370ec72d5a6a97534bfTimo Sirainen const char **error_r)
0ff28df76775a0740faa4370ec72d5a6a97534bfTimo Sirainen{
0ff28df76775a0740faa4370ec72d5a6a97534bfTimo Sirainen const struct mail_storage_settings *mail_set;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen struct mail_user *mail_user;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user = mail_user_alloc(user->input.username, user->user_info,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen user->user_set);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen &user->input.local_ip, &user->input.remote_ip);
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen if (mail_set->mail_debug) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen i_debug("Effective uid=%s, gid=%s, home=%s",
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen /* we don't want to write core files to any users' home
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen directories since they could contain information about other
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen users' mails as well. so do no chdiring to home. */
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen } else if (*home != '\0' &&
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen /* If possible chdir to home directory, so that core file
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen could be written in case we crash. */
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if (chdir(home) < 0) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if (errno == EACCES) {
fbb324fedccfd1cff9fb41b64f715ca77e5d588fTimo Sirainen i_error("%s", eacces_error_get("chdir",
fbb324fedccfd1cff9fb41b64f715ca77e5d588fTimo Sirainen t_strconcat(home, "/", NULL)));
fbb324fedccfd1cff9fb41b64f715ca77e5d588fTimo Sirainen } if (errno != ENOENT)
fbb324fedccfd1cff9fb41b64f715ca77e5d588fTimo Sirainen i_error("chdir(%s) failed: %m", home);
fbb324fedccfd1cff9fb41b64f715ca77e5d588fTimo Sirainen else if (mail_set->mail_debug)
6fbd30cc189c5acb4cfce841e17ed0eeff5056f4Timo Sirainen i_debug("Home dir not found: %s", home);
6fbd30cc189c5acb4cfce841e17ed0eeff5056f4Timo Sirainen }
6fbd30cc189c5acb4cfce841e17ed0eeff5056f4Timo Sirainen }
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen if (mail_user_init(mail_user, error_r) < 0) {
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen mail_user_unref(&mail_user);
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen return -1;
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen }
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen if (mail_namespaces_init(mail_user, error_r) < 0) {
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen mail_user_unref(&mail_user);
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen return -1;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen }
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen *mail_user_r = mail_user;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen return 0;
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen}
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic const struct var_expand_table *
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainenget_var_expand_table(struct master_service *service,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen struct mail_storage_service_input *input)
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen{
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen static struct var_expand_table static_tab[] = {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen { 'u', NULL, "user" },
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen { 'n', NULL, "username" },
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen { 'd', NULL, "domain" },
9d6dec796909384293006e4289436579089d88d5Timo Sirainen { 's', NULL, "service" },
9d6dec796909384293006e4289436579089d88d5Timo Sirainen { 'l', NULL, "lip" },
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen { 'r', NULL, "rip" },
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen { 'p', NULL, "pid" },
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen { 'i', NULL, "uid" },
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen { '\0', NULL, NULL }
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen };
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct var_expand_table *tab;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen tab = t_malloc(sizeof(static_tab));
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen tab[0].value = input->username;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen tab[1].value = t_strcut(input->username, '@');
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen tab[2].value = strchr(input->username, '@');
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen tab[3].value = service->name;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen tab[4].value = net_ip2addr(&input->local_ip);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen tab[5].value = net_ip2addr(&input->remote_ip);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen tab[6].value = my_pid;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen tab[7].value = dec2str(geteuid());
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen return tab;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen}
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic const char *
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenuser_expand_varstr(struct master_service *service,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct mail_storage_service_input *input, const char *str)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen{
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen string_t *ret;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (*str == SETTING_STRVAR_EXPANDED[0])
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen return str + 1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen ret = t_str_new(256);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen var_expand(ret, str + 1, get_var_expand_table(service, input));
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen return str_c(ret);
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen}
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainenstatic void
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenmail_storage_service_init_log(struct master_service *service,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen struct mail_storage_service_user *user)
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen{
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen const struct mail_user_settings *user_set;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen user_set = master_service_settings_get_others(service)[0];
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen T_BEGIN {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen string_t *str;
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen str = t_str_new(256);
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen var_expand(str, user->user_set->mail_log_prefix,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen get_var_expand_table(service, &user->input));
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen master_service_init_log(service, str_c(str));
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen } T_END;
9d6dec796909384293006e4289436579089d88d5Timo Sirainen}
9d6dec796909384293006e4289436579089d88d5Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic void mail_storage_service_time_moved(time_t old_time, time_t new_time)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen{
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen long diff = new_time - old_time;
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen if (diff > 0) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (diff > MAX_NOWARN_FORWARD_SECS)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_warning("Time jumped forwards %ld seconds", diff);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen return;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen }
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen diff = -diff;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (diff > MAX_TIME_BACKWARDS_SLEEP) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_fatal("Time just moved backwards by %ld seconds. "
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen "This might cause a lot of problems, "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "so I'll just kill myself now. "
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen "http://wiki.dovecot.org/TimeMovedBackwards", diff);
9d6dec796909384293006e4289436579089d88d5Timo Sirainen } else {
9d6dec796909384293006e4289436579089d88d5Timo Sirainen i_error("Time just moved backwards by %ld seconds. "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "I'll sleep now until we're back in present. "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "http://wiki.dovecot.org/TimeMovedBackwards", diff);
9d6dec796909384293006e4289436579089d88d5Timo Sirainen /* Sleep extra second to make sure usecs also grows. */
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen diff++;
9d6dec796909384293006e4289436579089d88d5Timo Sirainen
9d6dec796909384293006e4289436579089d88d5Timo Sirainen while (diff > 0 && sleep(diff) != 0) {
9d6dec796909384293006e4289436579089d88d5Timo Sirainen /* don't use sleep()'s return value, because
9d6dec796909384293006e4289436579089d88d5Timo Sirainen it could get us to a long loop in case
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen interrupts just keep coming */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen diff = old_time - time(NULL) + 1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen}
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstruct mail_storage_service_ctx *
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenmail_storage_service_init(struct master_service *service,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct setting_parser_info *set_roots[],
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen enum mail_storage_service_flags flags)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen{
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct mail_storage_service_ctx *ctx;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen pool_t pool;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (void)umask(0077);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen io_loop_set_time_moved_callback(current_ioloop,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_storage_service_time_moved);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_storage_init();
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen mail_storage_register_all();
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen mailbox_list_register_all();
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen pool = pool_alloconly_create("mail storage service", 2048);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx = p_new(pool, struct mail_storage_service_ctx, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->pool = pool;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->service = service;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->flags = flags;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen /* @UNSAFE */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen if (set_roots == NULL)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen count = 0;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen else
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->set_roots =
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen p_new(pool, const struct setting_parser_info *, count + 2);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen memcpy(ctx->set_roots + 1, set_roots, sizeof(*ctx->set_roots) * count);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* do all the global initialization. delay initializing plugins until
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen we drop privileges the first time. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen master_service_init_log(service,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen t_strconcat(service->name, ": ", NULL));
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen }
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen dict_drivers_register_builtin();
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return ctx;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainenstruct auth_master_connection *
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen{
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen i_assert(ctx->conn != NULL);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen return ctx->conn;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen}
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainenstatic void
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainensettings_parser_update_children_parent(struct setting_parser_info *parent,
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen pool_t pool)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct setting_define *new_defs;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen struct setting_parser_info *new_info;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int i, count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen for (count = 0; parent->defines[count].key != NULL; count++) ;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_defs = p_new(pool, struct setting_define, count + 1);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen memcpy(new_defs, parent->defines, sizeof(*new_defs) * count);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen parent->defines = new_defs;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen for (i = 0; i < count; i++) {
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen if (new_defs[i].list_info == NULL ||
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_defs[i].list_info->parent == NULL)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen continue;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen *new_info = *new_defs[i].list_info;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen new_info->parent = parent;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen new_defs[i].list_info = new_info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen}
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainenstatic struct setting_parser_info *
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainendyn_parsers_update_parent(pool_t pool,
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct setting_parser_info ***_roots,
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct dynamic_settings_parser **_dyn_parsers)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen{
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct dynamic_settings_parser *dyn_parsers = *_dyn_parsers;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const const struct setting_parser_info **roots = *_roots;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct setting_parser_info *old_parent, **new_roots;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen struct setting_parser_info *new_parent, *new_info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen struct dynamic_settings_parser *new_dyn_parsers;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen unsigned int i, count;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* settings_parser_info_update() modifies the parent structure.
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen since we may be using the same structure later, we want it to be
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen in its original state, so we'll have to copy all structures. */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen old_parent = dyn_parsers[0].info->parent;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_parent = p_new(pool, struct setting_parser_info, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen *new_parent = *old_parent;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen settings_parser_update_children_parent(new_parent, pool);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* update root */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen for (count = 0; roots[count] != NULL; count++) ;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_roots = p_new(pool, const struct setting_parser_info *, count + 1);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen for (i = 0; i < count; i++) {
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (roots[i] == old_parent)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_roots[i] = new_parent;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen else
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_roots[i] = roots[i];
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen }
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen *_roots = new_roots;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen /* update parent in dyn_parsers */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (count = 0; dyn_parsers[count].name != NULL; count++) ;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_dyn_parsers = p_new(pool, struct dynamic_settings_parser, count + 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (i = 0; i < count; i++) {
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_dyn_parsers[i] = dyn_parsers[i];
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen *new_info = *dyn_parsers[i].info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_info->parent = new_parent;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_dyn_parsers[i].info = new_info;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen }
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen *_dyn_parsers = new_dyn_parsers;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen return new_parent;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen}
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenint mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct mail_storage_service_input *input,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen pool_t pool,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct setting_parser_info **user_info_r,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct setting_parser_context **parser_r,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char **error_r)
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct master_service_settings_input set_input;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct master_service_settings_output set_output;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen unsigned int i;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen memset(&set_input, 0, sizeof(set_input));
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen set_input.roots = ctx->set_roots;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* settings reader may exec doveconf, which is going to clear
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen environment, and if we're not doing a userdb lookup we want to
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen use $HOME */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_input.preserve_home =
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (input != NULL) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_input.module = input->module;
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen set_input.service = input->service;
7c27b0ab7213121ea43994499c04059413f6d0f2Timo Sirainen set_input.username = input->username;
7c27b0ab7213121ea43994499c04059413f6d0f2Timo Sirainen set_input.local_ip = input->local_ip;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen set_input.remote_ip = input->remote_ip;
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (ctx->set_cache == NULL) {
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache_module = p_strdup(ctx->pool, input->module);
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache_service = p_strdup(ctx->pool, input->service);
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache = master_service_settings_cache_init(
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->service, input->module, input->service);
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache_roots = ctx->set_roots;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen ctx->set_cache_dyn_parsers =
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen mail_storage_get_dynamic_parsers(ctx->pool);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen ctx->set_cache_dyn_parsers_parent =
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen dyn_parsers_update_parent(ctx->pool,
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen &ctx->set_cache_roots,
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen &ctx->set_cache_dyn_parsers);
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen }
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen if (null_strcmp(input->module, ctx->set_cache_module) == 0 &&
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen null_strcmp(input->service, ctx->set_cache_service) == 0) {
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen set_input.roots = ctx->set_cache_roots;
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen set_input.dyn_parsers = ctx->set_cache_dyn_parsers;
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen set_input.dyn_parsers_parent =
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen ctx->set_cache_dyn_parsers_parent;
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen if (master_service_settings_cache_read(ctx->set_cache,
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen &set_input,
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen parser_r, error_r) < 0)
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_input.dyn_parsers = mail_storage_get_dynamic_parsers(pool);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_input.dyn_parsers_parent =
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen dyn_parsers_update_parent(pool, &set_input.roots,
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen &set_input.dyn_parsers);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen &set_output, error_r) < 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen *error_r = t_strdup_printf(
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen "Error reading configuration: %s", *error_r);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen return -1;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen *parser_r = ctx->service->set_parser;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen for (i = 0; ctx->set_roots[i] != NULL; i++) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (strcmp(ctx->set_roots[i]->module_name,
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_user_setting_parser_info.module_name) == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen *user_info_r = set_input.roots[i];
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen i_unreached();
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen return -1;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen const struct setting_parser_info *user_info,
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen const struct mail_user_settings *user_set)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const struct mail_storage_settings *mail_set;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen enum auth_master_flags flags = 0;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen i_assert(ctx->conn == NULL);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen MAIL_STORAGE_SET_DRIVER_NAME);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen ctx->debug = mail_set->mail_debug;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->debug)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen flags |= AUTH_MASTER_FLAG_DEBUG;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT) != 0)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen flags |= AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path, flags);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_assert(mail_user_auth_master_conn == NULL);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen mail_user_auth_master_conn = ctx->conn;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic void
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const struct setting_parser_info *user_info,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct mail_user_settings *user_set)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct mail_storage_settings *mail_set;
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen struct module_dir_load_settings mod_set;
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (*user_set->mail_plugins == '\0')
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen return;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen MAIL_STORAGE_SET_DRIVER_NAME);
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen memset(&mod_set, 0, sizeof(mod_set));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mod_set.version = master_service_get_version_string(ctx->service);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mod_set.require_init_funcs = TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mod_set.debug = mail_set->mail_debug;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen modules = module_dir_load_missing(modules, user_set->mail_plugin_dir,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen user_set->mail_plugins, &mod_set);
c000c8eca8f24b2a0c76393ec4bbf76a505a4983Timo Sirainen}
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
c817e46049c4dc07f7bbc16f43f903ab7ea9ae7dTimo Sirainenint mail_storage_service_lookup(struct mail_storage_service_ctx *ctx,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen const struct mail_storage_service_input *input,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen struct mail_storage_service_user **user_r,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen const char **error_r)
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen{
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen struct mail_storage_service_user *user;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char *username = input->username;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct setting_parser_info *user_info;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen const struct mail_user_settings *user_set;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char *const *userdb_fields;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct auth_user_reply reply;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const struct setting_parser_context *set_parser;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen pool_t user_pool, temp_pool;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen int ret = 1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*5);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen &user_info, &set_parser,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen error_r) < 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen pool_unref(&user_pool);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen return -1;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user_set = settings_parser_get_list(set_parser)[1];
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (ctx->conn == NULL)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* load global plugins */
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_load_modules(ctx, user_info, user_set);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen temp_pool = pool_alloconly_create("userdb lookup", 1024);
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen ret = service_auth_userdb_lookup(ctx, input, temp_pool,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen &username, &userdb_fields,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen error_r);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (ret <= 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen pool_unref(&temp_pool);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen pool_unref(&user_pool);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen return ret;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen } else {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen userdb_fields = input->userdb_fields;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user = p_new(user_pool, struct mail_storage_service_user, 1);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen memset(user_r, 0, sizeof(user_r));
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->pool = user_pool;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->input = *input;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->input.userdb_fields = NULL;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->input.username = p_strdup(user_pool, username);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->user_info = user_info;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (!settings_parser_check(user->set_parser, user_pool, error_r))
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen i_unreached();
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen user->user_set = settings_parser_get_list(user->set_parser)[1];
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const char *home = getenv("HOME");
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (home != NULL)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen set_keyval(user->set_parser, "mail_home", home);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (userdb_fields != NULL) {
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen auth_user_fields_parse(userdb_fields, temp_pool, &reply);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (user_reply_handle(user, &reply, error_r) < 0)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen ret = -1;
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen }
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen pool_unref(&temp_pool);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen /* load per-user plugins */
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen mail_storage_service_load_modules(ctx, user_info, user->user_set);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen *user_r = user;
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen return ret;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen}
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen struct mail_storage_service_user *user,
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen struct mail_user **mail_user_r,
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen const char **error_r)
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen{
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen const struct mail_user_settings *user_set = user->user_set;
6dc4af35c045e10609b13fe80f9cf33f3a06c3ceTimo Sirainen const char *home, *chroot;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen unsigned int len;
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen bool temp_priv_drop =
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen /* variable strings are expanded in mail_user_init(),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen but we need the home and chroot sooner so do them separately here. */
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen user_set->mail_home);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen user_set->mail_chroot);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (*home != '/' && *home != '\0') {
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen i_error("user %s: Relative home directory paths not supported: "
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen "%s", user->input.username, home);
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen return -1;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen }
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_init_log(ctx->service, user);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen service_drop_privileges(user_set, user->system_groups_user,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen home, chroot,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen temp_priv_drop, FALSE);
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen if (!temp_priv_drop ||
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen restrict_access_allow_coredumps(TRUE);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* privileges are dropped. initialize plugins that haven't been
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen initialized yet. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen module_dir_init(modules);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* we couldn't do chrooting, so if chrooting was enabled fix
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen the home directory */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen len = strlen(chroot);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen strncmp(home, chroot, len - 2) == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* home dir already contains the chroot dir */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (!temp_priv_drop) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen home += len - 2;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (*home == '\0')
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen home = "/";
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen set_keyval(user->set_parser, "mail_home", home);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen chroot = t_strndup(chroot, len - 2);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen }
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen } else if (len > 0 && temp_priv_drop) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_keyval(user->set_parser, "mail_home",
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen t_strconcat(chroot, "/", home, NULL));
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen }
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen mail_user_r, error_r) < 0)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen return -1;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen return 0;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen}
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainenvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen struct mail_storage_service_user *user)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen{
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const char *home, *chroot;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen user_set->mail_home);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen user_set->mail_chroot);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen service_drop_privileges(user_set, user->system_groups_user,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen home, chroot, FALSE, FALSE, TRUE);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen}
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainenint mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen const struct mail_storage_service_input *input,
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen struct mail_storage_service_user **user_r,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct mail_user **mail_user_r,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen const char **error_r)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen{
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct mail_storage_service_user *user;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const char *error;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen int ret;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, &error);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen if (ret <= 0) {
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen *error_r = t_strdup_printf("User lookup failed: %s", error);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen return ret;
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen }
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen if (mail_storage_service_next(ctx, user, mail_user_r, &error) < 0) {
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen mail_storage_service_user_free(&user);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen *error_r = t_strdup_printf("User init failed: %s", error);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen return -1;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen }
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen *user_r = user;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen return 1;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen}
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenvoid mail_storage_service_user_free(struct mail_storage_service_user **_user)
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen{
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen struct mail_storage_service_user *user = *_user;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen *_user = NULL;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen settings_parser_deinit(&user->set_parser);
pool_unref(&user->pool);
}
void mail_storage_service_init_settings(struct mail_storage_service_ctx *ctx,
const struct mail_storage_service_input *input)
{
const struct setting_parser_info *user_info;
const struct mail_user_settings *user_set;
const struct setting_parser_context *set_parser;
const char *error;
pool_t temp_pool;
if (ctx->conn != NULL)
return;
temp_pool = pool_alloconly_create("service all settings", 4096);
if (mail_storage_service_read_settings(ctx, input, temp_pool,
&user_info, &set_parser,
&error) < 0)
i_fatal("%s", error);
user_set = settings_parser_get_list(set_parser)[1];
mail_storage_service_first_init(ctx, user_info, user_set);
pool_unref(&temp_pool);
}
unsigned int
mail_storage_service_all_init(struct mail_storage_service_ctx *ctx)
{
if (ctx->auth_list != NULL)
(void)auth_master_user_list_deinit(&ctx->auth_list);
mail_storage_service_init_settings(ctx, NULL);
ctx->auth_list = auth_master_user_list_init(ctx->conn);
return auth_master_user_list_count(ctx->auth_list);
}
int mail_storage_service_all_next(struct mail_storage_service_ctx *ctx,
const char **username_r)
{
i_assert((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0);
*username_r = auth_master_user_list_next(ctx->auth_list);
if (*username_r != NULL)
return 1;
return auth_master_user_list_deinit(&ctx->auth_list);
}
void mail_storage_service_deinit(struct mail_storage_service_ctx **_ctx)
{
struct mail_storage_service_ctx *ctx = *_ctx;
*_ctx = NULL;
if (ctx->auth_list != NULL)
(void)auth_master_user_list_deinit(&ctx->auth_list);
if (ctx->conn != NULL) {
if (mail_user_auth_master_conn == ctx->conn)
mail_user_auth_master_conn = NULL;
auth_master_deinit(&ctx->conn);
}
if (ctx->set_cache != NULL)
master_service_settings_cache_deinit(&ctx->set_cache);
pool_unref(&ctx->pool);
module_dir_unload(&modules);
mail_storage_deinit();
dict_drivers_unregister_builtin();
}
void **mail_storage_service_user_get_set(struct mail_storage_service_user *user)
{
return settings_parser_get_list(user->set_parser) + 1;
}
const struct mail_storage_service_input *
mail_storage_service_user_get_input(struct mail_storage_service_user *user)
{
return &user->input;
}
struct setting_parser_context *
mail_storage_service_user_get_settings_parser(struct mail_storage_service_user *user)
{
return user->set_parser;
}
void *mail_storage_service_get_settings(struct master_service *service)
{
void **sets, *set;
T_BEGIN {
sets = master_service_settings_get_others(service);
set = sets[1];
} T_END;
return set;
}