Merge from vendor branch GROFF:
[dragonfly.git] / usr.sbin / jail / jail.c
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 }