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)

Reply via email to