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)