Currently, "chroot -u" doesn't use the settings in /etc/login.conf.
This adds a -c option to apply the via setusercontext().  We can't
use LOGIN_SETALL since the uid change has to happen after chroot(2)
and the groups may be specified via the -g option.

Open questions:

1) Should this just be default behavior with -u?  Are there cases
   when you would *not* want to set the priority and resouce limits
   based on the target user when one is specified?

2) Does it make sense to apply LOGIN_SETPATH, LOGIN_SETPATH
   and LOGIN_SETUMASK or are we better off with just LOGIN_SETPRIORITY
   and LOGIN_SETRESOURCES?  Ultimately it depends on whether you
   expect the chroot'd environment to be setup like a login session
   or not.  We don't invoke the shell as a login shell though.

Opinions?

 - todd

Index: usr.sbin/chroot/chroot.8
===================================================================
RCS file: /cvs/src/usr.sbin/chroot/chroot.8,v
retrieving revision 1.14
diff -u -p -u -r1.14 chroot.8
--- usr.sbin/chroot/chroot.8    8 Jul 2010 06:52:30 -0000       1.14
+++ usr.sbin/chroot/chroot.8    18 May 2015 20:02:55 -0000
@@ -37,6 +37,7 @@
 .Nd change root directory
 .Sh SYNOPSIS
 .Nm chroot
+.Op Fl c
 .Op Fl g Ar group,group,...
 .Op Fl u Ar user
 .Ar newroot
@@ -56,6 +57,13 @@ command is restricted to the superuser.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl c
+Apply the user's login class as defined in
+.Xr login.conf 5
+before executing
+.Ar command .
+This option may only be used in conjunction with
+.Fl u .
 .It Fl g Ar group,group,...
 Override the primary and supplemental group IDs.
 The primary group ID is set to the first group in the list.
@@ -94,6 +102,7 @@ is used.
 .El
 .Sh SEE ALSO
 .Xr ldd 1 ,
+.Xr login.conf 5 ,
 .Xr group 5 ,
 .Xr passwd 5 ,
 .Xr environ 7
Index: usr.sbin/chroot/chroot.c
===================================================================
RCS file: /cvs/src/usr.sbin/chroot/chroot.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 chroot.c
--- usr.sbin/chroot/chroot.c    27 Oct 2009 23:59:51 -0000      1.13
+++ usr.sbin/chroot/chroot.c    18 May 2015 19:56:15 -0000
@@ -35,8 +35,10 @@
 #include <errno.h>
 #include <grp.h>
 #include <limits.h>
+#include <login_cap.h>
 #include <paths.h>
 #include <pwd.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -50,16 +52,21 @@ main(int argc, char **argv)
 {
        struct group    *grp;
        struct passwd   *pwd;
+       login_cap_t     *lc = NULL;
        const char      *shell;
        char            *user, *group, *grouplist;
        gid_t           gidlist[NGROUPS_MAX];
        int             ch, ngids;
+       bool            cflag = false;
 
        ngids = 0;
        pwd = NULL;
        user = grouplist = NULL;
-       while ((ch = getopt(argc, argv, "g:u:")) != -1) {
+       while ((ch = getopt(argc, argv, "cg:u:")) != -1) {
                switch(ch) {
+               case 'c':
+                       cflag = true;
+                       break;
                case 'u':
                        user = optarg;
                        if (*user == '\0')
@@ -83,6 +90,12 @@ main(int argc, char **argv)
        if (user != NULL && (pwd = getpwnam(user)) == NULL)
                errx(1, "no such user `%s'", user);
 
+       if (cflag) {
+               if (pwd == NULL)
+                       errx(1, "login class requires a user");
+               lc = login_getclass(pwd->pw_class);
+       }
+
        while ((group = strsep(&grouplist, ",")) != NULL) {
                if (*group == '\0')
                        continue;
@@ -104,6 +117,11 @@ main(int argc, char **argv)
                        err(1, "setgid");
                if (initgroups(user, pwd->pw_gid) == -1)
                        err(1, "initgroups");
+               if (lc != NULL) {
+                       const int flags = LOGIN_SETALL & 
~(LOGIN_SETGROUP|LOGIN_SETLOGIN|LOGIN_SETUSER);
+                       if (setusercontext(lc, pwd, pwd->pw_uid, flags) == -1)
+                               err(1, "setusercontext");
+               }
        }
 
        if (chroot(argv[0]) != 0 || chdir("/") != 0)

Reply via email to