summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2002-10-29 23:12:07 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2002-10-29 23:12:07 +0000
commit2dfe8a3cfa607181206fe10baa4d1909e1026654 (patch)
treee9bfc069cfa1cda55aa8cab702c8194d1dfe5e02
parentd74a4133f90addc75d2fac4e3c1489f557ba16c1 (diff)
Add -U option to set uid, gid, and group vector based on password database.
-rw-r--r--usr.sbin/chroot/chroot.822
-rw-r--r--usr.sbin/chroot/chroot.c49
2 files changed, 52 insertions, 19 deletions
diff --git a/usr.sbin/chroot/chroot.8 b/usr.sbin/chroot/chroot.8
index 03202d202ce..87f78675d87 100644
--- a/usr.sbin/chroot/chroot.8
+++ b/usr.sbin/chroot/chroot.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: chroot.8,v 1.7 2002/10/25 19:23:48 millert Exp $
+.\" $OpenBSD: chroot.8,v 1.8 2002/10/29 23:12:06 millert Exp $
.\" $NetBSD: chroot.8,v 1.9 2000/08/17 12:36:32 mrg Exp $
.\"
.\" Copyright (c) 1988, 1991, 1993
@@ -43,6 +43,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,...
.Ar newroot
@@ -66,6 +67,14 @@ The options are as follows:
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
+.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
@@ -78,13 +87,12 @@ will be the used as the first entry in the group vector.
.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.
.El
-.Pp
-Note, the
-.Ar command
-or shell are run with the real user ID of the invoking user unless the
-.Fl u
-flag is specified.
.Sh ENVIRONMENT
.Bl -tag -width SHELL
.It Ev SHELL
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
index 52f6f1f5518..fe362b06ebc 100644
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: chroot.c,v 1.6 2002/10/25 19:23:48 millert Exp $ */
+/* $OpenBSD: chroot.c,v 1.7 2002/10/29 23:12:06 millert Exp $ */
/* $NetBSD: chroot.c,v 1.11 2001/04/06 02:34:04 lukem Exp $ */
/*
@@ -45,7 +45,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.6 2002/10/25 19:23:48 millert Exp $";
+static const char rcsid[] = "$OpenBSD: chroot.c,v 1.7 2002/10/29 23:12:06 millert Exp $";
#endif
#endif /* not lint */
@@ -70,16 +70,23 @@ main(int argc, char **argv)
struct group *gp;
struct passwd *pw;
const char *shell;
- char *user, *group, *grouplist, *endp, *p;
+ 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;
- user = group = grouplist = NULL;
- while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
+ user = fulluser = group = grouplist = NULL;
+ while ((ch = getopt(argc, argv, "G:g:U:u:")) != -1) {
switch(ch) {
+ case 'U':
+ fulluser = optarg;
+ if (*fulluser == '\0')
+ usage();
+ break;
case 'u':
user = optarg;
if (*user == '\0')
@@ -105,6 +112,9 @@ 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)
@@ -120,6 +130,8 @@ main(int argc, char **argv)
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) {
@@ -137,10 +149,16 @@ main(int argc, char **argv)
gidlist[gids] = (gid_t)ul;
} else
errx(1, "no such group `%s'", p);
- gids++;
+ /*
+ * 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 ((pw = getpwnam(user)) != NULL)
@@ -156,14 +174,21 @@ main(int argc, char **argv)
errx(1, "no such user `%s'", user);
}
+ if (fulluser != NULL) {
+ if ((pw = getpwnam(fulluser)) == NULL)
+ errx(1, "no such user `%s'", fulluser);
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ if (setgid(gid) != 0)
+ err(1, "setgid");
+ if (initgroups(fulluser, gid) == -1)
+ err(1, "initgroups");
+ }
+
if (chroot(argv[0]) != 0 || chdir("/") != 0)
err(1, "%s", argv[0]);
- if (gids && setgroups(gids, gidlist) != 0)
- err(1, "setgroups");
- if (group && setgid(gid) != 0)
- err(1, "setgid");
- if (user && setuid(uid) != 0)
+ if ((user || fulluser) && setuid(uid) != 0)
err(1, "setuid");
if (argv[1]) {
@@ -184,6 +209,6 @@ usage(void)
extern char *__progname;
(void)fprintf(stderr, "usage: %s [-g group] [-G group,group,...] "
- "[-u user] newroot [command]\n", __progname);
+ "[-u user] [-U user] newroot [command]\n", __progname);
exit(1);
}