diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-10-29 23:12:07 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-10-29 23:12:07 +0000 |
commit | 2dfe8a3cfa607181206fe10baa4d1909e1026654 (patch) | |
tree | e9bfc069cfa1cda55aa8cab702c8194d1dfe5e02 | |
parent | d74a4133f90addc75d2fac4e3c1489f557ba16c1 (diff) |
Add -U option to set uid, gid, and group vector based on password database.
-rw-r--r-- | usr.sbin/chroot/chroot.8 | 22 | ||||
-rw-r--r-- | usr.sbin/chroot/chroot.c | 49 |
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); } |