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)