Mercurial > dovecot > original-hg > dovecot-1.2
view src/master/imap-process.c @ 643:da34bdd4e0c6 HEAD
Added mbox lock settings to config file. Support timeouting fcntl() and
flock() locks. Plus before the fcntl/flocks weren't even set.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 21 Nov 2002 22:13:32 +0200 |
parents | 3b44bc64afd4 |
children | 415498fa78d6 |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "common.h" #include "restrict-access.h" #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <syslog.h> #include <grp.h> static unsigned int imap_process_count = 0; static int validate_uid_gid(uid_t uid, gid_t gid) { if (uid == 0) { i_error("imap process isn't allowed for root"); return FALSE; } if (uid != 0 && gid == 0) { i_error("imap process isn't allowed to be in group 0"); return FALSE; } if (uid < (uid_t)set_first_valid_uid || (set_last_valid_uid != 0 && uid > (uid_t)set_last_valid_uid)) { i_error("imap process isn't allowed to use UID %ld", (long) uid); return FALSE; } if (gid < (gid_t)set_first_valid_gid || (set_last_valid_gid != 0 && gid > (gid_t)set_last_valid_gid)) { i_error("imap process isn't allowed to use " "GID %ld (UID is %ld)", (long) gid, (long) uid); return FALSE; } return TRUE; } static int validate_chroot(const char *dir) { char *const *chroot_dirs; if (*dir == '\0') return TRUE; if (set_valid_chroot_dirs == '\0') return FALSE; chroot_dirs = t_strsplit(set_valid_chroot_dirs, ":"); while (*chroot_dirs != NULL) { if (strncmp(dir, *chroot_dirs, strlen(*chroot_dirs)) == 0) return TRUE; chroot_dirs++; } return FALSE; } MasterReplyResult create_imap_process(int socket, IPADDR *ip, const char *user, uid_t uid, gid_t gid, const char *home, int chroot, const char *env[]) { static char *argv[] = { NULL, "-s", NULL, NULL }; char host[MAX_IP_LEN], title[1024]; pid_t pid; int i, j, err; if (imap_process_count == set_max_imap_processes) { i_error("Maximum number of imap processes exceeded"); return MASTER_RESULT_INTERNAL_FAILURE; } if (!validate_uid_gid(uid, gid)) return MASTER_RESULT_FAILURE; if (chroot && !validate_chroot(home)) return MASTER_RESULT_FAILURE; pid = fork(); if (pid < 0) { i_error("fork() failed: %m"); return MASTER_RESULT_INTERNAL_FAILURE; } if (pid != 0) { /* master */ imap_process_count++; PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_IMAP); (void)close(socket); return MASTER_RESULT_SUCCESS; } clean_child_process(); /* move the imap socket into stdin, stdout and stderr fds */ for (i = 0; i < 3; i++) { if (dup2(socket, i) < 0) { err = errno; for (j = 0; j < i; j++) (void)close(j); (void)close(socket); i_fatal("imap: dup2() failed: %m"); } } (void)close(socket); /* setup environment */ while (env[0] != NULL && env[1] != NULL) { putenv((char *) t_strconcat(env[0], "=", env[1], NULL)); env += 2; } putenv((char *) t_strconcat("HOME=", home, NULL)); putenv((char *) t_strconcat("MAIL_CACHE_FIELDS=", set_mail_cache_fields, NULL)); putenv((char *) t_strconcat("MAIL_NEVER_CACHE_FIELDS=", set_mail_never_cache_fields, NULL)); putenv((char *) t_strdup_printf("MAILBOX_CHECK_INTERVAL=%u", set_mailbox_check_interval)); if (set_mail_save_crlf) putenv("MAIL_SAVE_CRLF=1"); if (set_maildir_copy_with_hardlinks) putenv("MAILDIR_COPY_WITH_HARDLINKS=1"); if (set_maildir_check_content_changes) putenv("MAILDIR_CHECK_CONTENT_CHANGES=1"); if (set_overwrite_incompatible_index) putenv("OVERWRITE_INCOMPATIBLE_INDEX=1"); if (umask(set_umask) != set_umask) i_fatal("Invalid umask: %o", set_umask); putenv((char *) t_strconcat("MBOX_LOCKS=", set_mbox_locks, NULL)); putenv((char *) t_strdup_printf("MBOX_LOCK_TIMEOUT=%u", set_mbox_lock_timeout)); putenv((char *) t_strdup_printf("MBOX_DOTLOCK_CHANGE_TIMEOUT=%u", set_mbox_dotlock_change_timeout)); if (set_mbox_read_dotlock) putenv("MBOX_READ_DOTLOCK=1"); if (set_verbose_proctitle && net_ip2host(ip, host) == 0) { i_snprintf(title, sizeof(title), "[%s %s]", user, host); argv[2] = title; } /* setup access environment - needs to be done after clean_child_process() since it clears environment */ restrict_access_set_env(user, uid, gid, chroot ? home : NULL); /* hide the path, it's ugly */ argv[0] = strrchr(set_imap_executable, '/'); if (argv[0] == NULL) argv[0] = set_imap_executable; else argv[0]++; execv(set_imap_executable, argv); err = errno; for (i = 0; i < 3; i++) (void)close(i); i_fatal("execv(%s) failed: %m", set_imap_executable); /* not reached */ return 0; } void imap_process_destroyed(pid_t pid __attr_unused__) { imap_process_count--; }