Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[CFR] NetBSD's chroot(8) functionality

4 views
Skip to first unread message

Mike Makonnen

unread,
Jun 2, 2003, 3:31:46 AM6/2/03
to
Does anyone have any objections to the following change to chroot(8) (the
program, not the syscall)?

Essentially, it allows the user to set a new uid, group, and/or group list when
invoking chroot(8).

Cheers.
--
Mike Makonnen | GPG-KEY: http://www.identd.net/~mtm/mtm.asc
m...@identd.net | D228 1A6F C64E 120A A1C9 A3AA DAE1 E2AF DBCC 68B9
m...@FreeBSD.Org| FreeBSD - The Power To Serve

Index: usr.sbin/chroot/chroot.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/chroot/chroot.c,v
retrieving revision 1.8
diff -u -r1.8 chroot.c
--- usr.sbin/chroot/chroot.c 3 May 2003 21:06:36 -0000 1.8
+++ usr.sbin/chroot/chroot.c 2 Jun 2003 05:55:53 -0000
@@ -47,8 +47,12 @@

#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 @@

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;
-
- while ((ch = getopt(argc, argv, "")) != -1)
+ struct group *gp;
+ struct passwd *pw;
+ char *endp, *p;
+ const char *shell;
+ gid_t gid, gidlist[NGROUPS_MAX];
+ uid_t uid;
+ int ch, gids;
+
+ 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]) || chroot("."))
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 @@
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);
}
_______________________________________________
freebs...@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-audit
To unsubscribe, send any mail to "freebsd-audi...@freebsd.org"

0 new messages