1ce5c1cd1SPoul-Henning Kamp /* 2ce5c1cd1SPoul-Henning Kamp * ---------------------------------------------------------------------------- 3ce5c1cd1SPoul-Henning Kamp * "THE BEER-WARE LICENSE" (Revision 42): 4ce5c1cd1SPoul-Henning Kamp * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5ce5c1cd1SPoul-Henning Kamp * can do whatever you want with this stuff. If we meet some day, and you think 6ce5c1cd1SPoul-Henning Kamp * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7ce5c1cd1SPoul-Henning Kamp * ---------------------------------------------------------------------------- 8ce5c1cd1SPoul-Henning Kamp * 997d92980SPeter Wemm * $FreeBSD$ 10ce5c1cd1SPoul-Henning Kamp * 11ce5c1cd1SPoul-Henning Kamp */ 12ce5c1cd1SPoul-Henning Kamp 13d6131f4bSMaxim Konovalov #include <sys/param.h> 143876038aSDima Dorfman #include <sys/jail.h> 153876038aSDima Dorfman 163876038aSDima Dorfman #include <netinet/in.h> 173876038aSDima Dorfman #include <arpa/inet.h> 183876038aSDima Dorfman 193876038aSDima Dorfman #include <err.h> 20d6131f4bSMaxim Konovalov #include <grp.h> 21d6131f4bSMaxim Konovalov #include <login_cap.h> 22d6131f4bSMaxim Konovalov #include <pwd.h> 2375c13541SPoul-Henning Kamp #include <stdio.h> 242694efd4SDima Dorfman #include <stdlib.h> 252694efd4SDima Dorfman #include <string.h> 263876038aSDima Dorfman #include <unistd.h> 2775c13541SPoul-Henning Kamp 28d6131f4bSMaxim Konovalov static void usage(void); 29d6131f4bSMaxim Konovalov 3075c13541SPoul-Henning Kamp int 3175c13541SPoul-Henning Kamp main(int argc, char **argv) 3275c13541SPoul-Henning Kamp { 33d6131f4bSMaxim Konovalov login_cap_t *lcap; 3475c13541SPoul-Henning Kamp struct jail j; 35d6131f4bSMaxim Konovalov struct passwd *pwd; 3675c13541SPoul-Henning Kamp struct in_addr in; 37ebf5d9bcSMike Barcroft int ch, groups[NGROUPS], i, iflag, ngroups; 38d6131f4bSMaxim Konovalov char *username; 3975c13541SPoul-Henning Kamp 40ebf5d9bcSMike Barcroft iflag = 0; 41d6131f4bSMaxim Konovalov username = NULL; 42d6131f4bSMaxim Konovalov 43ebf5d9bcSMike Barcroft while ((ch = getopt(argc, argv, "iu:")) != -1) { 44d6131f4bSMaxim Konovalov switch (ch) { 45ebf5d9bcSMike Barcroft case 'i': 46ebf5d9bcSMike Barcroft iflag = 1; 47ebf5d9bcSMike Barcroft break; 48d6131f4bSMaxim Konovalov case 'u': 49d6131f4bSMaxim Konovalov username = optarg; 50d6131f4bSMaxim Konovalov break; 51d6131f4bSMaxim Konovalov default: 52d6131f4bSMaxim Konovalov usage(); 53ebf5d9bcSMike Barcroft } 54d6131f4bSMaxim Konovalov } 55d6131f4bSMaxim Konovalov argc -= optind; 56d6131f4bSMaxim Konovalov argv += optind; 57d6131f4bSMaxim Konovalov if (argc < 4) 58d6131f4bSMaxim Konovalov usage(); 59d6131f4bSMaxim Konovalov 60d6131f4bSMaxim Konovalov if (username != NULL) { 61d6131f4bSMaxim Konovalov pwd = getpwnam(username); 62d6131f4bSMaxim Konovalov if (pwd == NULL) 63b026ec0eSMaxim Konovalov err(1, "getpwnam: %s", username); 64d6131f4bSMaxim Konovalov lcap = login_getpwclass(pwd); 65d6131f4bSMaxim Konovalov if (lcap == NULL) 66b026ec0eSMaxim Konovalov err(1, "getpwclass: %s", username); 67d6131f4bSMaxim Konovalov ngroups = NGROUPS; 68b026ec0eSMaxim Konovalov if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) 69b026ec0eSMaxim Konovalov err(1, "getgrouplist: %s", username); 70d6131f4bSMaxim Konovalov } 71b026ec0eSMaxim Konovalov if (chdir(argv[0]) != 0) 72b026ec0eSMaxim Konovalov err(1, "chdir: %s", argv[0]); 737248ef86SPoul-Henning Kamp memset(&j, 0, sizeof(j)); 747248ef86SPoul-Henning Kamp j.version = 0; 75d6131f4bSMaxim Konovalov j.path = argv[0]; 76d6131f4bSMaxim Konovalov j.hostname = argv[1]; 77b026ec0eSMaxim Konovalov if (inet_aton(argv[2], &in) == 0) 78b026ec0eSMaxim Konovalov errx(1, "Could not make sense of ip-number: %s", argv[2]); 79ce5c1cd1SPoul-Henning Kamp j.ip_number = ntohl(in.s_addr); 80ebf5d9bcSMike Barcroft i = jail(&j); 81ebf5d9bcSMike Barcroft if (i == -1) 82b026ec0eSMaxim Konovalov err(1, "jail"); 8325639ca7SMike Barcroft if (iflag) { 84ebf5d9bcSMike Barcroft printf("%d\n", i); 8525639ca7SMike Barcroft fflush(stdout); 8625639ca7SMike Barcroft } 87d6131f4bSMaxim Konovalov if (username != NULL) { 88b026ec0eSMaxim Konovalov if (setgroups(ngroups, groups) != 0) 89b026ec0eSMaxim Konovalov err(1, "setgroups"); 90b026ec0eSMaxim Konovalov if (setgid(pwd->pw_gid) != 0) 91b026ec0eSMaxim Konovalov err(1, "setgid"); 92b026ec0eSMaxim Konovalov if (setusercontext(lcap, pwd, pwd->pw_uid, 93b026ec0eSMaxim Konovalov LOGIN_SETALL & ~LOGIN_SETGROUP) != 0) 94b026ec0eSMaxim Konovalov err(1, "setusercontext"); 950389572fSMaxim Konovalov login_close(lcap); 96d6131f4bSMaxim Konovalov } 97b026ec0eSMaxim Konovalov if (execv(argv[3], argv + 3) != 0) 98b026ec0eSMaxim Konovalov err(1, "execv: %s", argv[3]); 9975c13541SPoul-Henning Kamp exit(0); 10075c13541SPoul-Henning Kamp } 101d6131f4bSMaxim Konovalov 102d6131f4bSMaxim Konovalov static void 103d6131f4bSMaxim Konovalov usage(void) 104d6131f4bSMaxim Konovalov { 105d6131f4bSMaxim Konovalov 106ebf5d9bcSMike Barcroft (void)fprintf(stderr, 107ebf5d9bcSMike Barcroft "usage: jail [-i] [-u username] path hostname ip-number command ...\n"); 108b026ec0eSMaxim Konovalov exit(1); 109d6131f4bSMaxim Konovalov } 110