On Mon, May 18, 2015 at 04:30:33PM -0600, Todd C. Miller wrote: > 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?
Color me surprised, I just looked at posix, and discovered that chroot is *not* a standard utility. So yeah, that would even make sense to me. > 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. For my use case, everything can be set up as a login session... Note that I would use the chroot -c -u user /directory cmd directly, so there is no login shell involved. > Opinions? Looks fine to me as it currently stands. > - 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)