11553Srgrimes/* 21553Srgrimes * Copyright (c) 1988, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 4. Neither the name of the University nor the names of its contributors 141553Srgrimes * may be used to endorse or promote products derived from this software 151553Srgrimes * without specific prior written permission. 161553Srgrimes * 171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271553Srgrimes * SUCH DAMAGE. 281553Srgrimes */ 291553Srgrimes 30114601Sobrien#if 0 311553Srgrimes#ifndef lint 3229448Scharnierstatic const char copyright[] = 331553Srgrimes"@(#) Copyright (c) 1988, 1993\n\ 341553Srgrimes The Regents of the University of California. All rights reserved.\n"; 351553Srgrimes#endif /* not lint */ 361553Srgrimes 371553Srgrimes#ifndef lint 381553Srgrimesstatic char sccsid[] = "@(#)chroot.c 8.1 (Berkeley) 6/9/93"; 39114601Sobrien#endif /* not lint */ 4029448Scharnier#endif 41114601Sobrien#include <sys/cdefs.h> 42114601Sobrien__FBSDID("$FreeBSD$"); 431553Srgrimes 441553Srgrimes#include <sys/types.h> 451553Srgrimes 46115952Smtm#include <ctype.h> 471553Srgrimes#include <err.h> 48115952Smtm#include <grp.h> 49115952Smtm#include <limits.h> 501553Srgrimes#include <paths.h> 51115952Smtm#include <pwd.h> 521553Srgrimes#include <stdio.h> 531553Srgrimes#include <stdlib.h> 541553Srgrimes#include <string.h> 551553Srgrimes#include <unistd.h> 561553Srgrimes 5799800Salfredstatic void usage(void); 581553Srgrimes 591553Srgrimesint 60201387Sedmain(int argc, char *argv[]) 611553Srgrimes{ 62115952Smtm struct group *gp; 63115952Smtm struct passwd *pw; 64227223Sed char *endp, *p, *user, *group, *grouplist; 65115952Smtm const char *shell; 66194494Sbrooks gid_t gid, *gidlist; 67115952Smtm uid_t uid; 68115952Smtm int ch, gids; 69194494Sbrooks long ngroups_max; 701553Srgrimes 71115952Smtm gid = 0; 72115952Smtm uid = 0; 73227223Sed user = group = grouplist = NULL; 74115952Smtm while ((ch = getopt(argc, argv, "G:g:u:")) != -1) { 751553Srgrimes switch(ch) { 76115952Smtm case 'u': 77115952Smtm user = optarg; 78115952Smtm if (*user == '\0') 79115952Smtm usage(); 80115952Smtm break; 81115952Smtm case 'g': 82115952Smtm group = optarg; 83115952Smtm if (*group == '\0') 84115952Smtm usage(); 85115952Smtm break; 86115952Smtm case 'G': 87115952Smtm grouplist = optarg; 88115952Smtm if (*grouplist == '\0') 89115952Smtm usage(); 90115952Smtm break; 911553Srgrimes case '?': 921553Srgrimes default: 931553Srgrimes usage(); 941553Srgrimes } 95115952Smtm } 961553Srgrimes argc -= optind; 971553Srgrimes argv += optind; 981553Srgrimes 991553Srgrimes if (argc < 1) 1001553Srgrimes usage(); 1011553Srgrimes 102115952Smtm if (group != NULL) { 103115952Smtm if (isdigit((unsigned char)*group)) { 104115952Smtm gid = (gid_t)strtoul(group, &endp, 0); 105115952Smtm if (*endp != '\0') 106115952Smtm goto getgroup; 107115952Smtm } else { 108115952Smtm getgroup: 109115952Smtm if ((gp = getgrnam(group)) != NULL) 110115952Smtm gid = gp->gr_gid; 111115952Smtm else 112115952Smtm errx(1, "no such group `%s'", group); 113115952Smtm } 114115952Smtm } 115115952Smtm 116194494Sbrooks ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; 117194494Sbrooks if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL) 118194494Sbrooks err(1, "malloc"); 119115952Smtm for (gids = 0; 120194494Sbrooks (p = strsep(&grouplist, ",")) != NULL && gids < ngroups_max; ) { 121115952Smtm if (*p == '\0') 122115952Smtm continue; 123115952Smtm 124115952Smtm if (isdigit((unsigned char)*p)) { 125115952Smtm gidlist[gids] = (gid_t)strtoul(p, &endp, 0); 126115952Smtm if (*endp != '\0') 127115952Smtm goto getglist; 128115952Smtm } else { 129115952Smtm getglist: 130115952Smtm if ((gp = getgrnam(p)) != NULL) 131115952Smtm gidlist[gids] = gp->gr_gid; 132115952Smtm else 133115952Smtm errx(1, "no such group `%s'", p); 134115952Smtm } 135115952Smtm gids++; 136115952Smtm } 137194494Sbrooks if (p != NULL && gids == ngroups_max) 138115952Smtm errx(1, "too many supplementary groups provided"); 139115952Smtm 140115952Smtm if (user != NULL) { 141115952Smtm if (isdigit((unsigned char)*user)) { 142115952Smtm uid = (uid_t)strtoul(user, &endp, 0); 143115952Smtm if (*endp != '\0') 144115952Smtm goto getuser; 145115952Smtm } else { 146115952Smtm getuser: 147115952Smtm if ((pw = getpwnam(user)) != NULL) 148115952Smtm uid = pw->pw_uid; 149115952Smtm else 150115952Smtm errx(1, "no such user `%s'", user); 151115952Smtm } 152115952Smtm } 153115952Smtm 154115677Smtm if (chdir(argv[0]) == -1 || chroot(".") == -1) 1551553Srgrimes err(1, "%s", argv[0]); 1561553Srgrimes 157115952Smtm if (gids && setgroups(gids, gidlist) == -1) 158115952Smtm err(1, "setgroups"); 159115952Smtm if (group && setgid(gid) == -1) 160115952Smtm err(1, "setgid"); 161115952Smtm if (user && setuid(uid) == -1) 162115952Smtm err(1, "setuid"); 163115952Smtm 1641553Srgrimes if (argv[1]) { 1651553Srgrimes execvp(argv[1], &argv[1]); 1661553Srgrimes err(1, "%s", argv[1]); 1671553Srgrimes } 1681553Srgrimes 1691553Srgrimes if (!(shell = getenv("SHELL"))) 1701553Srgrimes shell = _PATH_BSHELL; 17179452Sbrian execlp(shell, shell, "-i", (char *)NULL); 1721553Srgrimes err(1, "%s", shell); 1731553Srgrimes /* NOTREACHED */ 1741553Srgrimes} 1751553Srgrimes 17629448Scharnierstatic void 177201387Sedusage(void) 1781553Srgrimes{ 179115952Smtm (void)fprintf(stderr, "usage: chroot [-g group] [-G group,group,...] " 180115952Smtm "[-u user] newroot [command]\n"); 1811553Srgrimes exit(1); 1821553Srgrimes} 183