Allow the optional setting of a user, primary group, or grouplist
when chrooting. Obtained from: NetBSD MFC after: 4 weeks
This commit is contained in:
parent
dd1aaed417
commit
5ba88e8391
@ -32,7 +32,7 @@
|
||||
.\" @(#)chroot.8 8.1 (Berkeley) 6/9/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 24, 2002
|
||||
.Dd June 7, 2003
|
||||
.Dt CHROOT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,6 +40,9 @@
|
||||
.Nd change root directory
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl u Ar user
|
||||
.Op Fl g Ar group
|
||||
.Op Fl G Ar group,group,...
|
||||
.Ar newroot
|
||||
.Op Ar command
|
||||
.Sh DESCRIPTION
|
||||
@ -49,7 +52,20 @@ utility changes its current and root directories to the supplied directory
|
||||
.Ar newroot
|
||||
and then exec's
|
||||
.Ar command ,
|
||||
if supplied, or an interactive copy of the user's login shell.
|
||||
if supplied,
|
||||
or an interactive copy of the user's login shell.
|
||||
.Pp
|
||||
If the
|
||||
.Fl u ,
|
||||
.Fl g
|
||||
or
|
||||
.Fl G
|
||||
options are given,
|
||||
the user,
|
||||
group and group list of the process are set to
|
||||
these values after the
|
||||
.Xr chroot 8
|
||||
has taken place.
|
||||
.Sh ENVIRONMENT
|
||||
The following environment variable is referenced by
|
||||
.Nm :
|
||||
@ -69,6 +85,10 @@ is used.
|
||||
.Sh SEE ALSO
|
||||
.Xr chdir 2 ,
|
||||
.Xr chroot 2 ,
|
||||
.Xr setgid 2 ,
|
||||
.Xr setgroups 2 ,
|
||||
.Xr setuid 2 ,
|
||||
.Xr getgrnam 3 ,
|
||||
.Xr environ 7 ,
|
||||
.Xr jail 8
|
||||
.Sh HISTORY
|
||||
|
@ -47,8 +47,12 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -56,29 +60,112 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static void usage(void);
|
||||
|
||||
char *user; /* user to switch to before running program */
|
||||
char *group; /* group to switch to ... */
|
||||
char *grouplist; /* group list to switch to ... */
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int ch;
|
||||
const char *shell;
|
||||
struct group *gp;
|
||||
struct passwd *pw;
|
||||
char *endp, *p;
|
||||
const char *shell;
|
||||
gid_t gid, gidlist[NGROUPS_MAX];
|
||||
uid_t uid;
|
||||
int ch, gids;
|
||||
|
||||
while ((ch = getopt(argc, argv, "")) != -1)
|
||||
gid = 0;
|
||||
uid = 0;
|
||||
while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
|
||||
switch(ch) {
|
||||
case 'u':
|
||||
user = optarg;
|
||||
if (*user == '\0')
|
||||
usage();
|
||||
break;
|
||||
case 'g':
|
||||
group = optarg;
|
||||
if (*group == '\0')
|
||||
usage();
|
||||
break;
|
||||
case 'G':
|
||||
grouplist = optarg;
|
||||
if (*grouplist == '\0')
|
||||
usage();
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
if (group != NULL) {
|
||||
if (isdigit((unsigned char)*group)) {
|
||||
gid = (gid_t)strtoul(group, &endp, 0);
|
||||
if (*endp != '\0')
|
||||
goto getgroup;
|
||||
} else {
|
||||
getgroup:
|
||||
if ((gp = getgrnam(group)) != NULL)
|
||||
gid = gp->gr_gid;
|
||||
else
|
||||
errx(1, "no such group `%s'", group);
|
||||
}
|
||||
}
|
||||
|
||||
for (gids = 0;
|
||||
(p = strsep(&grouplist, ",")) != NULL && gids < NGROUPS_MAX; ) {
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
|
||||
if (isdigit((unsigned char)*p)) {
|
||||
gidlist[gids] = (gid_t)strtoul(p, &endp, 0);
|
||||
if (*endp != '\0')
|
||||
goto getglist;
|
||||
} else {
|
||||
getglist:
|
||||
if ((gp = getgrnam(p)) != NULL)
|
||||
gidlist[gids] = gp->gr_gid;
|
||||
else
|
||||
errx(1, "no such group `%s'", p);
|
||||
}
|
||||
gids++;
|
||||
}
|
||||
if (p != NULL && gids == NGROUPS_MAX)
|
||||
errx(1, "too many supplementary groups provided");
|
||||
|
||||
if (user != NULL) {
|
||||
if (isdigit((unsigned char)*user)) {
|
||||
uid = (uid_t)strtoul(user, &endp, 0);
|
||||
if (*endp != '\0')
|
||||
goto getuser;
|
||||
} else {
|
||||
getuser:
|
||||
if ((pw = getpwnam(user)) != NULL)
|
||||
uid = pw->pw_uid;
|
||||
else
|
||||
errx(1, "no such user `%s'", user);
|
||||
}
|
||||
}
|
||||
|
||||
if (chdir(argv[0]) == -1 || chroot(".") == -1)
|
||||
err(1, "%s", argv[0]);
|
||||
|
||||
if (gids && setgroups(gids, gidlist) == -1)
|
||||
err(1, "setgroups");
|
||||
if (group && setgid(gid) == -1)
|
||||
err(1, "setgid");
|
||||
if (user && setuid(uid) == -1)
|
||||
err(1, "setuid");
|
||||
|
||||
if (argv[1]) {
|
||||
execvp(argv[1], &argv[1]);
|
||||
err(1, "%s", argv[1]);
|
||||
@ -94,6 +181,7 @@ main(argc, argv)
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: chroot newroot [command]\n");
|
||||
(void)fprintf(stderr, "usage: chroot [-g group] [-G group,group,...] "
|
||||
"[-u user] newroot [command]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user