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; 37b026ec0eSMaxim Konovalov int ch, groups[NGROUPS], ngroups; 38d6131f4bSMaxim Konovalov char *username; 3975c13541SPoul-Henning Kamp 40d6131f4bSMaxim Konovalov username = NULL; 41d6131f4bSMaxim Konovalov 42d6131f4bSMaxim Konovalov while ((ch = getopt(argc, argv, "u:")) != -1) 43d6131f4bSMaxim Konovalov switch (ch) { 44d6131f4bSMaxim Konovalov case 'u': 45d6131f4bSMaxim Konovalov username = optarg; 46d6131f4bSMaxim Konovalov break; 47d6131f4bSMaxim Konovalov default: 48d6131f4bSMaxim Konovalov usage(); 49d6131f4bSMaxim Konovalov break; 50d6131f4bSMaxim Konovalov } 51d6131f4bSMaxim Konovalov argc -= optind; 52d6131f4bSMaxim Konovalov argv += optind; 53d6131f4bSMaxim Konovalov if (argc < 4) 54d6131f4bSMaxim Konovalov usage(); 55d6131f4bSMaxim Konovalov 56d6131f4bSMaxim Konovalov if (username != NULL) { 57d6131f4bSMaxim Konovalov pwd = getpwnam(username); 58d6131f4bSMaxim Konovalov if (pwd == NULL) 59b026ec0eSMaxim Konovalov err(1, "getpwnam: %s", username); 60d6131f4bSMaxim Konovalov lcap = login_getpwclass(pwd); 61d6131f4bSMaxim Konovalov if (lcap == NULL) 62b026ec0eSMaxim Konovalov err(1, "getpwclass: %s", username); 63d6131f4bSMaxim Konovalov ngroups = NGROUPS; 64b026ec0eSMaxim Konovalov if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) 65b026ec0eSMaxim Konovalov err(1, "getgrouplist: %s", username); 66d6131f4bSMaxim Konovalov } 67b026ec0eSMaxim Konovalov if (chdir(argv[0]) != 0) 68b026ec0eSMaxim Konovalov err(1, "chdir: %s", argv[0]); 697248ef86SPoul-Henning Kamp memset(&j, 0, sizeof(j)); 707248ef86SPoul-Henning Kamp j.version = 0; 71d6131f4bSMaxim Konovalov j.path = argv[0]; 72d6131f4bSMaxim Konovalov j.hostname = argv[1]; 73b026ec0eSMaxim Konovalov if (inet_aton(argv[2], &in) == 0) 74b026ec0eSMaxim Konovalov errx(1, "Could not make sense of ip-number: %s", argv[2]); 75ce5c1cd1SPoul-Henning Kamp j.ip_number = ntohl(in.s_addr); 76b026ec0eSMaxim Konovalov if (jail(&j) != 0) 77b026ec0eSMaxim Konovalov err(1, "jail"); 78d6131f4bSMaxim Konovalov if (username != NULL) { 79b026ec0eSMaxim Konovalov if (setgroups(ngroups, groups) != 0) 80b026ec0eSMaxim Konovalov err(1, "setgroups"); 81b026ec0eSMaxim Konovalov if (setgid(pwd->pw_gid) != 0) 82b026ec0eSMaxim Konovalov err(1, "setgid"); 83b026ec0eSMaxim Konovalov if (setusercontext(lcap, pwd, pwd->pw_uid, 84b026ec0eSMaxim Konovalov LOGIN_SETALL & ~LOGIN_SETGROUP) != 0) 85b026ec0eSMaxim Konovalov err(1, "setusercontext"); 86d6131f4bSMaxim Konovalov } 87b026ec0eSMaxim Konovalov if (execv(argv[3], argv + 3) != 0) 88b026ec0eSMaxim Konovalov err(1, "execv: %s", argv[3]); 8975c13541SPoul-Henning Kamp exit (0); 9075c13541SPoul-Henning Kamp } 91d6131f4bSMaxim Konovalov 92d6131f4bSMaxim Konovalov static void 93d6131f4bSMaxim Konovalov usage(void) 94d6131f4bSMaxim Konovalov { 95d6131f4bSMaxim Konovalov 96b026ec0eSMaxim Konovalov (void)fprintf(stderr, "%s\n", 97d6131f4bSMaxim Konovalov "Usage: jail [-u username] path hostname ip-number command ..."); 98b026ec0eSMaxim Konovalov exit(1); 99d6131f4bSMaxim Konovalov } 100