]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Chrooting changes. Now all userdbs will support "<chroot>/./<homedir>" style
authorTimo Sirainen <tss@iki.fi>
Thu, 8 May 2003 04:28:30 +0000 (07:28 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 8 May 2003 04:28:30 +0000 (07:28 +0300)
home directories.

--HG--
branch : HEAD

14 files changed:
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

index 79e02b0eb5faeb0ed96b83dbc74cd9b8a10362f1..d790c8bc6647f44de2c592e4550b54b58f04a76f 100644 (file)
@@ -53,6 +53,10 @@ Realms (or virtual domains) are supported by appending the "@realm" after
 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 @@ nowadays so it doesn't usually work as password database. BSDs are an
 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
 ------
index 25ec89d773f104072ed451a0053c657527d9e631..f901a590dda231aafbb25cd2e14825850ec44b4a 100644 (file)
@@ -37,7 +37,6 @@ base = uid=someone, dc=foo, dc=bar, dc=org
 #  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:
index b43cfdb0a64c93523e8c31dcdbefd2fc3416ea66..f37e321355d68a8fb45652dd375f653c663b3777 100644 (file)
@@ -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.
index fe89a8b7e332c46846b6b93f6144a4f0919ff249..1494bb737391c92da92b51bac9fe805164d9bcc5 100644 (file)
@@ -14,7 +14,6 @@ struct auth_master_reply {
        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 @@ struct auth_master_reply {
           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[]; */
index 1d740a2f6fd70a59666b3dcccd06bde6528996e7..73356b6adb226feaf1cbceed45571f3e1ad7d34b 100644 (file)
@@ -100,8 +100,7 @@ static void passwd_file_add(struct passwd_file *pw, const char *username,
 
        /* flags */
        if (*args != NULL) {
-               if (strstr(*args, "chroot") != NULL)
-                       pu->chroot = TRUE;
+               /* no flags currently */
                args++;
        }
 
index 40398ecb931cffb18f724461f457994ed6f4c961..1ba31e1394658403f3a85ad4b85b54be142a4984 100644 (file)
@@ -12,8 +12,6 @@ struct passwd_user {
        char *mail;
 
        char *password;
-
-       unsigned int chroot:1;
 };
 
 struct passwd_file {
index 4fa1476c18a2e38af428985244ede81dc92eebac..4e4be63a7f0d69f216fdba6ffcd8f637e90198e2 100644 (file)
@@ -39,6 +39,7 @@ fill_reply(const struct user_data *user, size_t *reply_size)
 {
        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 @@ fill_reply(const struct user_data *user, size_t *reply_size)
 
        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;
index a6a5ef0d73e6b08fa1c6f61157f95fe994d6c1a1..37647e06cdf7c2171bb4157137c28ff69705b806 100644 (file)
@@ -24,7 +24,6 @@ enum ldap_user_attr {
        ATTR_SYSTEM_USER,
        ATTR_UID_NUMBER,
        ATTR_GID_NUMBER,
-       ATTR_CHROOT,
 
        ATTR_COUNT
 };
@@ -78,9 +77,6 @@ static void parse_attr(struct userdb_ldap_connection *conn,
        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;
index a7e8bd6b8c954a7a687d84508cce4e08f68719fc..9fd1456a37c65f2163310f9b1b8d3de52b7b2db7 100644 (file)
@@ -31,8 +31,6 @@ static void passwd_file_lookup(const char *user, userdb_callback_t *callback,
        data.home = pu->home;
        data.mail = pu->mail;
 
-       data.chroot = pu->chroot;
-
        callback(&data, context);
 }
 
index f1f5de762d9c9d770997ed928f0f112a8eb06219..601463d20241d371b83da32cdc7e7142ce348fcc 100644 (file)
@@ -15,7 +15,6 @@ static void passwd_lookup(const char *user, userdb_callback_t *callback,
 {
        struct user_data data;
        struct passwd *pw;
-       size_t len;
 
        pw = getpwnam(user);
        if (pw == NULL) {
@@ -32,16 +31,7 @@ static void passwd_lookup(const char *user, userdb_callback_t *callback,
        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);
 }
index 716fd7002722d062ba4d7f444b7a426204b3ba08..be80cf8df04857ddf399ccccbea9a81e43455131 100644 (file)
@@ -69,7 +69,6 @@ static void pgsql_handle_request(struct pgsql_connection *conn __attr_unused__,
        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 @@ static void pgsql_handle_request(struct pgsql_connection *conn __attr_unused__,
                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);
index 9553c7d096ea286bb894e163ade30b99c33da280..75a5527bbe31288c398007b8ad99ced114d78d60 100644 (file)
@@ -9,8 +9,6 @@ struct user_data {
        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);
index ce19d22095c7f0fb8ae7d0f135ea0dfe2133b3f0..9a67d375711111c6e3286fdfe6f5ae24458b6a42 100644 (file)
@@ -90,6 +90,8 @@ static int handle_reply(struct auth_process *process,
                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;
 
index 26b94cf1f7e1d506b39c153558c590ed6b6a7a85..9fde9b7343d7ab3547b20a6052881584e77613eb 100644 (file)
@@ -105,7 +105,7 @@ int create_mail_process(int socket, struct ip_addr *ip,
                        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 @@ int create_mail_process(int socket, struct ip_addr *ip,
        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 @@ int create_mail_process(int socket, struct ip_addr *ip,
        /* 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 @@ int create_mail_process(int socket, struct ip_addr *ip,
        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));