changeset 1443:c96290faa106 HEAD

Chrooting changes. Now all userdbs will support "<chroot>/./<homedir>" style home directories.
author Timo Sirainen <tss@iki.fi>
date Thu, 08 May 2003 07:28:30 +0300
parents e03d22a64fb0
children 3b9a09c18647
files doc/auth.txt doc/dovecot-ldap.conf doc/dovecot-pgsql.conf src/auth/auth-master-interface.h src/auth/db-passwd-file.c src/auth/db-passwd-file.h src/auth/master-connection.c src/auth/userdb-ldap.c src/auth/userdb-passwd-file.c src/auth/userdb-passwd.c src/auth/userdb-pgsql.c src/auth/userdb.h src/master/auth-process.c src/master/mail-process.c
diffstat 14 files changed, 32 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/doc/auth.txt	Thu May 08 07:06:59 2003 +0300
+++ b/doc/auth.txt	Thu May 08 07:28:30 2003 +0300
@@ -53,6 +53,10 @@
 the user name. This behaviour works with all authentication mechanisms and
 databases.
 
+Home directory can be prefixed with "<chroot>/./" in which case <chroot>
+directory will be chrooted into. The actual home directory follows the
+"/./". For example "/chroot/./home/user".
+
 
 passwd
 ------
@@ -62,7 +66,6 @@
 exception to this, they still set the password field even with shadow
 passwords.
 
-As an extension, if home directory ends with "/./", it will be chrooted to.
 
 shadow
 ------
--- a/doc/dovecot-ldap.conf	Thu May 08 07:06:59 2003 +0300
+++ b/doc/dovecot-ldap.conf	Thu May 08 07:28:30 2003 +0300
@@ -37,7 +37,6 @@
 #  System user name (for initgroups())
 #  System UID
 #  System GID
-#  Chroot to home directory? (yes / no)
 #user_attrs = uid,homeDirectory,,uid,uidNumber,gidNumber
 
 # Filter for user lookup. Some variables can be used:
--- a/doc/dovecot-pgsql.conf	Thu May 08 07:06:59 2003 +0300
+++ b/doc/dovecot-pgsql.conf	Thu May 08 07:28:30 2003 +0300
@@ -61,7 +61,6 @@
 #   system_user - System user name (for initgroups())
 #   uid - System UID
 #   gid - System GID
-#   chroot - Chroot to home directory? (Y / N)
 #
 # Either home or mail is required. uid and gid are required. If more than one
 # row is returned or there's missing fields, login will automatically fail.
--- a/src/auth/auth-master-interface.h	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/auth-master-interface.h	Thu May 08 07:28:30 2003 +0300
@@ -14,7 +14,6 @@
 	unsigned int tag;
 
 	unsigned int success:1;
-	unsigned int chroot:1; /* chroot to home directory */
 
 	uid_t uid;
 	gid_t gid;
@@ -24,7 +23,7 @@
 	   Ignore if it points outside data_size. */
 	size_t system_user_idx;
 	size_t virtual_user_idx;
-	size_t home_idx, mail_idx;
+	size_t home_idx, mail_idx, chroot_idx;
 
 	size_t data_size;
 	/* unsigned char data[]; */
--- a/src/auth/db-passwd-file.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/db-passwd-file.c	Thu May 08 07:28:30 2003 +0300
@@ -100,8 +100,7 @@
 
 	/* flags */
 	if (*args != NULL) {
-		if (strstr(*args, "chroot") != NULL)
-			pu->chroot = TRUE;
+		/* no flags currently */
 		args++;
 	}
 
--- a/src/auth/db-passwd-file.h	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/db-passwd-file.h	Thu May 08 07:28:30 2003 +0300
@@ -12,8 +12,6 @@
 	char *mail;
 
 	char *password;
-
-	unsigned int chroot:1;
 };
 
 struct passwd_file {
--- a/src/auth/master-connection.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/master-connection.c	Thu May 08 07:28:30 2003 +0300
@@ -39,6 +39,7 @@
 {
 	struct auth_master_reply *reply;
 	buffer_t *buf;
+	char *p;
 
 	buf = buffer_create_dynamic(data_stack_pool,
 				    sizeof(*reply) + 256, (size_t)-1);
@@ -46,15 +47,23 @@
 
 	reply->success = TRUE;
 
-	reply->chroot = user->chroot;
 	reply->uid = user->uid;
 	reply->gid = user->gid;
 
 	reply->system_user_idx = reply_add(buf, user->system_user);
 	reply->virtual_user_idx = reply_add(buf, user->virtual_user);
-	reply->home_idx = reply_add(buf, user->home);
 	reply->mail_idx = reply_add(buf, user->mail);
 
+	p = strstr(user->home, "/./");
+	if (p == NULL) {
+		reply->home_idx = reply_add(buf, user->home);
+		reply->chroot_idx = reply_add(buf, NULL);
+	} else {
+		/* wu-ftpd like <chroot>/./<home> */
+		reply->home_idx = reply_add(buf, t_strdup_until(user->home, p));
+		reply->chroot_idx = reply_add(buf, p + 3);
+	}
+
 	*reply_size = buffer_get_used_size(buf);
 	reply->data_size = *reply_size - sizeof(*reply);
 	return reply;
--- a/src/auth/userdb-ldap.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/userdb-ldap.c	Thu May 08 07:28:30 2003 +0300
@@ -24,7 +24,6 @@
 	ATTR_SYSTEM_USER,
 	ATTR_UID_NUMBER,
 	ATTR_GID_NUMBER,
-	ATTR_CHROOT,
 
 	ATTR_COUNT
 };
@@ -78,9 +77,6 @@
 	case ATTR_GID_NUMBER:
 		user->gid = atoi(value);
 		break;
-	case ATTR_CHROOT:
-		user->chroot = value[0] == 'Y' || value[0] == 'y';
-		break;
 
 	case ATTR_COUNT:
 		break;
--- a/src/auth/userdb-passwd-file.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/userdb-passwd-file.c	Thu May 08 07:28:30 2003 +0300
@@ -31,8 +31,6 @@
 	data.home = pu->home;
 	data.mail = pu->mail;
 
-	data.chroot = pu->chroot;
-
 	callback(&data, context);
 }
 
--- a/src/auth/userdb-passwd.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/userdb-passwd.c	Thu May 08 07:28:30 2003 +0300
@@ -15,7 +15,6 @@
 {
 	struct user_data data;
 	struct passwd *pw;
-	size_t len;
 
 	pw = getpwnam(user);
 	if (pw == NULL) {
@@ -32,16 +31,7 @@
 	data.gid = pw->pw_gid;
 
 	data.virtual_user = data.system_user = pw->pw_name;
-
-	len = strlen(pw->pw_dir);
-	if (len < 3 || strcmp(pw->pw_dir + len - 3, "/./") != 0)
-		data.home = pw->pw_dir;
-	else {
-		/* wu-ftpd uses <chroot>/./<dir>. We don't support
-		   the dir after chroot, but this should work well enough. */
-		data.home = t_strndup(pw->pw_dir, len-3);
-		data.chroot = TRUE;
-	}
+	data.home = pw->pw_dir;
 
 	callback(&data, context);
 }
--- a/src/auth/userdb-pgsql.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/userdb-pgsql.c	Thu May 08 07:28:30 2003 +0300
@@ -69,7 +69,6 @@
 	struct userdb_pgsql_request *urequest =
 		(struct userdb_pgsql_request *) request;
 	struct user_data user;
-	const char *str;
 
 	if (res != NULL && is_result_valid(res)) {
 		memset(&user, 0, sizeof(user));
@@ -79,8 +78,6 @@
 		user.mail = pg_get_str(res, "mail");
 		user.uid = atoi(PQgetvalue(res, 0, PQfnumber(res, "uid")));
 		user.gid = atoi(PQgetvalue(res, 0, PQfnumber(res, "gid")));
-		str = pg_get_str(res, "chroot");
-		user.chroot = str != NULL && (*str == 'Y' || *str == 'y');
 		urequest->userdb_callback(&user, request->context);
 	} else {
 		urequest->userdb_callback(NULL, request->context);
--- a/src/auth/userdb.h	Thu May 08 07:06:59 2003 +0300
+++ b/src/auth/userdb.h	Thu May 08 07:28:30 2003 +0300
@@ -9,8 +9,6 @@
 	const char *system_user;
 	uid_t uid;
 	gid_t gid;
-
-	int chroot; /* chroot to home directory */
 };
 
 typedef void userdb_callback_t(struct user_data *user, void *context);
--- a/src/master/auth-process.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/master/auth-process.c	Thu May 08 07:28:30 2003 +0300
@@ -90,6 +90,8 @@
 		reply->virtual_user_idx = nul_pos;
 	if (reply->home_idx >= reply->data_size)
 		reply->home_idx = nul_pos;
+	if (reply->chroot_idx >= reply->data_size)
+		reply->chroot_idx = nul_pos;
 	if (reply->mail_idx >= reply->data_size)
 		reply->mail_idx = nul_pos;
 
--- a/src/master/mail-process.c	Thu May 08 07:06:59 2003 +0300
+++ b/src/master/mail-process.c	Thu May 08 07:28:30 2003 +0300
@@ -105,7 +105,7 @@
 			const char *data)
 {
 	static const char *argv[] = { NULL, NULL, NULL };
-	const char *host, *mail, *home_dir;
+	const char *host, *mail, *chroot_dir, *home_dir, *full_home_dir;
 	char title[1024];
 	pid_t pid;
 	int i, err;
@@ -118,8 +118,11 @@
 	if (!validate_uid_gid(reply->uid, reply->gid))
 		return FALSE;
 
-	if (reply->chroot && !validate_chroot(data + reply->home_idx)) {
-		i_error("Invalid chroot directory: %s", data + reply->home_idx);
+	home_dir = data + reply->home_idx;
+	chroot_dir = data + reply->chroot_idx;
+
+	if (*chroot_dir != '\0' && validate_chroot(chroot_dir)) {
+		i_error("Invalid chroot directory: %s", chroot_dir);
 		return FALSE;
 	}
 
@@ -151,15 +154,15 @@
 	/* setup environment - set the most important environment first
 	   (paranoia about filling up environment without noticing) */
 	restrict_access_set_env(data + reply->system_user_idx,
-				reply->uid, reply->gid,
-				reply->chroot ? data + reply->home_idx : NULL);
+				reply->uid, reply->gid, chroot_dir);
 
 	restrict_process_size(process_size, (unsigned int)-1);
 
-	home_dir = data + reply->home_idx;
 	if (*home_dir != '\0') {
-		if (chdir(home_dir) < 0)
-			i_fatal("chdir(%s) failed: %m", home_dir);
+		full_home_dir = *chroot_dir == '\0' ? home_dir :
+			t_strconcat(chroot_dir, "/", home_dir, NULL);
+		if (chdir(full_home_dir) < 0)
+			i_fatal("chdir(%s) failed: %m", full_home_dir);
 	}
 
 	env_put("LOGGED_IN=1");
@@ -204,7 +207,7 @@
 	if (*mail == '\0' && set->default_mail_env != NULL) {
 		mail = expand_mail_env(set->default_mail_env,
 				       data + reply->virtual_user_idx,
-				       data + reply->home_idx);
+				       home_dir);
 	}
 
 	env_put(t_strconcat("MAIL=", mail, NULL));