xref: /dragonfly/usr.sbin/jail/jail.c (revision 49781055)
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  * $FreeBSD: src/usr.sbin/jail/jail.c,v 1.5.2.2 2003/05/08 13:04:24 maxim Exp $
10  * $DragonFly: src/usr.sbin/jail/jail.c,v 1.4 2004/12/18 22:48:03 swildner Exp $
11  *
12  */
13 
14 #include <sys/param.h>
15 #include <sys/jail.h>
16 
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 
20 #include <err.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 
29 static void	usage(void);
30 
31 int
32 main(int argc, char **argv)
33 {
34 	login_cap_t *lcap = NULL;
35 	struct jail j;
36 	struct passwd *pwd = NULL;
37 	struct in_addr in;
38 	gid_t groups[NGROUPS];
39 	int ch, ngroups;
40 	char *username;
41 
42 	username = NULL;
43 
44 	while ((ch = getopt(argc, argv, "u:")) != -1)
45 		switch (ch) {
46 		case 'u':
47 			username = optarg;
48 			break;
49 		default:
50 			usage();
51 			break;
52 		}
53 	argc -= optind;
54 	argv += optind;
55 	if (argc < 4)
56 		usage();
57 
58 	if (username != NULL) {
59 		pwd = getpwnam(username);
60 		if (pwd == NULL)
61 			err(1, "getpwnam: %s", username);
62 		lcap = login_getpwclass(pwd);
63 		if (lcap == NULL)
64 			err(1, "getpwclass: %s", username);
65 		ngroups = NGROUPS;
66 		if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0)
67 			err(1, "getgrouplist: %s", username);
68 	}
69 	if (chdir(argv[0]) != 0)
70 		err(1, "chdir: %s", argv[0]);
71 	memset(&j, 0, sizeof(j));
72 	j.version = 0;
73 	j.path = argv[0];
74 	j.hostname = argv[1];
75 	if (inet_aton(argv[2], &in) == 0)
76 		errx(1, "Could not make sense of ip-number: %s", argv[2]);
77 	j.ip_number = ntohl(in.s_addr);
78 	if (jail(&j) != 0)
79 		err(1, "jail");
80 	if (username != NULL) {
81 		if (setgroups(ngroups, groups) != 0)
82 			err(1, "setgroups");
83 		if (setgid(pwd->pw_gid) != 0)
84 			err(1, "setgid");
85 		if (setusercontext(lcap, pwd, pwd->pw_uid,
86 		    LOGIN_SETALL & ~LOGIN_SETGROUP) != 0)
87 			err(1, "setusercontext");
88 		login_close(lcap);
89 	}
90 	if (execv(argv[3], argv + 3) != 0)
91 		err(1, "execv: %s", argv[3]);
92 	exit (0);
93 }
94 
95 static void
96 usage(void)
97 {
98 
99 	fprintf(stderr, "%s\n",
100 	    "Usage: jail [-u username] path hostname ip-number command ...");
101 	exit(1);
102 }
103