kern_jail.c revision 57163
1227825Stheraven/*
2227825Stheraven * ----------------------------------------------------------------------------
3227825Stheraven * "THE BEER-WARE LICENSE" (Revision 42):
4227825Stheraven * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
5227825Stheraven * can do whatever you want with this stuff. If we meet some day, and you think
6227825Stheraven * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7227825Stheraven * ----------------------------------------------------------------------------
8227825Stheraven *
9227825Stheraven * $FreeBSD: head/sys/kern/kern_jail.c 57163 2000-02-12 13:41:56Z rwatson $
10227825Stheraven *
11227825Stheraven */
12227825Stheraven
13227825Stheraven#include <sys/param.h>
14227825Stheraven#include <sys/types.h>
15227825Stheraven#include <sys/kernel.h>
16227825Stheraven#include <sys/systm.h>
17227825Stheraven#include <sys/errno.h>
18227825Stheraven#include <sys/sysproto.h>
19227825Stheraven#include <sys/malloc.h>
20227825Stheraven#include <sys/proc.h>
21227825Stheraven#include <sys/jail.h>
22227825Stheraven#include <sys/socket.h>
23227825Stheraven#include <sys/sysctl.h>
24227825Stheraven#include <net/if.h>
25227825Stheraven#include <netinet/in.h>
26227825Stheraven
27227825StheravenMALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
28227825Stheraven
29227825StheravenSYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0,
30227825Stheraven    "Jail rules");
31227825Stheraven
32227825Stheravenint	jail_set_hostname_allowed = 1;
33227825StheravenSYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
34227825Stheraven    &jail_set_hostname_allowed, 0,
35227825Stheraven    "Processes in jail can set their hostnames");
36
37int
38jail(p, uap)
39        struct proc *p;
40        struct jail_args /* {
41                syscallarg(struct jail *) jail;
42        } */ *uap;
43{
44	int error;
45	struct prison *pr;
46	struct jail j;
47	struct chroot_args ca;
48
49	error = suser(p);
50	if (error)
51		return (error);
52	error = copyin(uap->jail, &j, sizeof j);
53	if (error)
54		return (error);
55	if (j.version != 0)
56		return (EINVAL);
57	MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK);
58	bzero((caddr_t)pr, sizeof *pr);
59	error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
60	if (error)
61		goto bail;
62	pr->pr_ip = j.ip_number;
63
64	ca.path = j.path;
65	error = chroot(p, &ca);
66	if (error)
67		goto bail;
68
69	pr->pr_ref++;
70	p->p_prison = pr;
71	p->p_flag |= P_JAILED;
72	return (0);
73
74bail:
75	FREE(pr, M_PRISON);
76	return (error);
77}
78
79int
80prison_ip(struct proc *p, int flag, u_int32_t *ip)
81{
82	u_int32_t tmp;
83
84	if (!p->p_prison)
85		return (0);
86	if (flag)
87		tmp = *ip;
88	else
89		tmp = ntohl(*ip);
90	if (tmp == INADDR_ANY) {
91		if (flag)
92			*ip = p->p_prison->pr_ip;
93		else
94			*ip = htonl(p->p_prison->pr_ip);
95		return (0);
96	}
97	if (p->p_prison->pr_ip != tmp)
98		return (1);
99	return (0);
100}
101
102void
103prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
104{
105	u_int32_t tmp;
106
107	if (!p || !p->p_prison)
108		return;
109	if (flag)
110		tmp = *ip;
111	else
112		tmp = ntohl(*ip);
113	if (tmp == 0x7f000001) {
114		if (flag)
115			*ip = p->p_prison->pr_ip;
116		else
117			*ip = htonl(p->p_prison->pr_ip);
118		return;
119	}
120	return;
121}
122
123int
124prison_if(struct proc *p, struct sockaddr *sa)
125{
126	struct sockaddr_in *sai = (struct sockaddr_in*) sa;
127	int ok;
128
129	if (sai->sin_family != AF_INET)
130		ok = 0;
131	else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
132		ok = 1;
133	else
134		ok = 0;
135	return (ok);
136}
137