# HG changeset patch # User Timo Sirainen # Date 1183423896 -10800 # Node ID 933caa747d37a4ec57ef2ca205e29eea00f10b9d # Parent cda9824bab6336ac754bd59f3d4704cf92b053dc Added mail_uid and mail_gid settings. diff -r cda9824bab63 -r 933caa747d37 dovecot-example.conf --- a/dovecot-example.conf Tue Jul 03 03:47:39 2007 +0300 +++ b/dovecot-example.conf Tue Jul 03 03:51:36 2007 +0300 @@ -256,6 +256,12 @@ #list = yes #} +# System user and group used to access mails. If you use multiple, userdb +# can override these by returning uid or gid fields. You can use either numbers +# or names. +#mail_uid = +#mail_gid = + # Grant access to these extra groups for mail processes. Typical use would be # to give "mail" group write access to /var/mail to be able to create dotlocks. #mail_extra_groups = diff -r cda9824bab63 -r 933caa747d37 src/master/mail-process.c --- a/src/master/mail-process.c Tue Jul 03 03:47:39 2007 +0300 +++ b/src/master/mail-process.c Tue Jul 03 03:51:36 2007 +0300 @@ -539,7 +539,7 @@ t_array_init(&extra_args, 16); mail = home_dir = chroot_dir = system_user = ""; - uid = gid = 0; nice = 0; + uid = (uid_t)-1; gid = (gid_t)-1; nice = 0; home_given = FALSE; for (; *args != NULL; args++) { if (strncmp(*args, "home=", 5) == 0) { @@ -554,7 +554,7 @@ else if (strncmp(*args, "system_user=", 12) == 0) system_user = *args + 12; else if (strncmp(*args, "uid=", 4) == 0) { - if (uid != 0) { + if (uid != (uid_t)-1) { i_error("uid specified multiple times for %s", user); return MASTER_LOGIN_STATUS_INTERNAL_ERROR; @@ -568,6 +568,22 @@ } } + /* if uid/gid wasn't returned, use the defaults */ + if (uid == (uid_t)-1) { + uid = set->mail_uid_t; + if (uid == (uid_t)-1) { + i_error("User %s is missing UID (set mail_uid)", user); + return MASTER_LOGIN_STATUS_INTERNAL_ERROR; + } + } + if (gid == (gid_t)-1) { + gid = set->mail_gid_t; + if (gid == (gid_t)-1) { + i_error("User %s is missing GID (set mail_gid)", user); + return MASTER_LOGIN_STATUS_INTERNAL_ERROR; + } + } + if (*chroot_dir == '\0' && (p = strstr(home_dir, "/./")) != NULL) { /* wu-ftpd like /./ */ chroot_dir = t_strdup_until(home_dir, p); diff -r cda9824bab63 -r 933caa747d37 src/master/master-settings-defs.c --- a/src/master/master-settings-defs.c Tue Jul 03 03:47:39 2007 +0300 +++ b/src/master/master-settings-defs.c Tue Jul 03 03:51:36 2007 +0300 @@ -63,6 +63,8 @@ DEF_INT(first_valid_gid), DEF_INT(last_valid_gid), DEF_STR(mail_extra_groups), + DEF_STR(mail_uid), + DEF_STR(mail_gid), DEF_STR(default_mail_env), DEF_STR(mail_location), diff -r cda9824bab63 -r 933caa747d37 src/master/master-settings.c --- a/src/master/master-settings.c Tue Jul 03 03:47:39 2007 +0300 +++ b/src/master/master-settings.c Tue Jul 03 03:51:36 2007 +0300 @@ -22,6 +22,7 @@ #include #include #include +#include enum settings_type { SETTINGS_TYPE_ROOT, @@ -214,6 +215,8 @@ MEMBER(first_valid_gid) 1, MEMBER(last_valid_gid) 0, MEMBER(mail_extra_groups) "", + MEMBER(mail_uid) "", + MEMBER(mail_gid) "", MEMBER(default_mail_env) "", MEMBER(mail_location) "", @@ -350,6 +353,44 @@ } } +static bool parse_uid(const char *str, uid_t *uid_r) +{ + struct passwd *pw; + char *p; + + if (*str >= '0' && *str <= '9') { + *uid_r = (uid_t)strtoul(str, &p, 10); + if (*p == '\0') + return TRUE; + } + + pw = getpwnam(str); + if (pw == NULL) + return FALSE; + + *uid_r = pw->pw_uid; + return TRUE; +} + +static bool parse_gid(const char *str, gid_t *gid_r) +{ + struct group *gr; + char *p; + + if (*str >= '0' && *str <= '9') { + *gid_r = (gid_t)strtoul(str, &p, 10); + if (*p == '\0') + return TRUE; + } + + gr = getgrnam(str); + if (gr == NULL) + return FALSE; + + *gid_r = gr->gr_gid; + return TRUE; +} + static bool get_login_uid(struct settings *set) { struct passwd *pw; @@ -641,6 +682,18 @@ if (!get_login_uid(set)) return FALSE; + set->mail_uid_t = (uid_t)-1; + set->mail_gid_t = (gid_t)-1; + + if (*set->mail_uid != '\0') { + if (!parse_uid(set->mail_uid, &set->mail_uid_t)) + return FALSE; + } + if (*set->mail_gid != '\0') { + if (!parse_gid(set->mail_gid, &set->mail_gid_t)) + return FALSE; + } + if (set->protocol == MAIL_PROTOCOL_POP3 && *set->pop3_uidl_format == '\0') { i_error("POP3 enabled but pop3_uidl_format not set"); diff -r cda9824bab63 -r 933caa747d37 src/master/master-settings.h --- a/src/master/master-settings.h Tue Jul 03 03:47:39 2007 +0300 +++ b/src/master/master-settings.h Tue Jul 03 03:51:36 2007 +0300 @@ -67,6 +67,8 @@ unsigned int first_valid_uid, last_valid_uid; unsigned int first_valid_gid, last_valid_gid; const char *mail_extra_groups; + const char *mail_uid; + const char *mail_gid; const char *default_mail_env; const char *mail_location; @@ -124,7 +126,8 @@ /* .. */ int listen_fd, ssl_listen_fd; - uid_t login_uid; + uid_t login_uid, mail_uid_t; + gid_t mail_gid_t; struct ip_addr listen_ip, ssl_listen_ip; unsigned int listen_port, ssl_listen_port;