mail-storage-service.c revision 608bdb7f008cd5cd332d727018a9e8173abec998
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainenstatic void set_keyval(struct setting_parser_context *set_parser,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *str;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
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)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenuser_reply_handle(struct mail_storage_service_user *user,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i, count;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen set_keyval(set_parser, "mail_uid", dec2str(reply->uid));
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen set_keyval(set_parser, "mail_gid", dec2str(reply->gid));
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen set_keyval(set_parser, "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)",
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen set_keyval(set_parser, "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) {
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen /* assume it's a plugin setting */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen str[i], settings_parser_get_error(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,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("Unknown mail_uid user: %s", set->mail_uid);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_uid in config file).",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("Unknown mail_gid group: %s", set->mail_gid);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "not permitted (see first_valid_gid in config file).",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!parse_uid(set->mail_privileged_group, &rset.privileged_gid))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("Unknown mail_gid group: %s", set->mail_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.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0)))
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* we're changing the UID,
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen switch back to root first */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home, disallow_root);
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);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 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,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen sets = master_service_settings_get_others(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,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx = i_new(struct mail_storage_service_ctx, 1);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* @UNSAFE */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->set_roots = i_new(const struct setting_parser_info *, count + 2);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen memcpy(ctx->set_roots + 1, set_roots, sizeof(*ctx->set_roots) * count);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* do all the global initialization. delay initializing plugins until
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen we drop privileges the first time. */
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_NO_LOG_INIT) == 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainensettings_parser_update_children_parent(struct setting_parser_info *parent,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen unsigned int i, count;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (count = 0; parent->defines[count].key != NULL; count++) ;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_defs = p_new(pool, struct setting_define, count + 1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen memcpy(new_defs, parent->defines, sizeof(*new_defs) * count);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (i = 0; i < count; i++) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const struct setting_parser_info *old_parent, **new_roots;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct setting_parser_info *new_parent, *new_info;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct dynamic_settings_parser *new_dyn_parsers;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen unsigned int i, count;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* settings_parser_info_update() modifies the parent structure.
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen since we may be using the same structure later, we want it to be
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen in its original state, so we'll have to copy all structures. */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen old_parent = input->dyn_parsers[0].info->parent;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_parent = p_new(pool, struct setting_parser_info, 1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen settings_parser_update_children_parent(new_parent, pool);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* update root */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (count = 0; input->roots[count] != NULL; count++) ;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_roots = p_new(pool, const struct setting_parser_info *, count + 1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (i = 0; i < count; i++) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* update parent in dyn_parsers */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (count = 0; input->dyn_parsers[count].name != NULL; count++) ;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_dyn_parsers = p_new(pool, struct dynamic_settings_parser, count + 1);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen for (i = 0; i < count; i++) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
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,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen const char **error_r)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct master_service_settings_input set_input;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen unsigned int i;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_input.dyn_parsers = mail_storage_get_dynamic_parsers();
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;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *error_r = t_strdup_printf("Error reading configuration: %s",
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (ctx->set_roots[i] == &mail_user_setting_parser_info) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen modules = *user_set->mail_plugins == '\0' ? NULL :
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen master_service_get_version_string(ctx->service));
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path,
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)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char *const *userdb_fields;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*4);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen sets = settings_parser_get_list(ctx->service->set_parser);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen mail_storage_service_first_init(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);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen settings_parser_dup(ctx->service->set_parser, user_pool);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen sets = settings_parser_get_list(user->set_parser);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_keyval(user->set_parser, "mail_home", home);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen auth_user_fields_parse(userdb_fields, temp_pool, &reply);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (user_reply_handle(user, &reply, error_r) < 0)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen const char **error_r)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen unsigned int len;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP);
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,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_error("user %s: Relative home directory paths not supported: "
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_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) {
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen service_drop_privileges(user_set, user->system_groups_user,
1b04762685272a53643ac2179939537a44c7c044Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* privileges dropped for the first time. initialize the
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen modules now to avoid code running as root. */
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 */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen set_keyval(user->set_parser, "mail_home", home);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
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)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, &error);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *error_r = t_strdup_printf("User lookup failed: %s", error);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (mail_storage_service_next(ctx, user, mail_user_r, &error) < 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen *error_r = t_strdup_printf("User init failed: %s", error);
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)
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen temp_pool = pool_alloconly_create("service all settings", 4096);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen if (mail_storage_service_read_settings(ctx, input, temp_pool,
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen sets = settings_parser_get_list(ctx->service->set_parser);
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);
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)