mail-process.c revision 76b43e4417bab52e913da39b5f5bc2a130d3f149
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen/* Timeout chdir() completely after this many seconds */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen/* Give a warning about chdir() taking a while if it took longer than this
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen many seconds to finish. */
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen /* process.type + user + remote_ip identifies this process group */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* processes array acts also as refcount */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen/* type+user -> struct mail_process_group */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic unsigned int mail_process_count = 0;
9eef11df882f9c14d164f42cb438f32fe724041cTimo Sirainenstatic unsigned int mail_process_group_hash(const void *p)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen return str_hash(group->user) ^ group->process.type ^
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic int mail_process_group_cmp(const void *p1, const void *p2)
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen const struct mail_process_group *group1 = p1, *group2 = p2;
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen ret = group1->process.type - group2->process.type;
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen if (ret == 0 && !net_ip_compare(&group1->remote_ip, &group2->remote_ip))
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenmail_process_group_lookup(enum process_type type, const char *user,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return hash_lookup(mail_process_groups, &lookup_group);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenmail_process_group_create(enum process_type type, const char *user,
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen hash_insert(mail_process_groups, group, group);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenmail_process_group_add(struct mail_process_group *group, pid_t pid)
ce0e25f26d6e67480ee39b5ca0ad634fa60c4605Timo Sirainenstatic void mail_process_group_free(struct mail_process_group *group)
471a6b2b4e64eca5d5779ae20a477312b32c89eeTimo Sirainenstatic bool validate_uid_gid(struct settings *set, uid_t uid, gid_t gid,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("user %s: Logins with UID 0 not permitted", user);
2faaca21fb49df0f1da859090246866b111cee1eTimo Sirainen if (set->login_uid == uid && master_uid != uid) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("user %s: Logins with login_user's UID %s "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "not permitted (see http://wiki.dovecot.org/UserIds).",
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen (set->last_valid_uid != 0 && uid > (uid_t)set->last_valid_uid)) {
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen i_error("user %s: Logins with UID %s not permitted "
cd8a262bdd0b55a3bf53d9aa54fc3008a61d7f8dTimo Sirainen "(see first_valid_uid in config file).",
31d32d39dd09be0625a6d92ee715155f5d679515Timo Sirainen (set->last_valid_gid != 0 && gid > (gid_t)set->last_valid_gid)) {
31d32d39dd09be0625a6d92ee715155f5d679515Timo Sirainen i_error("user %s: Logins for users with primary group ID %s "
31d32d39dd09be0625a6d92ee715155f5d679515Timo Sirainen "not permitted (see first_valid_gid in config file).",
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainenstatic bool validate_chroot(struct settings *set, const char *dir)
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen const char *const *chroot_dirs;
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen chroot_dirs = t_strsplit(set->valid_chroot_dirs, ":");
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic const struct var_expand_table *
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen static struct var_expand_table static_tab[] = {
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen tab[1].value = user == NULL ? NULL : t_strcut(user, '@');
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen tab[2].value = user == NULL ? NULL : strchr(user, '@');
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen "/HOME_DIRECTORY_USED_BUT_NOT_GIVEN_BY_USERDB";
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic const char *
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainenexpand_mail_env(const char *env, const struct var_expand_table *table)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const char *p;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* it's either type:data or just data */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen while (env != p) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen (env[1] == '/' || env[1] == '\0' || env[1] == ':')) {
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen /* expand home */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* expand %vars */
2e652d2651b2800f99a17dcb3014a009fe4660d3Timo Sirainenenv_put_namespace(struct namespace_settings *ns, const char *default_location,
2e652d2651b2800f99a17dcb3014a009fe4660d3Timo Sirainen unsigned int i;
14b1d2a2634e75b988078baee1e8ad678de28a04Timo Sirainen location = *ns->location != '\0' ? ns->location :
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen env_put(t_strdup_printf("NAMESPACE_%u=%s", i, location));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_SEP=%s",
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_TYPE=%s",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* expand variables, eg. ~%u/ can be useful */
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_INBOX=1", i));
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_HIDDEN=1", i));
45af47783693b3ba2768c5ad34eeff68132382d0Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_LIST=1", i));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen env_put(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS=1",
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainenmail_process_set_environment(struct settings *set, const char *mail,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct var_expand_table *var_expand_table,
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen const char *const *envs;
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen unsigned int i, count;
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen env_put(t_strconcat("MAIL_NEVER_CACHE_FIELDS=",
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen env_put(t_strdup_printf("MAIL_CACHE_MIN_MAIL_COUNT=%u",
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen env_put(t_strdup_printf("MAILBOX_IDLE_CHECK_INTERVAL=%u",
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen env_put(t_strdup_printf("MAIL_MAX_KEYWORD_LENGTH=%u",
808fab19464062a665af85df5e147c6b64b1c348Timo Sirainen env_put(t_strdup_printf("IMAP_MAX_LINE_LENGTH=%u",
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen env_put(t_strconcat("IMAP_CLIENT_WORKAROUNDS=",
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen env_put(t_strconcat("POP3_CLIENT_WORKAROUNDS=",
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen /* We care about POP3 UIDL format in all process types */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen env_put(t_strconcat("POP3_UIDL_FORMAT=", set->pop3_uidl_format, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* when running dump-capability log still points to stderr,
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen and io_add()ing it might break (epoll_ctl() gives EPERM) */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen if (set->shutdown_clients && !dump_capability)
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat("LOCK_METHOD=", set->lock_method, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat("MBOX_READ_LOCKS=", set->mbox_read_locks, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat("MBOX_WRITE_LOCKS=", set->mbox_write_locks, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strdup_printf("MBOX_LOCK_TIMEOUT=%u",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strdup_printf("MBOX_DOTLOCK_CHANGE_TIMEOUT=%u",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strdup_printf("MBOX_MIN_INDEX_SIZE=%u",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strdup_printf("DBOX_ROTATE_SIZE=%u",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strdup_printf("DBOX_ROTATE_MIN_SIZE=%u",
0afe75cd8ea1814ba5711196ef749f93a140c01cTimo Sirainen env_put(t_strdup_printf("DBOX_ROTATE_DAYS=%u",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat("MAIL_PLUGINS=", set->mail_plugins, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* user given environment - may be malicious. virtual_user comes from
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen auth process, but don't trust that too much either. Some auth
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen mechanism might allow leaving extra data there. */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen if ((mail == NULL || *mail == '\0') && *set->mail_location != '\0')
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen mail = expand_mail_env(set->mail_location, var_expand_table);
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat(t_str_ucase(envs[i]), "=",
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainenvoid mail_process_exec(const char *protocol, const char *section)
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen struct server_settings *server = settings_root;
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen const struct var_expand_table *var_expand_table;
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* external binary. section contains path for it. */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen i_fatal("External binary parameter not given");
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen for (; server != NULL; server = server->next) {
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen get_var_expand_table(protocol, getenv("USER"), getenv("HOME"),
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* set up logging */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen env_put(t_strconcat("LOG_TIMESTAMP=", set->log_timestamp, NULL));
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen env_put(t_strconcat("LOGFILE=", set->log_path, NULL));
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen env_put(t_strconcat("INFOLOGFILE=", set->info_log_path, NULL));
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen var_expand(str, set->mail_log_prefix, var_expand_table);
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen mail_process_set_environment(set, getenv("MAIL"), var_expand_table,
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m", executable);
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainenstatic void nfs_warn_if_found(const char *mail, const char *full_home_dir)
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* indexes set separately */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* autodetection for path */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* format:path */
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen path = home_expand_tilde(t_strcut(path, ':'), full_home_dir);
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen if (mountpoint_get(path, pool_datastack_create(), &point) <= 0)
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen if (point.type == NULL || strcasecmp(point.type, "NFS") != 0)
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen i_fatal("Mailbox indexes in %s are in NFS mount. "
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen "You must set mmap_disable=yes to avoid index corruptions. "
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen "If you're sure this check was wrong, set nfs_check=no.", path);
eb729968680f4a36616ce8c60848c3b6c407f791Timo Sirainencreate_mail_process(enum process_type process_type, struct settings *set,
9307e4f91ea313a303b5473d9c53a3a2f383300fTimo Sirainen const struct var_expand_table *var_expand_table;
719123a3ec5aeb45ef1c50c265039666c71981d7Timo Sirainen const char *p, *addr, *mail, *chroot_dir, *home_dir, *full_home_dir;
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen if (mail_process_count == set->max_mail_processes) {
eb729968680f4a36616ce8c60848c3b6c407f791Timo Sirainen i_error("Maximum number of mail processes exceeded");
eb729968680f4a36616ce8c60848c3b6c407f791Timo Sirainen /* check process limit for this user */
eb729968680f4a36616ce8c60848c3b6c407f791Timo Sirainen mail_process_group_lookup(process_type, user, remote_ip);
a3e96a912e8a058a7372eda55ffc95d54269bd3cTimo Sirainen if (process_count >= set->mail_max_userip_connections &&
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail = home_dir = chroot_dir = system_user = "";
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen else if (strncmp(*args, "system_user=", 12) == 0)
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen i_error("uid specified multiple times for %s",
9bbfe7f5ff821cac11d1d2550a91b148f389d82cTimo Sirainen /* if uid/gid wasn't returned, use the defaults */
03936179f87aebde358dbe1ca8c34e5b5551db45Timo Sirainen i_error("User %s is missing UID (set mail_uid)", user);
9bbfe7f5ff821cac11d1d2550a91b148f389d82cTimo Sirainen i_error("User %s is missing GID (set mail_gid)", user);
d52f5dcb05092e126058874772f2c367499e650aTimo Sirainen if (*chroot_dir == '\0' && (p = strstr(home_dir, "/./")) != NULL) {
d52f5dcb05092e126058874772f2c367499e650aTimo Sirainen /* wu-ftpd like <chroot>/./<home> */
d52f5dcb05092e126058874772f2c367499e650aTimo Sirainen } else if (*chroot_dir != '\0' && *home_dir != '/') {
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen /* home directories should never be relative, but force this
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen with chroots. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (*chroot_dir == '\0' && *set->mail_chroot != '\0')
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Invalid chroot directory '%s' (user %s) "
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen "(see valid_chroot_dirs in config file)",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_error("Can't chroot to directory '%s' (user %s) "
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen "with mail_drop_priv_before_exec=yes",
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen log_fd = log_create_pipe(&log, set->mail_log_max_lines_per_sec);
d52f5dcb05092e126058874772f2c367499e650aTimo Sirainen /* See if we need to do the initial NFS check. We want to do this only
d52f5dcb05092e126058874772f2c367499e650aTimo Sirainen once, so the check code needs to be before fork(). */
a1893588a73d32a322153f5a2f7a16ef2c724979Timo Sirainen if (set->nfs_check && !set->mmap_disable && !dump_capability) {
3ef4aca8cae3e335e1fe53591049cb80b299c459Timo Sirainen get_var_expand_table(process_names[process_type],
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen var_expand(str, set->mail_log_prefix, var_expand_table);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen var_expand(str, set->mail_log_prefix, var_expand_table);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* move the client socket into stdin and stdout fds, log to stderr */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen if (dup2(dump_capability ? null_fd : socket, 0) < 0)
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen for (i = 0; i < 3; i++)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* setup environment - set the most important environment first
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen (paranoia about filling up environment without noticing) */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen restrict_access_set_env(system_user, uid, gid, chroot_dir,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen restrict_process_size(set->mail_process_size, (unsigned int)-1);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen full_home_dir = *chroot_dir == '\0' ? home_dir :
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* NOTE: if home directory is NFS-mounted, we might not
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen have access to it as root. Change the effective UID and GID
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen temporarily to make it work. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_fatal("setegid(%s) failed: %m", dec2str(gid));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(uid));
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen if ((left = alarm(0)) < CHDIR_TIMEOUT - CHDIR_WARN_SECS) {
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen /* Change UID back. No need to change GID back, it doesn't
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen really matter. */
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen if (uid != master_uid && seteuid(master_uid) < 0)
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen i_fatal("seteuid(%s) failed: %m", dec2str(master_uid));
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen /* If user's home directory doesn't exist and we're not
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen trying to chroot anywhere, fallback to /tmp as the mails
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen could be stored elsewhere. The ENOTDIR check is mostly for
69f6407b20f623193981d672c26fa722ee75d941Timo Sirainen /dev/null home directory. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* We still have to change to some directory where we have
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen rx-access. /tmp should exist everywhere. */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mail_process_set_environment(set, mail, var_expand_table,
8576eb5abb66178f251c00209e564c7673c0e4cfTimo Sirainen /* extra args. uppercase key value. */
03936179f87aebde358dbe1ca8c34e5b5551db45Timo Sirainen for (i = 0; i < count; i++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* Should be caught by dovecot-auth already */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_fatal("Userdb returned data with empty key (%s)",
79490ec1a58241d6011fa36713ca651d795855c3Timo Sirainen /* boolean */
79490ec1a58241d6011fa36713ca651d795855c3Timo Sirainen env_put(t_strconcat(t_str_ucase(args[i]), "=1", NULL));
79490ec1a58241d6011fa36713ca651d795855c3Timo Sirainen /* key=value */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* ideally we should check all of the namespaces,
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen but for now don't bother. */
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen const char *mail_location = getenv("NAMESPACE_1");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen nfs_warn_if_found(mail_location, full_home_dir);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen env_put(t_strconcat("HOME=", home_dir, NULL));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_snprintf(title, sizeof(title), "[%s %s]", user, addr);
3ea86ed7cf06ba04e4aa6cd1c4df9be336c06cd3Timo Sirainen /* make sure we don't leak syslog fd, but do it last so that
471a6b2b4e64eca5d5779ae20a477312b32c89eeTimo Sirainen any errors above will be logged */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen client_process_exec(set->mail_executable, title);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m",
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* not reached */
0c47c2096714b50880d48d00ce0bf28349eb4aceTimo Sirainenmail_process_destroyed(struct child_process *process,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen struct mail_process_group *group = (struct mail_process_group *)process;
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen unsigned int i, count;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen /* last process in this group */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < count; i++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen mail_process_groups = hash_create(default_pool, default_pool, 0,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen child_process_set_destroy_callback(PROCESS_TYPE_IMAP,
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen child_process_set_destroy_callback(PROCESS_TYPE_POP3,