mail-storage-service.c revision 9b78c0d5e13141f4df6c6e483f854e5acb861288
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#include "ioloop.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "array.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "hostpid.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "module-dir.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "restrict-access.h"
abf015c9682f0f723db87a7c97bc284ef814818fTimo Sirainen#include "eacces-error.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 <stdlib.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <sys/stat.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <pwd.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <grp.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
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct mail_storage_service_ctx {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_t pool;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct master_service *service;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen struct auth_master_connection *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
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int debug:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstruct mail_storage_service_user {
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen pool_t pool;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen struct mail_storage_service_input input;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const char *system_groups_user;
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;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen};
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainenstruct module *mail_storage_service_modules = NULL;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo 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 const char *str;
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
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str = t_strconcat(key, "=", value, NULL);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("Invalid userdb input '%s': %s", str,
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;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *key;
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);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen key = t_strcut(line, '=');
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
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = settings_parse_line(set_parser, line);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (mail_debug && ret >= 0) {
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{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *const *str, *line;
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 }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_uid", dec2str(reply->uid));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->gid != (uid_t)-1)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_gid", dec2str(reply->gid));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->home != NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_home", reply->home);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->chroot != NULL) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (!validate_chroot(user->user_set, reply->chroot)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "userdb returned invalid chroot directory: %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "(see valid_chroot_dirs setting)",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen reply->chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_chroot", reply->chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str = array_get(&reply->extra_fields, &count);
d7ec773d995888b09c4d8c88a4b0b134a2002361Timo Sirainen for (i = 0; i < count && ret >= 0; 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);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen } else if (strncmp(line, "nice=", 5) == 0) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen#ifdef HAVE_SETPRIORITY
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen int n = atoi(line + 5);
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen 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
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen } else T_BEGIN {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen ret = set_line(ctx, user, line);
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen } T_END;
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
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen memset(&info, 0, sizeof(info));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen info.service = ctx->service->name;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.local_ip = input->local_ip;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen info.remote_ip = input->remote_ip;
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
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct passwd *pw;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen char *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*str >= '0' && *str <= '9') {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *uid_r = (uid_t)strtoul(str, &p, 10);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*p == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pw = getpwnam(str);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (pw == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *uid_r = pw->pw_uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct group *gr;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen char *p;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*str >= '0' && *str <= '9') {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *gid_r = (gid_t)strtoul(str, &p, 10);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*p == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen gr = getgrnam(str);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (gr == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *gid_r = gr->gr_gid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainenstatic int
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenservice_drop_privileges(const struct mail_user_settings *set,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen const char *system_groups_user,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen const char *home, const char *chroot,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen bool disallow_root, bool keep_setuid_root,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen bool setenv_only, const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct restrict_access_settings rset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uid_t current_euid, setuid_uid = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen current_euid = geteuid();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen restrict_access_init(&rset);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_uid != '\0') {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (!parse_uid(set->mail_uid, &rset.uid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf("Unknown mail_uid user: %s",
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen set->mail_uid);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (rset.uid < (uid_t)set->first_valid_uid ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (set->last_valid_uid != 0 &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.uid > (uid_t)set->last_valid_uid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Mail access for users with UID %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_uid in config file).",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen dec2str(rset.uid));
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_gid != '\0') {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (!parse_gid(set->mail_gid, &rset.gid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf("Unknown mail_gid group: %s",
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen set->mail_gid);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (rset.gid < (gid_t)set->first_valid_gid ||
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (set->last_valid_gid != 0 &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.gid > (gid_t)set->last_valid_gid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Mail access for users with GID %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_gid in config file).",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen dec2str(rset.gid));
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_privileged_group != '\0') {
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf(
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Unknown mail_privileged_group: %s",
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen set->mail_gid);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_access_groups != '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.extra_groups = set->mail_access_groups;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.first_valid_gid = set->first_valid_gid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.last_valid_gid = set->last_valid_gid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we can't chroot if we want to switch between users. there's not
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen much point either (from security point of view) */
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen rset.chroot_dir = *chroot == '\0' || keep_setuid_root ? NULL : chroot;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.system_groups_user = system_groups_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (disallow_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) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (current_euid != rset.uid) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (current_euid != 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* we're changing the UID,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen switch back to root first */
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen if (seteuid(0) < 0)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen i_fatal("seteuid(0) failed: %m");
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen }
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen setuid_uid = rset.uid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.uid = (uid_t)-1;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen disallow_root = FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen if (!setenv_only) {
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen disallow_root);
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)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("seteuid(%s) failed: %m", 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,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const char *home, struct mail_user **mail_user_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mail_storage_settings *mail_set;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_user *mail_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_user = mail_user_alloc(user->input.username, user->user_info,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->user_set);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen &user->input.local_ip, &user->input.remote_ip);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen if (mail_set->mail_debug) {
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk i_debug("Effective uid=%s, gid=%s, home=%s",
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen }
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
263946a65b625fd4198619a8626db0f36bbafd66Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
263946a65b625fd4198619a8626db0f36bbafd66Timo Sirainen (ctx->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. */
02a6291366caff79793db35d479e2a062bec2af4Timo Sirainen } else if (*home != '\0' &&
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* If possible chdir to home directory, so that core file
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen could be written in case we crash. */
573085b4b25b0bbae8d27969df2c91702eefa23eTimo Sirainen if (chdir(home) < 0) {
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen if (errno == EACCES) {
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen i_error("%s", eacces_error_get("chdir",
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen t_strconcat(home, "/", NULL)));
0ee3fdb5e94ae6f34cb873ca3c9858342621e55fTimo Sirainen } if (errno != ENOENT)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("chdir(%s) failed: %m", home);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else if (mail_set->mail_debug)
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk i_debug("Home dir not found: %s", home);
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 }
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen if (mail_namespaces_init(mail_user, error_r) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_user_unref(&mail_user);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *mail_user_r = mail_user;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenstatic const struct var_expand_table *
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenget_var_expand_table(struct master_service *service,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen struct mail_storage_service_input *input)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen{
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen static struct var_expand_table static_tab[] = {
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 'u', NULL, "user" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 'n', NULL, "username" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 'd', NULL, "domain" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 's', NULL, "service" },
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen { 'l', NULL, "lip" },
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen { 'r', NULL, "rip" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 'p', NULL, "pid" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { 'i', NULL, "uid" },
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen { '\0', NULL, NULL }
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen };
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen struct var_expand_table *tab;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen tab = t_malloc(sizeof(static_tab));
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[0].value = input->username;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[1].value = t_strcut(input->username, '@');
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[2].value = strchr(input->username, '@');
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen tab[3].value = service->name;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[4].value = net_ip2addr(&input->local_ip);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[5].value = net_ip2addr(&input->remote_ip);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[6].value = my_pid;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[7].value = dec2str(geteuid());
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen return tab;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen}
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenstatic const char *
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenuser_expand_varstr(struct master_service *service,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen struct mail_storage_service_input *input, const char *str)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen{
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen string_t *ret;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen if (*str == SETTING_STRVAR_EXPANDED[0])
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen return str + 1;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen ret = t_str_new(256);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen var_expand(ret, str + 1, get_var_expand_table(service, input));
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen return str_c(ret);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen}
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenmail_storage_service_init_log(struct master_service *service,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen{
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen T_BEGIN {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen string_t *str;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen str = t_str_new(256);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen var_expand(str, user->user_set->mail_log_prefix,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen get_var_expand_table(service, &user->input));
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen master_service_init_log(service, str_c(str));
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen } T_END;
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. "
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen "http://wiki.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. "
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen "http://wiki.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;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool_t pool;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo 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();
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_storage_register_all();
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mailbox_list_register_all();
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) {
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen master_service_init_log(service,
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen t_strconcat(service->name, ": ", NULL));
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
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;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen unsigned int i;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen memset(&set_input, 0, sizeof(set_input));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.roots = ctx->set_roots;
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 */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen set_input.preserve_home =
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 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 }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen 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 &&
674f541b16689c0ed090dac32db94463c5af3977Timo Sirainen null_strcmp(set_input.service, ctx->set_cache_service) == 0) {
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);
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
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
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen i_assert(ctx->conn == NULL);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo 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;
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path, flags);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_assert(mail_user_auth_master_conn == NULL);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_user_auth_master_conn = ctx->conn;
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen}
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainenstatic void
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen const struct setting_parser_info *user_info,
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen const struct mail_user_settings *user_set)
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen{
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen struct module_dir_load_settings mod_set;
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen if (*user_set->mail_plugins == '\0')
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen return;
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
b7835adbfddd8c92b51d6653fb759f963302fa78Timo Sirainen return;
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen memset(&mod_set, 0, sizeof(mod_set));
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen mod_set.version = master_service_get_version_string(ctx->service);
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
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen mail_storage_service_modules =
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen module_dir_load_missing(mail_storage_service_modules,
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen user_set->mail_plugin_dir,
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen user_set->mail_plugins, &mod_set);
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen}
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_lookup(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 const char **error_r)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
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;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_t user_pool, temp_pool;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen int ret = 1;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
4c1deab456fe8877bf025d11843167ac1f36327aTimo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*5);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen &user_info, &set_parser,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen &error) < 0) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: %s", username, error);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen pool_unref(&user_pool);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = MAIL_ERRSTR_CRITICAL_MSG;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return -1;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen }
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user_set = settings_parser_get_list(set_parser)[1];
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (ctx->conn == NULL)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* load global plugins */
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen mail_storage_service_load_modules(ctx, user_info, user_set);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen temp_pool = pool_alloconly_create("userdb lookup", 1024);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = service_auth_userdb_lookup(ctx, input, temp_pool,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen &username, &userdb_fields,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen 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 }
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);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen memset(user_r, 0, sizeof(user_r));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->pool = user_pool;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen user->input = *input;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->input.userdb_fields = NULL;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->input.username = p_strdup(user_pool, username);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user->user_info = user_info;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (!settings_parser_check(user->set_parser, user_pool, &error))
abb9b8f14e83baca887cf12210bfe480f6cde7a6Timo Sirainen i_unreached();
abb9b8f14e83baca887cf12210bfe480f6cde7a6Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user->user_set = settings_parser_get_list(user->set_parser)[1];
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if ((ctx->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);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (user_reply_handle(ctx, user, &reply, &error) < 0) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: Invalid settings in userdb: %s",
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen username, error);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = ERRSTR_INVALID_USER_SETTINGS;
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen ret = -2;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen pool_unref(&temp_pool);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* load per-user plugins */
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen if (ret > 0) {
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen mail_storage_service_load_modules(ctx, user_info,
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen user->user_set);
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen }
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen *user_r = user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return ret;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen}
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen struct mail_user **mail_user_r)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen{
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen const char *home, *chroot, *error;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen unsigned int len;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen bool disallow_root =
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen bool temp_priv_drop =
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen /* variable strings are expanded in mail_user_init(),
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen but we need the home and chroot sooner so do them separately here. */
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen user_set->mail_home);
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen user_set->mail_chroot);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (*home != '/' && *home != '\0') {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: "
63fc74d46d781e87edb6388e51a5bf942c5f8eabTimo Sirainen "Relative home directory paths not supported: %s",
63fc74d46d781e87edb6388e51a5bf942c5f8eabTimo Sirainen user->input.username, home);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return -2;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen mail_storage_service_init_log(ctx->service, user);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (service_drop_privileges(user_set, user->system_groups_user,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen home, chroot, disallow_root,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen temp_priv_drop, FALSE, &error) < 0) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: Couldn't drop privileges: %s",
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen user->input.username, error);
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen return -1;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen }
95d9395d15540b3a96f75c7f9fd73e6d8ad5e897Timo Sirainen if (!temp_priv_drop ||
95d9395d15540b3a96f75c7f9fd73e6d8ad5e897Timo Sirainen (ctx->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
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we couldn't do chrooting, so if chrooting was enabled fix
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen the home directory */
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen len = strlen(chroot);
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen strncmp(home, chroot, len - 2) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* home dir already contains the chroot dir */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (!temp_priv_drop) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen home += len - 2;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (*home == '\0')
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen home = "/";
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_home", home);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen chroot = t_strndup(chroot, len - 2);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen } else if (len > 0 && temp_priv_drop) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_home",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen t_strconcat(chroot, "/", home, NULL));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen mail_user_r, &error) < 0) {
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: Initialization failed: %s",
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen user->input.username, error);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return -2;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen }
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainenvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen struct mail_storage_service_user *user)
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen{
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen const char *home, *chroot, *error;
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen user_set->mail_home);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen user_set->mail_chroot);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (service_drop_privileges(user_set, user->system_groups_user,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen home, chroot, FALSE, FALSE, TRUE,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen &error) < 0)
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen i_fatal("%s", 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
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ret = mail_storage_service_next(ctx, user, mail_user_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (ret < 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen mail_storage_service_user_free(&user);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = ret == -2 ? ERRSTR_INVALID_USER_SETTINGS :
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen MAIL_ERRSTR_CRITICAL_MSG;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen return ret;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *user_r = user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return 1;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen}
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid mail_storage_service_user_free(struct mail_storage_service_user **_user)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen{
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user = *_user;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *_user = NULL;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen settings_parser_deinit(&user->set_parser);
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;
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);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user_set = settings_parser_get_list(set_parser)[1];
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen pool_unref(&temp_pool);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen}
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainenunsigned int
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_all_init(struct mail_storage_service_ctx *ctx)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen{
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen if (ctx->auth_list != NULL)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen (void)auth_master_user_list_deinit(&ctx->auth_list);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen mail_storage_service_init_settings(ctx, NULL);
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen ctx->auth_list = auth_master_user_list_init(ctx->conn);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen return auth_master_user_list_count(ctx->auth_list);
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;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen return auth_master_user_list_deinit(&ctx->auth_list);
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;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen if (ctx->auth_list != NULL)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen (void)auth_master_user_list_deinit(&ctx->auth_list);
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{
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen return settings_parser_get_list(user->set_parser) + 1;
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen}
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo 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
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}