mail-storage-service.c revision b9b841558c5f91db7f5fc71c0ac62aad1bbf6418
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "ioloop.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "array.h"
dfa2201c6ac8ddb2d2798dee15662cfe774e644eMartti Rannanjärvi#include "hostpid.h"
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen#include "module-dir.h"
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen#include "restrict-access.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "eacces-error.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "ipwd.h"
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen#include "str.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "var-expand.h"
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen#include "dict.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "settings-parser.h"
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen#include "auth-master.h"
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen#include "master-service-private.h"
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen#include "master-service-settings.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "master-service-settings-cache.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-user.h"
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi#include "mail-namespace.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage-service.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdlib.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <sys/stat.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#ifdef HAVE_SYS_TIME_H
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen# include <sys/time.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#endif
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#ifdef HAVE_SYS_RESOURCE_H
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen# include <sys/resource.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#endif
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#define MAX_TIME_BACKWARDS_SLEEP 5
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#define MAX_NOWARN_FORWARD_SECS 10
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#define ERRSTR_INVALID_USER_SETTINGS \
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen "Invalid user settings. Refer to server log for more information."
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainenstruct mail_storage_service_ctx {
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen pool_t pool;
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen struct master_service *service;
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen struct auth_master_connection *conn;
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen struct auth_master_user_list_ctx *auth_list;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const struct setting_parser_info **set_roots;
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen enum mail_storage_service_flags flags;
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *set_cache_module, *set_cache_service;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct master_service_settings_cache *set_cache;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
104318260228780a5c6b3181b3401e8e504e2776Timo Sirainen unsigned int debug:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int log_initialized:1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct mail_storage_service_user {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pool_t pool;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_storage_service_input input;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen enum mail_storage_service_flags flags;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *system_groups_user, *uid_source, *gid_source;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mail_user_settings *user_set;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct setting_parser_info *user_info;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct setting_parser_context *set_parser;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen};
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainenstruct module *mail_storage_service_modules = NULL;
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainen
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainenstatic bool
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainenmail_user_set_get_mail_debug(const struct setting_parser_info *user_info,
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen const struct mail_user_settings *user_set)
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen{
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen const struct mail_storage_settings *mail_set;
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen MAIL_STORAGE_SET_DRIVER_NAME);
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen return mail_set->mail_debug;
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen}
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainenstatic void set_keyval(struct mail_storage_service_ctx *ctx,
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen struct mail_storage_service_user *user,
2f94ca6b0f70641fe31c8e1f93404ca0df8bb289Timo Sirainen const char *key, const char *value)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen const char *str;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* this setting was already overridden with -o parameter */
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen if (mail_user_set_get_mail_debug(user->user_info,
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen user->user_set)) {
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen key);
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen }
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen return;
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen }
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen str = t_strconcat(key, "=", value, NULL);
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen if (settings_parse_line(set_parser, str) < 0) {
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen i_fatal("Invalid userdb input '%s': %s", str,
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen settings_parser_get_error(set_parser));
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen }
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen}
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainenstatic int set_line(struct mail_storage_service_ctx *ctx,
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen struct mail_storage_service_user *user,
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen const char *line)
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen{
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen bool mail_debug;
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen const char *key;
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen int ret;
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_debug = mail_user_set_get_mail_debug(user->user_info,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen user->user_set);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (strchr(line, '=') == NULL)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen line = t_strconcat(line, "=yes", NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen key = t_strcut(line, '=');
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* assume it's a plugin setting */
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen key = t_strconcat("plugin/", key, NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen line = t_strconcat("plugin/", line, NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* this setting was already overridden with -o parameter */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_debug) {
7fe37c2b0e4cd2a39896ab16e47eb418a59e3934Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen key);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return 1;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen }
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen ret = settings_parse_line(set_parser, line);
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen if (mail_debug && ret >= 0) {
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen i_debug(ret == 0 ?
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen "Unknown userdb setting: %s" :
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen "Added userdb setting: %s", line);
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen }
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return ret;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char *dir)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen{
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char *const *chroot_dirs;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen if (*dir == '\0')
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return FALSE;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen if (*user_set->valid_chroot_dirs == '\0')
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return FALSE;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen while (*chroot_dirs != NULL) {
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen if (**chroot_dirs != '\0' &&
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return TRUE;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen chroot_dirs++;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen }
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return FALSE;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainenstatic int
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainenuser_reply_handle(struct mail_storage_service_ctx *ctx,
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen struct mail_storage_service_user *user,
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const struct auth_user_reply *reply,
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char **error_r)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen{
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char *home = reply->home;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char *chroot = reply->chroot;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen const char *const *str, *line, *p;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen unsigned int i, count;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int ret = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen if (reply->uid != (uid_t)-1) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->uid == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = "userdb returned 0 as uid";
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainen return -1;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen }
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen user->uid_source = "userdb lookup";
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi set_keyval(ctx, user, "mail_uid", dec2str(reply->uid));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (reply->gid != (uid_t)-1) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen user->gid_source = "userdb lookup";
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen set_keyval(ctx, user, "mail_gid", dec2str(reply->gid));
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen }
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen if (home != NULL && chroot == NULL &&
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch *user->user_set->valid_chroot_dirs != '\0' &&
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch (p = strstr(home, "/./")) != NULL) {
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen /* wu-ftpd like <chroot>/./<home> - check only if there's even
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen a possibility of using them (non-empty valid_chroot_dirs) */
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen chroot = t_strdup_until(home, p);
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen home = p + 2;
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen }
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen if (home != NULL)
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen set_keyval(ctx, user, "mail_home", reply->home);
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen if (chroot != NULL) {
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen if (!validate_chroot(user->user_set, chroot)) {
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "userdb returned invalid chroot directory: %s "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "(see valid_chroot_dirs setting)", chroot);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen set_keyval(ctx, user, "mail_chroot", chroot);
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen str = array_get(&reply->extra_fields, &count);
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen for (i = 0; i < count && ret >= 0; i++) {
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen line = str[i];
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainen user->system_groups_user =
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen p_strdup(user->pool, line + 19);
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen } else if (strncmp(line, "nice=", 5) == 0) {
d6b3cfd855c0eebed68be50d3111de1b5a6afeb0Timo Sirainen#ifdef HAVE_SETPRIORITY
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen int n = atoi(line + 5);
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen if (n != 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (setpriority(PRIO_PROCESS, 0, n) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_error("setpriority(%d) failed: %m", n);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
1904e2fc786dbc037039d284b371730777277fc5Aki Tuomi#endif
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen } else T_BEGIN {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = set_line(ctx, user, line);
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen } T_END;
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen if (ret < 0) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen str[i], settings_parser_get_error(user->set_parser));
e6b4168ba670d9e51ea7877661def039ae6b53c3Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainenstatic int
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct mail_storage_service_input *input,
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen pool_t pool, const char **user,
6efdbeab167483597bef087f70ea852d1256a082Timo Sirainen const char *const **fields_r,
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen const char **error_r)
6efdbeab167483597bef087f70ea852d1256a082Timo Sirainen{
6efdbeab167483597bef087f70ea852d1256a082Timo Sirainen struct auth_user_info info;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *new_username;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen memset(&info, 0, sizeof(info));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen info.service = ctx->service->name;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen info.local_ip = input->local_ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen info.remote_ip = input->remote_ip;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen &new_username, fields_r);
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (ret > 0) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (strcmp(*user, new_username) != 0) {
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen if (ctx->debug)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen i_debug("changed username to %s", new_username);
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen *user = t_strdup(new_username);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi *user = new_username;
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi } else if (ret == 0)
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi *error_r = "Unknown user";
754896551f0422cda5d78500b26700eec5343c5bAki Tuomi else if (**fields_r != NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup(**fields_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = -2;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = MAIL_ERRSTR_CRITICAL_MSG;
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen }
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen return ret;
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen}
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r, const char **error_r)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen{
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct passwd pw;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen if (str_to_uid(str, uid_r) == 0)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen return TRUE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen switch (i_getpwnam(str, &pw)) {
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen case -1:
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen *error_r = t_strdup_printf("getpwnam(%s) failed: %m", str);
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen return FALSE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen case 0:
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen *error_r = t_strconcat("Unknown UNIX UID user: ", str, NULL);
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen return FALSE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen default:
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen *uid_r = pw.pw_uid;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen return TRUE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen }
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen}
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r, const char **error_r)
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen{
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen struct group gr;
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen if (str_to_gid(str, gid_r) == 0)
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen return TRUE;
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen switch (i_getgrnam(str, &gr)) {
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen case -1:
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen *error_r = t_strdup_printf("getgrnam(%s) failed: %m", str);
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen return FALSE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen case 0:
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen *error_r = t_strconcat("Unknown UNIX GID group: ", str, NULL);
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen return FALSE;
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen default:
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen *gid_r = gr.gr_gid;
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen return TRUE;
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen }
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen}
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenstatic int
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainenservice_drop_privileges(struct mail_storage_service_user *user,
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen const struct mail_user_settings *set,
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen const char *home, const char *chroot,
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen bool disallow_root, bool keep_setuid_root,
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen bool setenv_only, const char **error_r)
b7b9d4be2a1ff399026a5d6feeffd3a048f22be0Timo Sirainen{
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen struct restrict_access_settings rset;
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen uid_t current_euid, setuid_uid = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *cur_chroot, *error;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen current_euid = geteuid();
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen restrict_access_init(&rset);
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen restrict_access_get_env(&rset);
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (*set->mail_uid != '\0') {
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (!parse_uid(set->mail_uid, &rset.uid, &error)) {
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen *error_r = t_strdup_printf("%s (from %s)", error,
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen user->uid_source);
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen return -1;
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen }
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (rset.uid < (uid_t)set->first_valid_uid ||
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen (set->last_valid_uid != 0 &&
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen rset.uid > (uid_t)set->last_valid_uid)) {
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen *error_r = t_strdup_printf(
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen "Mail access for users with UID %s not permitted "
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen "(see first_valid_uid in config file, uid from %s).",
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen dec2str(rset.uid), user->uid_source);
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen return -1;
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen }
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen rset.uid_source = user->uid_source;
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen } else if (rset.uid == (uid_t)-1 &&
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen disallow_root && current_euid == 0) {
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen *error_r = "User is missing UID (see mail_uid setting)";
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen return -1;
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen }
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen if (*set->mail_gid != '\0') {
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen if (!parse_gid(set->mail_gid, &rset.gid, &error)) {
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen *error_r = t_strdup_printf("%s (from %s)", error,
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen user->gid_source);
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen return -1;
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen }
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen if (rset.gid < (gid_t)set->first_valid_gid ||
9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6Timo Sirainen (set->last_valid_gid != 0 &&
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen rset.gid > (gid_t)set->last_valid_gid)) {
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen *error_r = t_strdup_printf(
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen "Mail access for users with GID %s not permitted "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "(see first_valid_gid in config file, gid from %s).",
e52f55c08f6f1b4fbc5765bf6aa9c7daee0785c3Timo Sirainen dec2str(rset.gid), user->gid_source);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen }
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen rset.gid_source = user->gid_source;
e52f55c08f6f1b4fbc5765bf6aa9c7daee0785c3Timo Sirainen } else if (rset.gid == (gid_t)-1 && disallow_root &&
e52f55c08f6f1b4fbc5765bf6aa9c7daee0785c3Timo Sirainen set->first_valid_gid > 0 && getegid() == 0) {
e52f55c08f6f1b4fbc5765bf6aa9c7daee0785c3Timo Sirainen *error_r = "User is missing GID (see mail_gid setting)";
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen return -1;
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
719abeb2088987f213a33a7dd1fe78958beaef03Timo Sirainen if (*set->mail_privileged_group != '\0') {
719abeb2088987f213a33a7dd1fe78958beaef03Timo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &error)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "%s (in mail_privileged_group setting)", error);
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen return -1;
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (*set->mail_access_groups != '\0') {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen rset.extra_groups = t_strconcat(set->mail_access_groups, ",",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen rset.extra_groups, NULL);
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen rset.first_valid_gid = set->first_valid_gid;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen rset.last_valid_gid = set->last_valid_gid;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen /* we can't chroot if we want to switch between users. there's not
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen much point either (from security point of view) */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen rset.chroot_dir = *chroot == '\0' || keep_setuid_root ? NULL : chroot;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen rset.system_groups_user = user->system_groups_user;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen cur_chroot = restrict_access_get_current_chroot();
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (cur_chroot != NULL) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (rset.chroot_dir == NULL) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen *error_r = "Process is already chrooted, "
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen "can't un-chroot for this user";
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (strcmp(rset.chroot_dir, cur_chroot) != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Process is already chrooted to %s, "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "can't chroot to %s", cur_chroot, chroot);
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen return -1;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen /* chrooting to same directory where we're already chrooted */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen rset.chroot_dir = NULL;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (disallow_root &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = "Mail access not allowed for root";
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen return -1;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (keep_setuid_root) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (current_euid != rset.uid) {
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (current_euid != 0) {
f5e1d3d6b34ec152aa1ff15c7bd3d3552e9227eaTimo Sirainen /* we're changing the UID,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen switch back to root first */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (seteuid(0) < 0)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen i_fatal("seteuid(0) failed: %m");
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen setuid_uid = rset.uid;
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rset.uid = (uid_t)-1;
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen disallow_root = FALSE;
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen if (!setenv_only) {
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen restrict_access(&rset, *home == '\0' ? NULL : home,
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen disallow_root);
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen } else {
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen restrict_access_set_env(&rset);
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen if (setuid_uid != 0 && !setenv_only) {
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen if (seteuid(setuid_uid) < 0)
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(setuid_uid));
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen }
61eec37dd74af9434ff876bc739a4cbe4a0ba8b4Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainenstatic int
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen struct mail_storage_service_user *user,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen const char *home, struct mail_user **mail_user_r,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen const char **error_r)
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen{
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen const struct mail_storage_settings *mail_set;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen struct mail_user *mail_user;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_user = mail_user_alloc(user->input.username, user->user_info,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen user->user_set);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen &user->input.local_ip, &user->input.remote_ip);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen if (mail_set->mail_debug) {
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen i_debug("Effective uid=%s, gid=%s, home=%s",
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen }
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
d9515a2eaa94c8287188c38fc28028727671e729Timo Sirainen /* we don't want to write core files to any users' home
d9515a2eaa94c8287188c38fc28028727671e729Timo Sirainen directories since they could contain information about other
d9515a2eaa94c8287188c38fc28028727671e729Timo Sirainen users' mails as well. so do no chdiring to home. */
d9515a2eaa94c8287188c38fc28028727671e729Timo Sirainen } else if (*home != '\0' &&
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen /* If possible chdir to home directory, so that core file
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen could be written in case we crash. */
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen if (chdir(home) < 0) {
dd645357a6b851a3a9527d16e2bced731e46dcaaMartti Rannanjärvi if (errno == EACCES) {
dd645357a6b851a3a9527d16e2bced731e46dcaaMartti Rannanjärvi i_error("%s", eacces_error_get("chdir",
dd645357a6b851a3a9527d16e2bced731e46dcaaMartti Rannanjärvi t_strconcat(home, "/", NULL)));
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen } if (errno != ENOENT)
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen i_error("chdir(%s) failed: %m", home);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen else if (mail_set->mail_debug)
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen i_debug("Home dir not found: %s", home);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mail_user_init(mail_user, error_r) < 0) {
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen mail_user_unref(&mail_user);
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES) == 0) {
85b4143f07c504294dd4e5b168e9bfb293515c31Josef 'Jeff' Sipek if (mail_namespaces_init(mail_user, error_r) < 0) {
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen mail_user_unref(&mail_user);
6efdbeab167483597bef087f70ea852d1256a082Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen }
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen *mail_user_r = mail_user;
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen return 0;
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen}
6efdbeab167483597bef087f70ea852d1256a082Timo Sirainen
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainenstatic const struct var_expand_table *
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenget_var_expand_table(struct master_service *service,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_storage_service_input *input)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen static struct var_expand_table static_tab[] = {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen { 'u', NULL, "user" },
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen { 'n', NULL, "username" },
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen { 'd', NULL, "domain" },
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen { 's', NULL, "service" },
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen { 'l', NULL, "lip" },
047c00cd3f7f403672f81569413669238df8c15aTimo Sirainen { 'r', NULL, "rip" },
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen { 'p', NULL, "pid" },
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { 'i', NULL, "uid" },
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { '\0', NULL, NULL }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen };
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct var_expand_table *tab;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen tab = t_malloc(sizeof(static_tab));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen tab[0].value = input->username;
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen tab[1].value = t_strcut(input->username, '@');
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen tab[2].value = strchr(input->username, '@');
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (tab[2].value != NULL) tab[2].value++;
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen tab[3].value = service->name;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen tab[4].value = net_ip2addr(&input->local_ip);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen tab[5].value = net_ip2addr(&input->remote_ip);
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen tab[6].value = my_pid;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen tab[7].value = dec2str(geteuid());
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen return tab;
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen}
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainenstatic const char *
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainenuser_expand_varstr(struct master_service *service,
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen struct mail_storage_service_input *input, const char *str)
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen{
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen string_t *ret;
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainen
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen if (*str == SETTING_STRVAR_EXPANDED[0])
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return str + 1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = t_str_new(256);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen var_expand(ret, str + 1, get_var_expand_table(service, input));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return str_c(ret);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void
8d7eb4104707c60ca7e9d0228b37c5133476907bTimo Sirainenmail_storage_service_init_log(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail_storage_service_user *user)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ctx->log_initialized = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen T_BEGIN {
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen string_t *str;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct ioloop_log *log;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen str = t_str_new(256);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen var_expand(str, user->user_set->mail_log_prefix,
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen get_var_expand_table(ctx->service, &user->input));
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen master_service_init_log(ctx->service, str_c(str));
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen log = io_loop_log_new(current_ioloop);
5512d420d826a2f9d4e7cb4e4919e1864fe688b0Timo Sirainen io_loop_log_set_prefix(log, str_c(str));
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen io_loop_log_unref(&log);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen } T_END;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void mail_storage_service_time_moved(time_t old_time, time_t new_time)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen long diff = new_time - old_time;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cbcba924a745c938260fd39cb284175b75f8eaf2Timo Sirainen if (diff > 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (diff > MAX_NOWARN_FORWARD_SECS)
4cbe2b4ee234317331eadd1768d9ce433adb60e1Timo Sirainen i_warning("Time jumped forwards %ld seconds", diff);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
8b5c520883aa37bb55646286d375fdbae294d710Timo Sirainen diff = -diff;
8b5c520883aa37bb55646286d375fdbae294d710Timo Sirainen
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen if (diff > MAX_TIME_BACKWARDS_SLEEP) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_fatal("Time just moved backwards by %ld seconds. "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "This might cause a lot of problems, "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "so I'll just kill myself now. "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "http://wiki2.dovecot.org/TimeMovedBackwards", diff);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen } else {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("Time just moved backwards by %ld seconds. "
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen "I'll sleep now until we're back in present. "
0679f8a70a8dda43b204ae35fc6a903818cc6584Timo Sirainen "http://wiki2.dovecot.org/TimeMovedBackwards", diff);
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainen /* Sleep extra second to make sure usecs also grows. */
3c5ee51327f075dc13cdacf46135f7f0abbdaafeTimo Sirainen diff++;
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainen
28bf8f762fcd21c57bf71822cf818447babce9a0Timo Sirainen while (diff > 0 && sleep(diff) != 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* don't use sleep()'s return value, because
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen it could get us to a long loop in case
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen interrupts just keep coming */
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen diff = old_time - time(NULL) + 1;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen }
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen }
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen}
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainenstruct mail_storage_service_ctx *
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainenmail_storage_service_init(struct master_service *service,
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen const struct setting_parser_info *set_roots[],
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen enum mail_storage_service_flags flags)
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen{
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen struct mail_storage_service_ctx *ctx;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen pool_t pool;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen unsigned int count;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen (void)umask(0077);
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen io_loop_set_time_moved_callback(current_ioloop,
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen mail_storage_service_time_moved);
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen mail_storage_init();
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen mail_storage_register_all();
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen mailbox_list_register_all();
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen pool = pool_alloconly_create("mail storage service", 2048);
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen ctx = p_new(pool, struct mail_storage_service_ctx, 1);
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen ctx->pool = pool;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen ctx->service = service;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen ctx->flags = flags;
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen /* @UNSAFE */
8a0a8c982a6ffc75a4b1c8717b6180a811655794Timo Sirainen if (set_roots == NULL)
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen count = 0;
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen else
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen for (count = 0; set_roots[count] != NULL; count++) ;
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen ctx->set_roots =
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen p_new(pool, const struct setting_parser_info *, count + 2);
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen ctx->set_roots[0] = &mail_user_setting_parser_info;
c6dfc77cb24ba1bb72437896080d3177b653e2afTimo Sirainen if (set_roots != NULL) {
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen memcpy(ctx->set_roots + 1, set_roots,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sizeof(*ctx->set_roots) * count);
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen }
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen /* do all the global initialization. delay initializing plugins until
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen we drop privileges the first time. */
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0) {
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen /* note: we may not have read any settings yet, so this logging
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen may still be going to wrong location */
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen const char *log_prefix = t_strconcat(service->name, ": ", NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen master_service_init_log(service, log_prefix);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen io_loop_set_default_log_prefix(current_ioloop, log_prefix);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dict_drivers_register_builtin();
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen return ctx;
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstruct auth_master_connection *
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_storage_service_get_auth_conn(struct mail_storage_service_ctx *ctx)
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen{
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen i_assert(ctx->conn != NULL);
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen return ctx->conn;
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainenstatic enum mail_storage_service_flags
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_storage_service_input_get_flags(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct mail_storage_service_input *input)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen enum mail_storage_service_flags flags;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen flags = (ctx->flags & ~input->flags_override_remove) |
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen input->flags_override_add;
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen if (input->no_userdb_lookup) {
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen /* FIXME: for API backwards compatibility only */
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen flags &= ~MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen }
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen return flags;
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen}
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainenint mail_storage_service_read_settings(struct mail_storage_service_ctx *ctx,
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen const struct mail_storage_service_input *input,
d4845c4245638fd6f02dc0cb92c3465fae763cbbTimo Sirainen pool_t pool,
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen const struct setting_parser_info **user_info_r,
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen const struct setting_parser_context **parser_r,
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen const char **error_r)
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen{
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen struct master_service_settings_input set_input;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct setting_parser_info *const *roots;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct master_service_settings_output set_output;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct dynamic_settings_parser *dyn_parsers;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen enum mail_storage_service_flags flags;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int i;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen flags = mail_storage_service_input_get_flags(ctx, input);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen memset(&set_input, 0, sizeof(set_input));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.roots = ctx->set_roots;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.preserve_user = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* settings reader may exec doveconf, which is going to clear
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen environment, and if we're not doing a userdb lookup we want to
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen use $HOME */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.preserve_home =
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.use_sysexits =
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (flags & MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS) != 0;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (input != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.module = input->module;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.service = input->service;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.username = input->username;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.local_ip = input->local_ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen set_input.remote_ip = input->remote_ip;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen if (ctx->set_cache == NULL) {
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen ctx->set_cache_module = p_strdup(ctx->pool, set_input.module);
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen ctx->set_cache_service = p_strdup(ctx->pool, set_input.service);
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen ctx->set_cache = master_service_settings_cache_init(
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen ctx->service, set_input.module, set_input.service);
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen } else {
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen /* already looked up settings at least once.
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen we really shouldn't be execing anymore. */
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen set_input.never_exec = TRUE;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen }
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen dyn_parsers = mail_storage_get_dynamic_parsers(pool);
7f1b897201d80c83c96b0d663f2a14c517d48f14Timo Sirainen if (null_strcmp(set_input.module, ctx->set_cache_module) == 0 &&
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen null_strcmp(set_input.service, ctx->set_cache_service) == 0) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (master_service_settings_cache_read(ctx->set_cache,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen &set_input, dyn_parsers,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen parser_r, error_r) < 0) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen *error_r = t_strdup_printf(
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen "Error reading configuration: %s", *error_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen settings_parser_dyn_update(pool, &set_input.roots, dyn_parsers);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (master_service_settings_read(ctx->service, &set_input,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen &set_output, error_r) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "Error reading configuration: %s", *error_r);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen *parser_r = ctx->service->set_parser;
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen }
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen roots = settings_parser_get_roots(*parser_r);
b2d562f9c7fd13f9a16e9b3bcee904630b80b1feTimo Sirainen for (i = 0; roots[i] != NULL; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (strcmp(roots[i]->module_name,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_user_setting_parser_info.module_name) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *user_info_r = roots[i];
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_unreached();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return -1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmail_storage_service_first_init(struct mail_storage_service_ctx *ctx,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct setting_parser_info *user_info,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen const struct mail_user_settings *user_set)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen{
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen enum auth_master_flags flags = 0;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen i_assert(ctx->conn == NULL);
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen ctx->debug = mail_user_set_get_mail_debug(user_info, user_set);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (ctx->debug)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen flags |= AUTH_MASTER_FLAG_DEBUG;
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT) != 0)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen flags |= AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen ctx->conn = auth_master_init(user_set->auth_socket_path, flags);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen i_assert(mail_user_auth_master_conn == NULL);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen mail_user_auth_master_conn = ctx->conn;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen}
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainenstatic void
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainenmail_storage_service_load_modules(struct mail_storage_service_ctx *ctx,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen const struct setting_parser_info *user_info,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen const struct mail_user_settings *user_set)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen{
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen struct module_dir_load_settings mod_set;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen if (*user_set->mail_plugins == '\0')
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen return;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS) != 0)
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen return;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen memset(&mod_set, 0, sizeof(mod_set));
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen mod_set.version = master_service_get_version_string(ctx->service);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen mod_set.binary_name = master_service_get_name(ctx->service);
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen mod_set.setting_name = "mail_plugins";
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainen mod_set.require_init_funcs = TRUE;
57397188558fcd1a9e24dbbbd2952eac9c45c20dTimo Sirainen mod_set.debug = mail_user_set_get_mail_debug(user_info, user_set);
57397188558fcd1a9e24dbbbd2952eac9c45c20dTimo Sirainen
03baa1c4c51f7b08fb285e82b528fcb00ac09ebfTimo Sirainen mail_storage_service_modules =
03baa1c4c51f7b08fb285e82b528fcb00ac09ebfTimo Sirainen module_dir_load_missing(mail_storage_service_modules,
57397188558fcd1a9e24dbbbd2952eac9c45c20dTimo Sirainen user_set->mail_plugin_dir,
57397188558fcd1a9e24dbbbd2952eac9c45c20dTimo Sirainen user_set->mail_plugins, &mod_set);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen}
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainenint mail_storage_service_lookup(struct mail_storage_service_ctx *ctx,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen const struct mail_storage_service_input *input,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen struct mail_storage_service_user **user_r,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen const char **error_r)
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen{
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen enum mail_storage_service_flags flags;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen struct mail_storage_service_user *user;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen const char *username = input->username;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen const struct setting_parser_info *user_info;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen const struct mail_user_settings *user_set;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen const char *const *userdb_fields, *error;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen struct auth_user_reply reply;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen const struct setting_parser_context *set_parser;
1bea4b9c24fbe2b457950c09cf072292a6701cffTimo Sirainen pool_t user_pool, temp_pool;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen int ret = 1;
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen user_pool = pool_alloconly_create("mail storage service user", 1024*5);
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen if (mail_storage_service_read_settings(ctx, input, user_pool,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen &user_info, &set_parser,
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen &error) < 0) {
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen i_error("user %s: %s", username, error);
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen pool_unref(&user_pool);
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen *error_r = MAIL_ERRSTR_CRITICAL_MSG;
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen return -1;
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen }
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen flags = mail_storage_service_input_get_flags(ctx, input);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0 &&
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen !ctx->log_initialized) {
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen /* initialize logging again, in case we only read the
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen settings for the first above */
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen ctx->log_initialized = TRUE;
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen master_service_init_log(ctx->service,
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen t_strconcat(ctx->service->name, ": ", NULL));
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen }
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user_set = settings_parser_get_list(set_parser)[1];
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen if (ctx->conn == NULL)
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen /* load global plugins */
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen mail_storage_service_load_modules(ctx, user_info, user_set);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen temp_pool = pool_alloconly_create("userdb lookup", 2048);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen ret = service_auth_userdb_lookup(ctx, input, temp_pool,
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen &username, &userdb_fields,
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen error_r);
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen if (ret <= 0) {
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen pool_unref(&temp_pool);
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen pool_unref(&user_pool);
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen return ret;
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen }
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen } else {
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen userdb_fields = input->userdb_fields;
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen }
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user = p_new(user_pool, struct mail_storage_service_user, 1);
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen memset(user_r, 0, sizeof(user_r));
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user->pool = user_pool;
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user->input = *input;
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user->input.userdb_fields = NULL;
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user->input.username = p_strdup(user_pool, username);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user->user_info = user_info;
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user->flags = flags;
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen user->set_parser = settings_parser_dup(set_parser, user_pool);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen if (!settings_parser_check(user->set_parser, user_pool, &error))
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen i_panic("settings_parser_check() failed: %s", error);
d2c41d6587f973d3b215e035288a07619bc22c2aTimo Sirainen
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user->user_set = settings_parser_get_list(user->set_parser)[1];
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user->gid_source = "mail_gid setting";
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen user->uid_source = "mail_uid setting";
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_DEBUG) != 0)
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen (void)settings_parse_line(user->set_parser, "mail_debug=yes");
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen if ((flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) == 0) {
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen const char *home = getenv("HOME");
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen if (home != NULL)
8ab32a83ca0ead65c5670f337ca3a4d7a0fd0ed1Timo Sirainen set_keyval(ctx, user, "mail_home", home);
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen }
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen if (userdb_fields != NULL) {
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen auth_user_fields_parse(userdb_fields, temp_pool, &reply);
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen if (user_reply_handle(ctx, user, &reply, &error) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("user %s: Invalid settings in userdb: %s",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen username, error);
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen *error_r = ERRSTR_INVALID_USER_SETTINGS;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen ret = -2;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen pool_unref(&temp_pool);
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen /* load per-user plugins */
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen if (ret > 0) {
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen mail_storage_service_load_modules(ctx, user_info,
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen user->user_set);
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen }
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *user_r = user;
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen return ret;
885e1b36da370a674c0fd3b85db53740d7dcbd9bTimo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenint mail_storage_service_next(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen struct mail_storage_service_user *user,
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen struct mail_user **mail_user_r)
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen{
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen const struct mail_user_settings *user_set = user->user_set;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen const char *home, *chroot, *error;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen unsigned int len;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen bool disallow_root =
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0;
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen bool temp_priv_drop =
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen
c668292359474a4aa8c608b30a858337fa3fc813Timo Sirainen /* variable strings are expanded in mail_user_init(),
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen but we need the home and chroot sooner so do them separately here. */
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen home = user_expand_varstr(ctx->service, &user->input,
de70a6f77fc3b350eeee4e2a0d29dd07ddde431bTimo Sirainen user_set->mail_home);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen user_set->mail_chroot);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (*home != '/' && *home != '\0') {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_error("user %s: "
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen "Relative home directory paths not supported: %s",
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek user->input.username, home);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return -2;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen len = strlen(chroot);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen strncmp(home, chroot, len - 2) == 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* mail_chroot = /chroot/. means that the home dir already
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen contains the chroot dir. remove it from home. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (!temp_priv_drop) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen home += len - 2;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (*home == '\0')
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen home = "/";
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen chroot = t_strndup(chroot, len - 2);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen set_keyval(ctx, user, "mail_home", home);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen set_keyval(ctx, user, "mail_chroot", chroot);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen } else if (len > 0 && temp_priv_drop) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* we're dropping privileges only temporarily, so we can't
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen chroot. fix home directory so we can access it. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (*home == '\0' || strcmp(home, "/") == 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen home = chroot;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen else
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen home = t_strconcat(chroot, home, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen chroot = "";
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen set_keyval(ctx, user, "mail_home", home);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen mail_storage_service_init_log(ctx, user);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (service_drop_privileges(user, user_set, home, chroot,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen disallow_root, temp_priv_drop,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen FALSE, &error) < 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_error("user %s: Couldn't drop privileges: %s",
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen user->input.username, error);
6a6e3c2538a08cc4880a8db7e0a9a3392122ea04Timo Sirainen return -1;
a943ed0f901e312445fd393249b91932797bba79Josef 'Jeff' Sipek }
6a6e3c2538a08cc4880a8db7e0a9a3392122ea04Timo Sirainen if (!temp_priv_drop ||
6a6e3c2538a08cc4880a8db7e0a9a3392122ea04Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) != 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen restrict_access_allow_coredumps(TRUE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen /* privileges are dropped. initialize plugins that haven't been
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen initialized yet. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen module_dir_init(mail_storage_service_modules);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen if (mail_storage_service_init_post(ctx, user, home,
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen mail_user_r, &error) < 0) {
442232f2d1cfdf28f3a18aa00a5c19246d321036Timo Sirainen i_error("user %s: Initialization failed: %s",
5a6343181a5183b1ae1c39d40fc5a1deb3b840d9Timo Sirainen user->input.username, error);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return -2;
6a6e3c2538a08cc4880a8db7e0a9a3392122ea04Timo Sirainen }
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek return 0;
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek}
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipekvoid mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipek struct mail_storage_service_user *user)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen{
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const struct mail_user_settings *user_set = user->user_set;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *home, *chroot, *error;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen home = user_expand_varstr(ctx->service, &user->input,
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen user_set->mail_home);
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen chroot = user_expand_varstr(ctx->service, &user->input,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen user_set->mail_chroot);
41789540204ce091b2c06629d9a31788082e5da8Timo Sirainen
41789540204ce091b2c06629d9a31788082e5da8Timo Sirainen if (service_drop_privileges(user, user_set, home, chroot,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen FALSE, FALSE, TRUE,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen &error) < 0)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen i_fatal("%s", error);
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
6ed1e82824590b514201d9db84ba96bdfc832dd5Timo Sirainen
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainenint mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct mail_storage_service_input *input,
96d19229e5f322411eb84446e5477d8170cfa5afTimo Sirainen struct mail_storage_service_user **user_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_user **mail_user_r,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char **error_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_storage_service_user *user;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen int ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = mail_storage_service_lookup(ctx, input, &user, error_r);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (ret <= 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return ret;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen ret = mail_storage_service_next(ctx, user, mail_user_r);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (ret < 0) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen mail_storage_service_user_free(&user);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen *error_r = ret == -2 ? ERRSTR_INVALID_USER_SETTINGS :
a7bf18c0a462e4069675dec5038c474f8eb0a60dTimo Sirainen MAIL_ERRSTR_CRITICAL_MSG;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen return ret;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen *user_r = user;
442232f2d1cfdf28f3a18aa00a5c19246d321036Timo Sirainen return 1;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen}
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid mail_storage_service_user_free(struct mail_storage_service_user **_user)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch struct mail_storage_service_user *user = *_user;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *_user = NULL;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen settings_parser_deinit(&user->set_parser);
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen pool_unref(&user->pool);
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen}
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid mail_storage_service_init_settings(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct mail_storage_service_input *input)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen const struct setting_parser_info *user_info;
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen const struct mail_user_settings *user_set;
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen const struct setting_parser_context *set_parser;
56ba5a9b62e3ce527e898a8fe3b1a015ab30ed54Timo Sirainen const char *error;
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen pool_t temp_pool;
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen if (ctx->conn != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return;
5ff22d69989a3ccc2d947164e47996f720d493d8Timo Sirainen
5ff22d69989a3ccc2d947164e47996f720d493d8Timo Sirainen temp_pool = pool_alloconly_create("service all settings", 4096);
5ff22d69989a3ccc2d947164e47996f720d493d8Timo Sirainen if (mail_storage_service_read_settings(ctx, input, temp_pool,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &user_info, &set_parser,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen &error) < 0)
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen i_fatal("%s", error);
835ba470fb6a73b74e258e12678236106d0df09eTimo Sirainen user_set = settings_parser_get_list(set_parser)[1];
89237470342ea6d4bbdf4cff9764037cfb3f6f45Timo Sirainen
e3540e734a79fd4f971652925079c2e26a4b5524Timo Sirainen mail_storage_service_first_init(ctx, user_info, user_set);
89237470342ea6d4bbdf4cff9764037cfb3f6f45Timo Sirainen pool_unref(&temp_pool);
89237470342ea6d4bbdf4cff9764037cfb3f6f45Timo Sirainen}
89237470342ea6d4bbdf4cff9764037cfb3f6f45Timo Sirainen
89237470342ea6d4bbdf4cff9764037cfb3f6f45Timo Sirainenunsigned int
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmail_storage_service_all_init(struct mail_storage_service_ctx *ctx)
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen{
13f4d4d4a69d7dff2f71363d189d048abb04b6c6Timo Sirainen if (ctx->auth_list != NULL)
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch (void)auth_master_user_list_deinit(&ctx->auth_list);
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch mail_storage_service_init_settings(ctx, NULL);
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch ctx->auth_list = auth_master_user_list_init(ctx->conn);
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch return auth_master_user_list_count(ctx->auth_list);
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch}
72f21884c0bb9bb26edad63623427ac2120901eaStephan Bosch
e4eb49e29197c6783ec93b868100394e189f4e0cTimo Sirainenint mail_storage_service_all_next(struct mail_storage_service_ctx *ctx,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char **username_r)
21e6b4fd844fd074583b17f09e1f27b9835ee238Timo Sirainen{
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen i_assert((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0);
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen *username_r = auth_master_user_list_next(ctx->auth_list);
8761992b5aa05862e7ec3a460cdc17af41a4a0f5Timo Sirainen if (*username_r != NULL)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return 1;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return auth_master_user_list_deinit(&ctx->auth_list);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen}
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainenvoid mail_storage_service_deinit(struct mail_storage_service_ctx **_ctx)
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen{
baca06331782e2752734199486e51a26d7c93d75Timo Sirainen struct mail_storage_service_ctx *ctx = *_ctx;
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen *_ctx = NULL;
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen if (ctx->auth_list != NULL)
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen (void)auth_master_user_list_deinit(&ctx->auth_list);
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen if (ctx->conn != NULL) {
04a6e51325d52a8f6046389406b2f606159a61e3Timo Sirainen if (mail_user_auth_master_conn == ctx->conn)
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen mail_user_auth_master_conn = NULL;
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen auth_master_deinit(&ctx->conn);
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen }
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen if (ctx->set_cache != NULL)
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen master_service_settings_cache_deinit(&ctx->set_cache);
2ac0a22865272cb4311a1bd09eb69b475625b3ebTimo Sirainen pool_unref(&ctx->pool);
442232f2d1cfdf28f3a18aa00a5c19246d321036Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen module_dir_unload(&mail_storage_service_modules);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_storage_deinit();
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen dict_drivers_unregister_builtin();
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
5f1d689131a75c39f064cbd4202373e7edf78f18Josef 'Jeff' Sipek
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid **mail_storage_service_user_get_set(struct mail_storage_service_user *user)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen{
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return settings_parser_get_list(user->set_parser) + 1;
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen}
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenconst struct mail_storage_service_input *
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenmail_storage_service_user_get_input(struct mail_storage_service_user *user)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen{
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen return &user->input;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenstruct setting_parser_context *
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenmail_storage_service_user_get_settings_parser(struct mail_storage_service_user *user)
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen{
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen return user->set_parser;
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen}
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainenvoid *mail_storage_service_get_settings(struct master_service *service)
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen{
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen void **sets, *set;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen T_BEGIN {
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen sets = master_service_settings_get_others(service);
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen set = sets[1];
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen } T_END;
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen return set;
71056e0f5e1f68cb9ac002a7827eb98435c40d62Timo Sirainen}
bd20ef9d5c639faf470912ab94e6e6627d3eaebaTimo Sirainen