mail-storage-service.c revision 9b78c0d5e13141f4df6c6e483f854e5acb861288
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen "Invalid user settings. Refer to server log for more information."
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const char *set_cache_module, *set_cache_service;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct master_service_settings_cache *set_cache;
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainenstruct module *mail_storage_service_modules = NULL;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenmail_user_set_get_mail_debug(const struct setting_parser_info *user_info,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void set_keyval(struct mail_storage_service_ctx *ctx,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *str;
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 i_debug("Ignoring overridden (-o) userdb setting: %s",
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic int set_line(struct mail_storage_service_ctx *ctx,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *key;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_debug = mail_user_set_get_mail_debug(user->user_info,
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* assume it's a plugin setting */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* this setting was already overridden with -o parameter */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen "Unknown userdb setting: %s" :
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *dir)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *const *chroot_dirs;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenuser_reply_handle(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i, count;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_uid", dec2str(reply->uid));
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_gid", dec2str(reply->gid));
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_home", reply->home);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (!validate_chroot(user->user_set, reply->chroot)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "userdb returned invalid chroot directory: %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "(see valid_chroot_dirs setting)",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen set_keyval(ctx, user, "mail_chroot", reply->chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str = array_get(&reply->extra_fields, &count);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen if (n != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen str[i], settings_parser_get_error(user->set_parser));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen const struct mail_storage_service_input *input,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *const **fields_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_debug("changed username to %s", new_username);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen } else if (ret == 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*p == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*p == '\0')
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenservice_drop_privileges(const struct mail_user_settings *set,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf("Unknown mail_uid user: %s",
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Mail access for users with UID %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_uid in config file).",
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = t_strdup_printf("Unknown mail_gid group: %s",
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Mail access for users with GID %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_gid in config file).",
9aceb071780a949f4e8bf41d3cf80735d9ac7fdfTimo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid)) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen "Unknown mail_privileged_group: %s",
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;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen *error_r = "Mail access not allowed for root";
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* we're changing the UID,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen switch back to root first */
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(setuid_uid));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const char *home, struct mail_user **mail_user_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_user = mail_user_alloc(user->input.username, user->user_info,
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 mail_set = mail_user_set_get_storage_set(mail_user);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
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. */
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. */
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen if (mail_namespaces_init(mail_user, error_r) < 0) {
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenstatic const struct var_expand_table *
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenget_var_expand_table(struct master_service *service,
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen static struct var_expand_table static_tab[] = {
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[1].value = t_strcut(input->username, '@');
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen tab[5].value = net_ip2addr(&input->remote_ip);
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 i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen var_expand(ret, str + 1, get_var_expand_table(service, input));
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenmail_storage_service_init_log(struct master_service *service,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen var_expand(str, user->user_set->mail_log_prefix,
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenstatic void mail_storage_service_time_moved(time_t old_time, time_t new_time)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen i_warning("Time jumped forwards %ld seconds", diff);
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 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 /* 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 */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_init(struct master_service *service,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct setting_parser_info *set_roots[],
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen unsigned int count;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen io_loop_set_time_moved_callback(current_ioloop,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen pool = pool_alloconly_create("mail storage service", 2048);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen ctx = p_new(pool, struct mail_storage_service_ctx, 1);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* @UNSAFE */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
878a83a906e1be6354b563ead096955a22ad5fbeTimo Sirainen p_new(pool, const struct setting_parser_info *, count + 2);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
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) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenint mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct mail_storage_service_input *input,
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)
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;
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 (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
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 /* already looked up settings at least once.
faca2afa3576c50caf28e0f009555325d2a49e0bTimo Sirainen we really shouldn't be execing anymore. */
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 settings_parser_dyn_update(pool, &set_input.roots, dyn_parsers);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen mail_user_setting_parser_info.module_name) == 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
72f2a851238e5661695c63bff0e9a9e800ba577aTimo Sirainen ctx->debug = mail_user_set_get_mail_debug(user_info, user_set);
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT) != 0)
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path, flags);
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
9ba7e76c20be775f368254e3059a6189fe789f16Timo Sirainen mod_set.version = master_service_get_version_string(ctx->service);
72f2a851238e5661695c63bff0e9a9e800ba577aTimo Sirainen mod_set.debug = mail_user_set_get_mail_debug(user_info, user_set);
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen module_dir_load_missing(mail_storage_service_modules,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_lookup(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct mail_storage_service_input *input,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const struct setting_parser_context *set_parser;
4c1deab456fe8877bf025d11843167ac1f36327aTimo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*5);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user_set = settings_parser_get_list(set_parser)[1];
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);
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 user = p_new(user_pool, struct mail_storage_service_user, 1);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen user->input.username = p_strdup(user_pool, username);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen if (!settings_parser_check(user->set_parser, user_pool, &error))
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen user->user_set = settings_parser_get_list(user->set_parser)[1];
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
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",
48ada47cce07fb7195a3437224c7c25f542326b0Timo Sirainen /* load per-user plugins */
57ff998a443881c8959a8e65f6325cf19fefc1d0Timo Sirainen mail_storage_service_load_modules(ctx, user_info,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen unsigned int len;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0;
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
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,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
63fc74d46d781e87edb6388e51a5bf942c5f8eabTimo Sirainen "Relative home directory paths not supported: %s",
705f6fbad395e6f014838e797b7dbcaceafd2f1dTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen mail_storage_service_init_log(ctx->service, user);
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,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen i_error("user %s: Couldn't drop privileges: %s",
95d9395d15540b3a96f75c7f9fd73e6d8ad5e897Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) != 0)
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 /* we couldn't do chrooting, so if chrooting was enabled fix
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen the home directory */
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* home dir already contains the chroot dir */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainenvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
c06d6ea0766d0520af1a93e6000c0e73f350e0a2Timo Sirainen if (service_drop_privileges(user_set, user->system_groups_user,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const struct mail_storage_service_input *input,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, error_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ret = mail_storage_service_next(ctx, user, mail_user_r);
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen *error_r = ret == -2 ? ERRSTR_INVALID_USER_SETTINGS :
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid mail_storage_service_user_free(struct mail_storage_service_user **_user)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct mail_storage_service_user *user = *_user;
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainenvoid mail_storage_service_init_settings(struct mail_storage_service_ctx *ctx,
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen const struct mail_storage_service_input *input)
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const struct setting_parser_context *set_parser;
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_set = settings_parser_get_list(set_parser)[1];
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_all_init(struct mail_storage_service_ctx *ctx)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen (void)auth_master_user_list_deinit(&ctx->auth_list);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen mail_storage_service_init_settings(ctx, NULL);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen ctx->auth_list = auth_master_user_list_init(ctx->conn);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen return auth_master_user_list_count(ctx->auth_list);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_all_next(struct mail_storage_service_ctx *ctx,
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen i_assert((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen *username_r = auth_master_user_list_next(ctx->auth_list);
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen return auth_master_user_list_deinit(&ctx->auth_list);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid mail_storage_service_deinit(struct mail_storage_service_ctx **_ctx)
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen (void)auth_master_user_list_deinit(&ctx->auth_list);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen master_service_settings_cache_deinit(&ctx->set_cache);
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen module_dir_unload(&mail_storage_service_modules);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid **mail_storage_service_user_get_set(struct mail_storage_service_user *user)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen return settings_parser_get_list(user->set_parser) + 1;
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainenmail_storage_service_user_get_input(struct mail_storage_service_user *user)
608bdb7f008cd5cd332d727018a9e8173abec998Timo Sirainenmail_storage_service_user_get_settings_parser(struct mail_storage_service_user *user)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid *mail_storage_service_get_settings(struct master_service *service)