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