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