jail.c revision 129848
1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 */ 9 10#include <sys/cdefs.h> 11__FBSDID("$FreeBSD: head/usr.sbin/jail/jail.c 129848 2004-05-29 18:39:27Z maxim $"); 12 13#include <sys/param.h> 14#include <sys/jail.h> 15 16#include <netinet/in.h> 17#include <arpa/inet.h> 18 19#include <err.h> 20#include <errno.h> 21#include <grp.h> 22#include <login_cap.h> 23#include <pwd.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28 29static void usage(void); 30 31#define GET_USER_INFO do { \ 32 pwd = getpwnam(username); \ 33 if (pwd == NULL) { \ 34 if (errno) \ 35 err(1, "getpwnam: %s", username); \ 36 else \ 37 errx(1, "%s: no such user", username); \ 38 } \ 39 lcap = login_getpwclass(pwd); \ 40 if (lcap == NULL) \ 41 err(1, "getpwclass: %s", username); \ 42 ngroups = NGROUPS; \ 43 if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \ 44 err(1, "getgrouplist: %s", username); \ 45} while (0) 46 47int 48main(int argc, char **argv) 49{ 50 login_cap_t *lcap; 51 struct jail j; 52 struct passwd *pwd; 53 struct in_addr in; 54 int ch, groups[NGROUPS], i, iflag, ngroups, uflag, Uflag; 55 char *username; 56 57 iflag = uflag = Uflag = 0; 58 username = NULL; 59 60 while ((ch = getopt(argc, argv, "iu:U:")) != -1) { 61 switch (ch) { 62 case 'i': 63 iflag = 1; 64 break; 65 case 'u': 66 username = optarg; 67 uflag = 1; 68 break; 69 case 'U': 70 username = optarg; 71 Uflag = 1; 72 break; 73 default: 74 usage(); 75 } 76 } 77 argc -= optind; 78 argv += optind; 79 if (argc < 4) 80 usage(); 81 if (uflag && Uflag) 82 usage(); 83 if (uflag) 84 GET_USER_INFO; 85 if (chdir(argv[0]) != 0) 86 err(1, "chdir: %s", argv[0]); 87 memset(&j, 0, sizeof(j)); 88 j.version = 0; 89 j.path = argv[0]; 90 j.hostname = argv[1]; 91 if (inet_aton(argv[2], &in) == 0) 92 errx(1, "Could not make sense of ip-number: %s", argv[2]); 93 j.ip_number = ntohl(in.s_addr); 94 i = jail(&j); 95 if (i == -1) 96 err(1, "jail"); 97 if (iflag) { 98 printf("%d\n", i); 99 fflush(stdout); 100 } 101 if (username != NULL) { 102 if (Uflag) 103 GET_USER_INFO; 104 if (setgroups(ngroups, groups) != 0) 105 err(1, "setgroups"); 106 if (setgid(pwd->pw_gid) != 0) 107 err(1, "setgid"); 108 if (setusercontext(lcap, pwd, pwd->pw_uid, 109 LOGIN_SETALL & ~LOGIN_SETGROUP) != 0) 110 err(1, "setusercontext"); 111 login_close(lcap); 112 } 113 if (execv(argv[3], argv + 3) != 0) 114 err(1, "execv: %s", argv[3]); 115 exit(0); 116} 117 118static void 119usage(void) 120{ 121 122 (void)fprintf(stderr, "%s%s\n", 123 "usage: jail [-i] [-u username | -U username]", 124 " path hostname ip-number command ..."); 125 exit(1); 126} 127