summaryrefslogtreecommitdiff
path: root/usr.sbin/chroot
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/chroot')
-rw-r--r--usr.sbin/chroot/chroot.853
-rw-r--r--usr.sbin/chroot/chroot.c136
2 files changed, 60 insertions, 129 deletions
diff --git a/usr.sbin/chroot/chroot.8 b/usr.sbin/chroot/chroot.8
index 7ee39c65eed..77e34f67bd6 100644
--- a/usr.sbin/chroot/chroot.8
+++ b/usr.sbin/chroot/chroot.8
@@ -1,5 +1,4 @@
-.\" $OpenBSD: chroot.8,v 1.9 2003/02/01 16:29:52 jmc Exp $
-.\" $NetBSD: chroot.8,v 1.9 2000/08/17 12:36:32 mrg Exp $
+.\" $OpenBSD: chroot.8,v 1.10 2003/02/08 21:37:04 millert Exp $
.\"
.\" Copyright (c) 1988, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -34,7 +33,7 @@
.\"
.\" from: @(#)chroot.8 8.1 (Berkeley) 6/9/93
.\"
-.Dd October 25, 2002
+.Dd February 7, 2003
.Dt CHROOT 8
.Os
.Sh NAME
@@ -43,9 +42,7 @@
.Sh SYNOPSIS
.Nm chroot
.Op Fl u Ar user
-.Op Fl U Ar user
-.Op Fl g Ar group
-.Op Fl G Ar group,group,...
+.Op Fl g Ar group,group,...
.Ar newroot
.Op Ar command
.Sh DESCRIPTION
@@ -66,32 +63,24 @@ The options are as follows:
.It Fl u Ar user
Set user ID to
.Ar user
-(a user name or user ID).
-.It Fl U Ar user
-Set user, group and supplemental group IDs based on the
+(which must exist in the
.Xr passwd 5
-database entry for
-.Ar user .
-The
-.Fl U
-option may not be specified in conjunction with any other options.
-.It Fl g Ar group
-Set group ID to
-.Ar group
-(a group name or group ID).
-If supplemental groups are specified via the
-.Fl G
-flag,
-.Ar group
-will be used as the first entry in the group vector.
+database).
+The primary and supplemental group IDs will be set based on the user's
+entries in the
+.Xr passwd 5
+and
+.Xr group 5
+databases unless overridden by the
+.Fl g
+option.
.It Fl G Ar group,group,...
-Set the supplemental group IDs to a comma-separated list of
-group names or group IDs.
-If neither the
-.Fl G
-nor the
-.Fl U
-option is specified, the supplemental group list remains unchanged.
+Override the primary and supplemental group IDs.
+The primary group ID is set to the first group in the list.
+Any remaining groups are placed in the supplemental group ID vector.
+Each group listed must exist in the
+.Xr group 5
+databases.
.El
.Sh ENVIRONMENT
.Bl -tag -width SHELL
@@ -113,8 +102,8 @@ is used.
.Xr setgid 2 ,
.Xr setgroups 2 ,
.Xr setuid 2 ,
-.Xr getgrnam 3 ,
-.Xr getpwnam 3 ,
+.Xr group 5 ,
+.Xr passwd 5 ,
.Xr environ 7
.Sh HISTORY
The
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
index b22cacb6d3c..663d3d6ba44 100644
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -1,5 +1,4 @@
-/* $OpenBSD: chroot.c,v 1.8 2002/12/22 22:25:20 millert Exp $ */
-/* $NetBSD: chroot.c,v 1.11 2001/04/06 02:34:04 lukem Exp $ */
+/* $OpenBSD: chroot.c,v 1.9 2003/02/08 21:37:04 millert Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -45,7 +44,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)chroot.c 8.1 (Berkeley) 6/9/93";
#else
-static const char rcsid[] = "$OpenBSD: chroot.c,v 1.8 2002/12/22 22:25:20 millert Exp $";
+static const char rcsid[] = "$OpenBSD: chroot.c,v 1.9 2003/02/08 21:37:04 millert Exp $";
#endif
#endif /* not lint */
@@ -67,43 +66,28 @@ __dead void usage(void);
int
main(int argc, char **argv)
{
- struct group *gp;
+ struct group *grp;
struct passwd *pwd;
const char *shell;
- char *fulluser, *user, *group, *grouplist, *endp, *p;
- gid_t gid, gidlist[NGROUPS_MAX];
- uid_t uid;
- int ch, gids;
- unsigned long ul;
-
- gid = 0;
- uid = 0;
- gids = 0;
+ char *user, *group, *grouplist;
+ gid_t gidlist[NGROUPS_MAX];
+ int ch, ngids;
+
+ ngids = 0;
pwd = NULL;
- user = fulluser = group = grouplist = NULL;
- while ((ch = getopt(argc, argv, "G:g:U:u:")) != -1) {
+ user = grouplist = NULL;
+ while ((ch = getopt(argc, argv, "g:u:")) != -1) {
switch(ch) {
- case 'U':
- fulluser = optarg;
- if (*fulluser == '\0')
- usage();
- break;
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();
}
@@ -113,87 +97,45 @@ main(int argc, char **argv)
if (argc < 1)
usage();
- if (fulluser && (user || group || grouplist))
- errx(1,
- "the -U option may not be specified with any other option");
-
- if (group != NULL) {
- if ((gp = getgrnam(group)) != NULL)
- gid = gp->gr_gid;
- else if (isdigit((unsigned char)*group)) {
- errno = 0;
- ul = strtoul(group, &endp, 10);
- if (*endp != '\0' ||
- (ul == ULONG_MAX && errno == ERANGE))
- errx(1, "invalid group ID `%s'", group);
- gid = (gid_t)ul;
- } else
- errx(1, "no such group `%s'", group);
- if (grouplist != NULL)
- gidlist[gids++] = gid;
- if (setgid(gid) != 0)
- err(1, "setgid");
- }
- while ((p = strsep(&grouplist, ",")) != NULL && gids < NGROUPS_MAX) {
- if (*p == '\0')
+ if (user != NULL && (pwd = getpwnam(user)) == NULL)
+ errx(1, "no such user `%s'", user);
+
+ while ((group = strsep(&grouplist, ",")) != NULL) {
+ if (*group == '\0')
continue;
- if ((gp = getgrnam(p)) != NULL)
- gidlist[gids] = gp->gr_gid;
- else if (isdigit((unsigned char)*p)) {
- errno = 0;
- ul = strtoul(p, &endp, 10);
- if (*endp != '\0' ||
- (ul == ULONG_MAX && errno == ERANGE))
- errx(1, "invalid group ID `%s'", p);
- gidlist[gids] = (gid_t)ul;
- } else
- errx(1, "no such group `%s'", p);
- /*
- * Ignore primary group if specified; we already added it above.
- */
- if (group == NULL || gidlist[gids] != gid)
- gids++;
- }
- if (p != NULL && gids == NGROUPS_MAX)
- errx(1, "too many supplementary groups provided");
- if (gids && setgroups(gids, gidlist) != 0)
- err(1, "setgroups");
-
- if (user != NULL) {
- if ((pwd = getpwnam(user)) != NULL)
- uid = pwd->pw_uid;
- else if (isdigit((unsigned char)*user)) {
- errno = 0;
- ul = strtoul(user, &endp, 10);
- if (*endp != '\0' ||
- (ul == ULONG_MAX && errno == ERANGE))
- errx(1, "invalid user ID `%s'", user);
- uid = (uid_t)ul;
- } else
- errx(1, "no such user `%s'", user);
+ if (ngids == NGROUPS_MAX)
+ errx(1, "too many supplementary groups provided");
+ if ((grp = getgrnam(group)) == NULL)
+ errx(1, "no such group `%s'", group);
+ gidlist[ngids++] = grp->gr_gid;
}
- if (fulluser != NULL) {
- if ((pwd = getpwnam(fulluser)) == NULL)
- errx(1, "no such user `%s'", fulluser);
- uid = pwd->pw_uid;
- gid = pwd->pw_gid;
- if (setgid(gid) != 0)
+ if (ngids != 0) {
+ if (setgid(gidlist[0]) != 0)
err(1, "setgid");
- if (initgroups(fulluser, gid) == -1)
+ if (setgroups(ngids, gidlist) != 0)
+ err(1, "setgroups");
+ } else if (pwd != NULL) {
+ if (setgid(pwd->pw_gid) != 0)
+ err(1, "setgid");
+ if (initgroups(user, pwd->pw_gid) == -1)
err(1, "initgroups");
}
- if (pwd != NULL && (getsid(0) == getpid() || setsid() != -1))
- setlogin(pwd->pw_name);
-
if (chroot(argv[0]) != 0 || chdir("/") != 0)
err(1, "%s", argv[0]);
- if ((user || fulluser) && setuid(uid) != 0)
- err(1, "setuid");
+ if (pwd != NULL) {
+ /* only set login name if we are/can be a session leader */
+ if (getsid(0) == getpid() || setsid() != -1)
+ setlogin(pwd->pw_name);
+ if (setuid(pwd->pw_uid) != 0)
+ err(1, "setuid");
+ endgrent();
+ endpwent();
+ }
if (argv[1]) {
execvp(argv[1], &argv[1]);
@@ -212,7 +154,7 @@ usage(void)
{
extern char *__progname;
- (void)fprintf(stderr, "usage: %s [-g group] [-G group,group,...] "
- "[-u user] [-U user] newroot [command]\n", __progname);
+ (void)fprintf(stderr, "usage: %s [-g group,group,...] [-u user] "
+ "newroot [command]\n", __progname);
exit(1);
}