xref: /freebsd/usr.sbin/jail/jail.c (revision 25639ca722b69a3821bb6622fef795a7138bd3dc)
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