mail-storage-service.c revision 878a83a906e1be6354b563ead096955a22ad5fbe
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const char *set_cache_module, *set_cache_service;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen struct master_service_settings_cache *set_cache;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen const struct dynamic_settings_parser *set_cache_dyn_parsers;
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen struct setting_parser_info *set_cache_dyn_parsers_parent;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const struct setting_parser_info **set_cache_roots;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic void set_keyval(struct setting_parser_context *set_parser,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *str;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const char *dir)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char *const *chroot_dirs;
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenuser_reply_handle(struct mail_storage_service_user *user,
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen const char **error_r)
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen unsigned int i, count;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_uid", dec2str(reply->uid));
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_gid", dec2str(reply->gid));
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_home", reply->home);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen if (!validate_chroot(user->user_set, reply->chroot)) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "userdb returned invalid chroot directory: %s "
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen "(see valid_chroot_dirs setting)",
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen set_keyval(set_parser, "mail_chroot", reply->chroot);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str = array_get(&reply->extra_fields, &count);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (n != 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* assume it's a plugin setting */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen str[i], settings_parser_get_error(set_parser));
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const struct mail_storage_service_input *input,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const char *const **fields_r,
08ea8b302b62bc688f6b34f89f674e08eda7828cTimo Sirainen const char **error_r)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_debug("changed username to %s", new_username);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen } else if (ret == 0)
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r)
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen if (*p == '\0')
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r)
a505d1beb29cbffab724b92ad16d0c44ebbaffb9Timo Sirainen if (*p == '\0')
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenservice_drop_privileges(const struct mail_user_settings *set,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen i_fatal("Unknown mail_uid user: %s", set->mail_uid);
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen "not permitted (see first_valid_uid in config file).",
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("Unknown mail_gid group: %s", set->mail_gid);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen "not permitted (see first_valid_gid in config file).",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid)) {
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen /* we can't chroot if we want to switch between users. there's not
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen much point either (from security point of view) */
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen rset.chroot_dir = *chroot == '\0' || keep_setuid_root ? NULL : chroot;
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0)))
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen /* we're changing the UID,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen switch back to root first */
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(setuid_uid));
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen const char *home, struct mail_user **mail_user_r,
0ff28df76775a0740faa4370ec72d5a6a97534bfTimo Sirainen const char **error_r)
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user = mail_user_alloc(user->input.username, user->user_info,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen &user->input.local_ip, &user->input.remote_ip);
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen /* we don't want to write core files to any users' home
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen directories since they could contain information about other
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen users' mails as well. so do no chdiring to home. */
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen /* If possible chdir to home directory, so that core file
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen could be written in case we crash. */
dcf49e7ccf042982fde41ce256723f925fb9f1e4Timo Sirainen if (mail_namespaces_init(mail_user, error_r) < 0) {
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainenstatic const struct var_expand_table *
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainenget_var_expand_table(struct master_service *service,
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen static struct var_expand_table static_tab[] = {
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen tab[1].value = t_strcut(input->username, '@');
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen tab[5].value = net_ip2addr(&input->remote_ip);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic const char *
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenuser_expand_varstr(struct master_service *service,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct mail_storage_service_input *input, const char *str)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen var_expand(ret, str + 1, get_var_expand_table(service, input));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenmail_storage_service_init_log(struct master_service *service,
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainen user_set = master_service_settings_get_others(service)[0];
62ccd8152d2f0142ab3301da4f5270b9d4f06718Timo Sirainen var_expand(str, user->user_set->mail_log_prefix,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenstatic void mail_storage_service_time_moved(time_t old_time, time_t new_time)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_warning("Time jumped forwards %ld seconds", diff);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen i_fatal("Time just moved backwards by %ld seconds. "
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen "This might cause a lot of problems, "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "so I'll just kill myself now. "
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen "http://wiki.dovecot.org/TimeMovedBackwards", diff);
9d6dec796909384293006e4289436579089d88d5Timo Sirainen i_error("Time just moved backwards by %ld seconds. "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "I'll sleep now until we're back in present. "
9d6dec796909384293006e4289436579089d88d5Timo Sirainen "http://wiki.dovecot.org/TimeMovedBackwards", diff);
9d6dec796909384293006e4289436579089d88d5Timo Sirainen /* Sleep extra second to make sure usecs also grows. */
9d6dec796909384293006e4289436579089d88d5Timo Sirainen /* don't use sleep()'s return value, because
9d6dec796909384293006e4289436579089d88d5Timo Sirainen it could get us to a long loop in case
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen interrupts just keep coming */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenmail_storage_service_init(struct master_service *service,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct setting_parser_info *set_roots[],
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen io_loop_set_time_moved_callback(current_ioloop,
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen pool = pool_alloconly_create("mail storage service", 2048);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx = p_new(pool, struct mail_storage_service_ctx, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen /* @UNSAFE */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen p_new(pool, const struct setting_parser_info *, count + 2);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen memcpy(ctx->set_roots + 1, set_roots, sizeof(*ctx->set_roots) * count);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* do all the global initialization. delay initializing plugins until
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen we drop privileges the first time. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) {
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainensettings_parser_update_children_parent(struct setting_parser_info *parent,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int i, count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen for (count = 0; parent->defines[count].key != NULL; count++) ;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_defs = p_new(pool, struct setting_define, count + 1);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen memcpy(new_defs, parent->defines, sizeof(*new_defs) * count);
8bb360f9e5de1c25e4f875205bb06e8bf15dae14Timo Sirainen for (i = 0; i < count; i++) {
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct dynamic_settings_parser **_dyn_parsers)
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct dynamic_settings_parser *dyn_parsers = *_dyn_parsers;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const const struct setting_parser_info **roots = *_roots;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen const struct setting_parser_info *old_parent, **new_roots;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen struct setting_parser_info *new_parent, *new_info;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen struct dynamic_settings_parser *new_dyn_parsers;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen unsigned int i, count;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* settings_parser_info_update() modifies the parent structure.
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen since we may be using the same structure later, we want it to be
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen in its original state, so we'll have to copy all structures. */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_parent = p_new(pool, struct setting_parser_info, 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen settings_parser_update_children_parent(new_parent, pool);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* update root */
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen for (count = 0; roots[count] != NULL; count++) ;
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen new_roots = p_new(pool, const struct setting_parser_info *, count + 1);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainen for (i = 0; i < count; i++) {
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen /* update parent in dyn_parsers */
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (count = 0; dyn_parsers[count].name != NULL; count++) ;
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen new_dyn_parsers = p_new(pool, struct dynamic_settings_parser, count + 1);
35077ff71c0082c1370d9c296abce3153f645958Timo Sirainen for (i = 0; i < count; i++) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen new_info = p_new(pool, struct setting_parser_info, 1);
fc1696e32dd732a5bbabc3c8f64810448e327043Timo Sirainenint mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen const struct mail_storage_service_input *input,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct setting_parser_info **user_info_r,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const struct setting_parser_context **parser_r,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char **error_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct master_service_settings_input set_input;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct master_service_settings_output set_output;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen unsigned int i;
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* settings reader may exec doveconf, which is going to clear
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen environment, and if we're not doing a userdb lookup we want to
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache_module = p_strdup(ctx->pool, input->module);
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache_service = p_strdup(ctx->pool, input->service);
822b71c04ddd61cb08a0104f9e58f55334725e2aTimo Sirainen ctx->set_cache = master_service_settings_cache_init(
88de8e8fb4ad86f59ac0c4d85f5a9103dfd3fcc0Timo Sirainen if (null_strcmp(input->module, ctx->set_cache_module) == 0 &&
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen null_strcmp(input->service, ctx->set_cache_service) == 0) {
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen set_input.dyn_parsers = ctx->set_cache_dyn_parsers;
6797b2bb35596ec47d7f140eba79d4c686f370bcTimo Sirainen if (master_service_settings_cache_read(ctx->set_cache,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen set_input.dyn_parsers = mail_storage_get_dynamic_parsers(pool);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen dyn_parsers_update_parent(pool, &set_input.roots,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_user_setting_parser_info.module_name) == 0) {
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path, flags);
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mod_set.version = master_service_get_version_string(ctx->service);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen modules = module_dir_load_missing(modules, user_set->mail_plugin_dir,
c817e46049c4dc07f7bbc16f43f903ab7ea9ae7dTimo Sirainenint mail_storage_service_lookup(struct mail_storage_service_ctx *ctx,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen const struct mail_storage_service_input *input,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen const char **error_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char *const *userdb_fields;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const struct setting_parser_context *set_parser;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*5);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user_set = settings_parser_get_list(set_parser)[1];
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* load global plugins */
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_load_modules(ctx, user_info, user_set);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen temp_pool = pool_alloconly_create("userdb lookup", 1024);
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen ret = service_auth_userdb_lookup(ctx, input, temp_pool,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen user = p_new(user_pool, struct mail_storage_service_user, 1);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen user->input.username = p_strdup(user_pool, username);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (!settings_parser_check(user->set_parser, user_pool, error_r))
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen user->user_set = settings_parser_get_list(user->set_parser)[1];
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen set_keyval(user->set_parser, "mail_home", home);
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen auth_user_fields_parse(userdb_fields, temp_pool, &reply);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if (user_reply_handle(user, &reply, error_r) < 0)
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen /* load per-user plugins */
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen mail_storage_service_load_modules(ctx, user_info, user->user_set);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen const char **error_r)
4fe2f0c34044aad9f6cc1e23dfc696dc464348cbTimo Sirainen const struct mail_user_settings *user_set = user->user_set;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen unsigned int len;
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP);
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen /* variable strings are expanded in mail_user_init(),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen but we need the home and chroot sooner so do them separately here. */
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen i_error("user %s: Relative home directory paths not supported: "
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen mail_storage_service_init_log(ctx->service, user);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen service_drop_privileges(user_set, user->system_groups_user,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0,
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen (ctx->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) != 0)
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* privileges are dropped. initialize plugins that haven't been
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen initialized yet. */
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen /* we couldn't do chrooting, so if chrooting was enabled fix
704efd0b34e3611e3decf1d559fe6a93214b0bd0Timo Sirainen the home directory */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* home dir already contains the chroot dir */
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen set_keyval(user->set_parser, "mail_home", home);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainenvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen const struct mail_user_settings *user_set = user->user_set;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen home = user_expand_varstr(ctx->service, &user->input,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
2c7ab05ef98c46eb70c8ba6ea85e49749aafb2a3Timo Sirainen service_drop_privileges(user_set, user->system_groups_user,
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainenint mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen const struct mail_storage_service_input *input,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen const char **error_r)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, &error);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen *error_r = t_strdup_printf("User lookup failed: %s", error);
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen if (mail_storage_service_next(ctx, user, mail_user_r, &error) < 0) {
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen *error_r = t_strdup_printf("User init failed: %s", error);
7f97ca94363c9e38fbbaaef204d6d01c54af6fc4Timo Sirainenvoid mail_storage_service_user_free(struct mail_storage_service_user **_user)
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen struct mail_storage_service_user *user = *_user;
const char *error;
&error) < 0)
const char **username_r)
const struct mail_storage_service_input *
struct setting_parser_context *
T_BEGIN {
} T_END;
return set;