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 * ----------------------------------------------------------------------------
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.8 2007/01/17 11:37:48 victor Exp $
14 #include <sys/param.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
23 #include <login_cap.h>
31 static void usage(void);
32 extern char **environ
;
34 #define GET_USER_INFO do { \
35 pwd = getpwnam(username); \
38 err(1, "getpwnam: %s", username); \
40 errx(1, "%s: no such user", username); \
42 lcap = login_getpwclass(pwd); \
44 err(1, "getpwclass: %s", username); \
46 if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \
47 err(1, "getgrouplist: %s", username); \
51 main(int argc
, char **argv
)
53 login_cap_t
*lcap
= NULL
;
55 struct sockaddr_in
*sin4
;
56 struct sockaddr_in6
*sin6
;
57 struct passwd
*pwd
= NULL
;
58 gid_t groups
[NGROUPS
];
59 int ch
, ngroups
, i
, iflag
, lflag
, uflag
, Uflag
;
60 static char *cleanenv
;
61 const char *shell
, *p
= NULL
;
62 char path
[PATH_MAX
], *username
, *curpos
;
64 iflag
= lflag
= uflag
= Uflag
= 0;
66 j
.ips
= malloc(sizeof(struct sockaddr_storage
)*20);
67 bzero(j
.ips
, sizeof(struct sockaddr_storage
)*20);
69 while ((ch
= getopt(argc
, argv
, "ilu:U:")) != -1)
95 if (lflag
&& username
== NULL
)
99 if (realpath(argv
[0], path
) == NULL
)
100 err(1, "realpath: %s", argv
[0]);
101 if (chdir(path
) != 0)
102 err(1, "chdir: %s", path
);
106 j
.hostname
= argv
[1];
107 curpos
= strtok(argv
[2], ",");
108 for (i
=0; curpos
!= NULL
; i
++) {
109 if (i
&& i
%20 == 0) {
110 if ( (j
.ips
= realloc(j
.ips
, sizeof(struct sockaddr_storage
)*i
+20)) == NULL
) {
111 perror("Can't allocate memory");
116 sin4
= (struct sockaddr_in
*)(j
.ips
+i
);
117 sin6
= (struct sockaddr_in6
*)(j
.ips
+i
);
119 if (inet_pton(AF_INET
, curpos
, &sin4
->sin_addr
) == 1) {
120 sin4
->sin_family
= AF_INET
;
122 if (inet_pton(AF_INET6
, curpos
, &sin6
->sin6_addr
) == 1) {
123 sin6
->sin6_family
= AF_INET6
;
125 printf("Invalid value %s\n", curpos
);
129 curpos
= strtok(NULL
, ",");
140 if (username
!= NULL
) {
147 if (setgroups(ngroups
, groups
) != 0)
149 if (setgid(pwd
->pw_gid
) != 0)
151 if (setusercontext(lcap
, pwd
, pwd
->pw_uid
,
152 LOGIN_SETALL
& ~LOGIN_SETGROUP
) != 0)
153 err(1, "setusercontext");
158 shell
= pwd
->pw_shell
;
160 shell
= _PATH_BSHELL
;
161 if (chdir(pwd
->pw_dir
) < 0)
162 errx(1, "no home directory");
163 setenv("HOME", pwd
->pw_dir
, 1);
164 setenv("SHELL", shell
, 1);
165 setenv("USER", pwd
->pw_name
, 1);
167 setenv("TERM", p
, 1);
169 if (execv(argv
[3], argv
+ 3) != 0)
170 err(1, "execv: %s", argv
[3]);
178 fprintf(stderr
, "%s\n",
179 "Usage: jail [-i] [-l -u username | -U username] path hostname ip-list command ...");