diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-02-08 21:37:05 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-02-08 21:37:05 +0000 |
commit | ed17a83d1f8476babc9fb8088a2010f25d483e77 (patch) | |
tree | 207fb348248fc8f085e670187c6e1898e543eda6 /usr.sbin | |
parent | 723af9aa885aa823971664dfd58d412118c1c5d1 (diff) |
Make the -u and -g options more like the -U and -G options. My intention
was to avoid needless incompatibilities with NetBSD's command line options
but this ended up causing too much confusion on the part of the user.
The -u option now also sets the group and group vector based on passwd(5)
and group(5) unless an alternate group list is specified via the -g option.
The -U and -G options have been removed.
The resulting code is much simpler and the behavior of chroot(8) seems
to better match users' expectations; OK deraadt@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/chroot/chroot.8 | 53 | ||||
-rw-r--r-- | usr.sbin/chroot/chroot.c | 136 |
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); } |