mail-storage-service.c revision 073353fe5b7ddbc44fd2b099e023b84254041083
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2009-2017 Dovecot authors, see the included COPYING file */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen/* If time moves backwards more than this, kill ourself instead of sleeping. */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen "Invalid user settings. Refer to server log for more information."
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct auth_master_connection *conn, *iter_conn;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char *set_cache_module, *set_cache_service;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen struct master_service_settings_cache *set_cache;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *const **userdb_next_fieldsp;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *log_prefix, *auth_token, *auth_user;
eacce2276278ce6a8176a9a100807dba50bbfb36Timo Sirainen const char *system_groups_user, *uid_source, *gid_source;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstruct module *mail_storage_service_modules = NULL;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenmail_storage_service_var_expand(struct mail_storage_service_ctx *ctx,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_storage_service_input *input,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_storage_service_privileges *priv,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char **error_r);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenmail_user_set_get_mail_debug(const struct setting_parser_info *user_info,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_set = mail_user_set_get_driver_settings(user_info, user_set,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic void set_keyval(struct mail_storage_service_ctx *ctx,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* this setting was already overridden with -o parameter */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (mail_user_set_get_mail_debug(user->user_info,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (settings_parse_keyvalue(set_parser, key, value) < 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_fatal("Invalid userdb input %s=%s: %s", key, value,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic int set_line(struct mail_storage_service_ctx *ctx,
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen struct setting_parser_context *set_parser = user->set_parser;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *key, *orig_key, *append_value = NULL;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_debug = mail_user_set_get_mail_debug(user->user_info,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* key+=value */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (!settings_parse_is_valid_key(set_parser, key)) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* assume it's a plugin setting */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (master_service_set_has_config_override(ctx->service, key)) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* this setting was already overridden with -o parameter */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_debug("Ignoring overridden (-o) userdb setting: %s",
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen value = settings_parse_get_value(set_parser, key, &type);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen "'+' can only be used for strings.", orig_key);
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen /* possibly a password field (e.g. imapc_password).
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen hide the value. */
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen "Unknown userdb setting: %s" :
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainenstatic bool validate_chroot(const struct mail_user_settings *user_set,
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen const char *dir)
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen const char *const *chroot_dirs;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen chroot_dirs = t_strsplit(user_set->valid_chroot_dirs, ":");
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomiuser_reply_handle(struct mail_storage_service_ctx *ctx,
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen const char **error_r)
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen unsigned int i, count;
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen set_keyval(ctx, user, "mail_uid", dec2str(reply->uid));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen set_keyval(ctx, user, "mail_gid", dec2str(reply->gid));
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* wu-ftpd like <chroot>/./<home> - check only if there's even
c7f6992db44e9cd33b3b0d754833a1503ee9a53fAki Tuomi a possibility of using them (non-empty valid_chroot_dirs) */
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen if (!validate_chroot(user->user_set, chroot)) {
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen "userdb returned invalid chroot directory: %s "
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str = array_get(&reply->extra_fields, &count);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen for (i = 0; i < count; i++) {
45c872f65e4f327ef166c6e2b71bb43e188ac562Timo Sirainen if (strncmp(line, "system_groups_user=", 19) == 0) {
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen i_error("userdb returned invalid nice value %s",
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if (n != 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if (strncmp(line, "auth_token=", 11) == 0) {
44f93baa7b8dca7d00bf187cd3db1c15eed384d2Timo Sirainen user->auth_token = p_strdup(user->pool, line+11);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if (strncmp(line, "auth_user=", 10) == 0) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen user->auth_user = p_strdup(user->pool, line+10);
0b2f7be9fadfd4026a9174e51170890cde3edf48Timo Sirainen user->admin = line[6] == 'y' || line[6] == 'Y' ||
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *error_r = t_strdup_printf("Invalid userdb input '%s': %s",
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str[i], settings_parser_get_error(user->set_parser));
ec5fec7eab19e134a2607b7e224b3e14a1771ee0Timo Sirainenservice_auth_userdb_lookup(struct mail_storage_service_ctx *ctx,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_storage_service_input *input,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *const **fields_r,
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen const char **error_r)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen info.service = input->service != NULL ? input->service :
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = auth_master_user_lookup(ctx->conn, *user, &info, pool,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_debug("changed username to %s", new_username);
04870054863757edf048c81dcce3c5e7dec453cdTimo Sirainen } else if (ret == 0)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool parse_uid(const char *str, uid_t *uid_r, const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *error_r = t_strdup_printf("getpwnam(%s) failed: %m", str);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *error_r = t_strconcat("Unknown UNIX UID user: ", str, NULL);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenstatic bool parse_gid(const char *str, gid_t *gid_r, const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *error_r = t_strdup_printf("getgrnam(%s) failed: %m", str);
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen *error_r = t_strconcat("Unknown UNIX GID group: ", str, NULL);
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainenstatic const struct var_expand_table *
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainenget_var_expand_table(struct master_service *service,
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen const struct mail_storage_service_input *input,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_storage_service_privileges *priv)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *username = t_strcut(input->username, '@');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *domain = i_strchr_to_next(input->username, '@');
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char *auth_user, *auth_username, *auth_domain;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (user == NULL || user->auth_user == NULL) {
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen auth_username = t_strcut(user->auth_user, '@');
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen auth_domain = i_strchr_to_next(user->auth_user, '@');
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen { 'l', net_ip2addr(&input->local_ip), "lip" },
e5b723864630e40c9028808ef417dd3d6fbf495bTimo Sirainen { 'r', net_ip2addr(&input->remote_ip), "rip" },
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenmail_storage_service_get_var_expand_table(struct mail_storage_service_ctx *ctx,
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen return get_var_expand_table(ctx->service, NULL, input, &priv);
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainenuser_expand_varstr(struct mail_storage_service_ctx *ctx,
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen const char *str, const char **value_r, const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen ret = mail_storage_service_var_expand(ctx, value, str + 1, user,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenservice_parse_privileges(struct mail_storage_service_ctx *ctx,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen struct mail_storage_service_privileges *priv_r,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_user_settings *set = user->user_set;
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (!parse_uid(set->mail_uid, &uid, error_r)) {
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen *error_r = t_strdup_printf("%s (from %s)", *error_r,
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "Mail access for users with UID %s not permitted "
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "(see first_valid_uid in config file, uid from %s).",
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen if (!parse_gid(set->mail_gid, &gid, error_r)) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen *error_r = t_strdup_printf("%s (from %s)", *error_r,
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "Mail access for users with GID %s not permitted "
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "(see first_valid_gid in config file, gid from %s).",
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen /* variable strings are expanded in mail_user_init(),
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen but we need the home and chroot sooner so do them separately here. */
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (!user_expand_varstr(ctx, user, priv_r, user->user_set->mail_home,
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "Failed to expand mail_home '%s': %s",
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen if (!user_expand_varstr(ctx, user, priv_r, user->user_set->mail_chroot,
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen "Failed to expand mail_chroot '%s': %s",
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenstatic void mail_storage_service_seteuid_root(void)
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen if (seteuid(0) < 0) {
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen "Failed to restore temporarily dropped root privileges: "
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainen "seteuid(0) failed: %m");
eb4d4f557fa75aa2a47639e9deb75a21f44eb42aTimo Sirainenservice_drop_privileges(struct mail_storage_service_user *user,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const struct mail_user_settings *set = user->user_set;
04a7b696e5255aa956277a0f7cabee736c69ec96Timo Sirainen *error_r = "User is missing UID (see mail_uid setting)";
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if (rset.gid == (gid_t)-1 && disallow_root &&
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen *error_r = "User is missing GID (see mail_gid setting)";
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen "%s (in mail_privileged_group setting)", error);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen rset.extra_groups = t_strconcat(set->mail_access_groups, ",",
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen rset.chroot_dir = *priv->chroot == '\0' ? NULL : priv->chroot;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen rset.system_groups_user = user->system_groups_user;
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen cur_chroot = restrict_access_get_current_chroot();
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen /* we're already chrooted. make sure the chroots are equal. */
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen "can't un-chroot for this user";
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen if (strcmp(rset.chroot_dir, cur_chroot) != 0) {
c3d40f3092af25cad9e807a85eaad4d92aab107bTimo Sirainen "Process is already chrooted to %s, "
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "can't chroot to %s", cur_chroot, priv->chroot);
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen /* chrooting to same directory where we're already chrooted */
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
4530cfa7456c10cd03fe9120c75f8bcb2f623ba4Timo Sirainen *error_r = "Mail access not allowed for root";
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if (current_euid != rset.uid && rset.uid != (uid_t)-1) {
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen /* we're changing the UID,
bd4de9c8152e6ea032c1cb1df8b79635ff5ddf9eTimo Sirainen switch back to root first */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen restrict_access(&rset, *priv->home == '\0' ? NULL : priv->home,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen i_fatal("mail-storage-service: seteuid(%s) failed: %m",
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainenmail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen const char **error_r)
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* NOTE: if more user initialization is added, add it also to
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user_dup() */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user = mail_user_alloc_nodup_set(user->input.username,
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mail_user_set_vars(mail_user, ctx->service->name,
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen &user->input.local_ip, &user->input.remote_ip);
714e2da5096fb52b8845d3c79f9bb26225a606c9Timo Sirainen mail_user->uid = priv->uid == (uid_t)-1 ? geteuid() : priv->uid;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user->gid = priv->gid == (gid_t)-1 ? getegid() : priv->gid;
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen p_strdup(mail_user->pool, user->input.session_id);
6882df5fbca4a09cdaa95f54d70bb31b5920528cTimo Sirainen mail_user->userdb_fields = user->input.userdb_fields == NULL ? NULL :
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen p_strarray_dup(mail_user->pool, user->input.userdb_fields);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_AUTOEXPUNGE) != 0;
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainen mail_set = mail_user_set_get_storage_set(mail_user);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen str_printfa(str, "Effective uid=%s, gid=%s, home=%s",
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen dec2str(geteuid()), dec2str(getegid()), home);
cd2cd224d3216a243d55c71c298a5b7684de0ac4Timo Sirainen str_printfa(str, ", chroot=%s", priv->chroot);
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen (user->flags & MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS) == 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* we don't want to write core files to any users' home
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen directories since they could contain information about other
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen users' mails as well. so do no chdiring to home. */
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen } else if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR) == 0) {
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen /* If possible chdir to home directory, so that core file
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen could be written in case we crash.
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen fallback to chdir()ing to root directory. this is needed
02a54da28f376dd66d7939d8546a196a0045b486Timo Sirainen because the current directory may not be accessible after
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainen dropping privileges, and for example unlink_directory()
23fdad6c7e2581921f511e24cd9371c9eaebcef9Timo Sirainen requires ability to open the current directory. */
if (p == NULL)
const char *const *fields)
const char **value_r,
const char **error_r)
const char *error;
T_BEGIN {
} T_END;
user);
if (diff > 0) {
diff++;
struct mail_storage_service_ctx *
const char *version;
unsigned int count;
getuid() != 0) {
count = 0;
return ctx;
struct auth_master_connection *
static enum mail_storage_service_flags
return flags;
const char **error_r)
i_unreached();
const char **error_r)
const char *error;
bool update_log_prefix,
const char **error_r)
void **sets;
geteuid() != 0) {
error_r) < 0) {
if (update_log_prefix)
if (ret <= 0) {
return ret;
if (ret > 0) {
error_r) < 0) {
return ret;
const char **error_r)
bool update_log_prefix;
int ret;
const char *session_id =
return ret;
const char **error_r)
const char *error;
bool disallow_root =
bool temp_priv_drop =
bool use_chroot;
if (use_chroot) {
if (!temp_priv_drop ||
const char **error_r)
int ret;
return ret;
const char *error;
const char **error_r)
int ret;
if (ret <= 0)
return ret;
if (ret < 0) {
return ret;
const char *error;
void **sets;
&error) < 0)
int ret = 0;
return ret;
const char *user_mask_hint)
flags);
const char **username_r)
const struct mail_storage_settings *
const struct mail_storage_service_input *
struct setting_parser_context *
struct mail_storage_service_ctx *
T_BEGIN {
} T_END;
return set;