changeset 5876:933caa747d37 HEAD

Added mail_uid and mail_gid settings.
author Timo Sirainen <tss@iki.fi>
date Tue, 03 Jul 2007 03:51:36 +0300
parents cda9824bab63
children a3bbf340694f
files dovecot-example.conf src/master/mail-process.c src/master/master-settings-defs.c src/master/master-settings.c src/master/master-settings.h
diffstat 5 files changed, 83 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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. <doc/wiki/UserIds>
+#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 =
--- 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>/./<home> */
 		chroot_dir = t_strdup_until(home_dir, p);
--- 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),
--- 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 <sys/stat.h>
 #include <sys/wait.h>
 #include <pwd.h>
+#include <grp.h>
 
 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");
--- 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;