xref: /freebsd/sys/kern/kern_jail.c (revision 6e8394b8baa7d5d9153ab90de6824bcd19b3b4e1)
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  * $Id: malloc.c,v 1.44 1999/03/28 14:16:05 phk Exp $
10  *
11  */
12 
13 #include <sys/param.h>
14 #include <sys/types.h>
15 #include <sys/kernel.h>
16 #include <sys/systm.h>
17 #include <sys/errno.h>
18 #include <sys/sysproto.h>
19 #include <sys/malloc.h>
20 #include <sys/proc.h>
21 #include <sys/jail.h>
22 #include <sys/socket.h>
23 #include <net/if.h>
24 #include <netinet/in.h>
25 
26 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
27 
28 int
29 jail(p, uap)
30         struct proc *p;
31         struct jail_args /* {
32                 syscallarg(struct jail *) jail;
33         } */ *uap;
34 {
35 	int error;
36 	struct prison *pr;
37 	struct jail j;
38 	struct chroot_args ca;
39 
40 	error = suser(p);
41 	if (error)
42 		return (error);
43 	error = copyin(uap->jail, &j, sizeof j);
44 	if (error)
45 		return (error);
46 	MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
47 	bzero((caddr_t)pr, sizeof *pr);
48 	error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
49 	if (error)
50 		goto bail;
51 	pr->pr_ip = j.ip_number;
52 
53 	ca.path = j.path;
54 	error = chroot(p, &ca);
55 	if (error)
56 		goto bail;
57 
58 	pr->pr_ref++;
59 	p->p_prison = pr;
60 	p->p_flag |= P_JAILED;
61 	return (0);
62 
63 bail:
64 	FREE(pr, M_PRISON);
65 	return (error);
66 }
67 
68 int
69 prison_ip(struct proc *p, int flag, u_int32_t *ip)
70 {
71 	u_int32_t tmp;
72 
73 	if (!p->p_prison)
74 		return (0);
75 	if (flag)
76 		tmp = *ip;
77 	else
78 		tmp = ntohl(*ip);
79 	if (tmp == INADDR_ANY) {
80 		if (flag)
81 			*ip = p->p_prison->pr_ip;
82 		else
83 			*ip = htonl(p->p_prison->pr_ip);
84 		return (0);
85 	}
86 	if (p->p_prison->pr_ip != tmp)
87 		return (1);
88 	return (0);
89 }
90 
91 void
92 prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
93 {
94 	u_int32_t tmp;
95 
96 	if (!p || !p->p_prison)
97 		return;
98 	if (flag)
99 		tmp = *ip;
100 	else
101 		tmp = ntohl(*ip);
102 	if (tmp == 0x7f000001) {
103 		if (flag)
104 			*ip = p->p_prison->pr_ip;
105 		else
106 			*ip = htonl(p->p_prison->pr_ip);
107 		return;
108 	}
109 	return;
110 }
111 
112 int
113 prison_if(struct proc *p, struct sockaddr *sa)
114 {
115 	struct sockaddr_in *sai = (struct sockaddr_in*) sa;
116 	int ok;
117 
118 	if (sai->sin_family != AF_INET)
119 		ok = 0;
120 	else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
121 		ok = 1;
122 	else
123 		ok = 0;
124 	return (ok);
125 }
126