107901f22SPoul-Henning Kamp /* 207901f22SPoul-Henning Kamp * ---------------------------------------------------------------------------- 307901f22SPoul-Henning Kamp * "THE BEER-WARE LICENSE" (Revision 42): 407901f22SPoul-Henning Kamp * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 507901f22SPoul-Henning Kamp * can do whatever you want with this stuff. If we meet some day, and you think 607901f22SPoul-Henning Kamp * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 707901f22SPoul-Henning Kamp * ---------------------------------------------------------------------------- 807901f22SPoul-Henning Kamp * 9c3aac50fSPeter Wemm * $FreeBSD$ 1007901f22SPoul-Henning Kamp * 1107901f22SPoul-Henning Kamp */ 1275c13541SPoul-Henning Kamp 1375c13541SPoul-Henning Kamp #include <sys/param.h> 1475c13541SPoul-Henning Kamp #include <sys/types.h> 1575c13541SPoul-Henning Kamp #include <sys/kernel.h> 1675c13541SPoul-Henning Kamp #include <sys/systm.h> 1775c13541SPoul-Henning Kamp #include <sys/errno.h> 1875c13541SPoul-Henning Kamp #include <sys/sysproto.h> 1975c13541SPoul-Henning Kamp #include <sys/malloc.h> 2075c13541SPoul-Henning Kamp #include <sys/proc.h> 2175c13541SPoul-Henning Kamp #include <sys/jail.h> 2275c13541SPoul-Henning Kamp #include <sys/socket.h> 2383f1e257SRobert Watson #include <sys/sysctl.h> 2475c13541SPoul-Henning Kamp #include <net/if.h> 2575c13541SPoul-Henning Kamp #include <netinet/in.h> 2675c13541SPoul-Henning Kamp 2775c13541SPoul-Henning Kamp MALLOC_DEFINE(M_PRISON, "prison", "Prison structures"); 2875c13541SPoul-Henning Kamp 2983f1e257SRobert Watson SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0, 3083f1e257SRobert Watson "Jail rules"); 3183f1e257SRobert Watson 3283f1e257SRobert Watson int jail_set_hostname_allowed = 1; 3383f1e257SRobert Watson SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW, 3483f1e257SRobert Watson &jail_set_hostname_allowed, 0, 3583f1e257SRobert Watson "Processes in jail can set their hostnames"); 3683f1e257SRobert Watson 3775c13541SPoul-Henning Kamp int 3875c13541SPoul-Henning Kamp jail(p, uap) 3975c13541SPoul-Henning Kamp struct proc *p; 4075c13541SPoul-Henning Kamp struct jail_args /* { 4175c13541SPoul-Henning Kamp syscallarg(struct jail *) jail; 4275c13541SPoul-Henning Kamp } */ *uap; 4375c13541SPoul-Henning Kamp { 4475c13541SPoul-Henning Kamp int error; 4575c13541SPoul-Henning Kamp struct prison *pr; 4675c13541SPoul-Henning Kamp struct jail j; 4775c13541SPoul-Henning Kamp struct chroot_args ca; 4875c13541SPoul-Henning Kamp 4975c13541SPoul-Henning Kamp error = suser(p); 5075c13541SPoul-Henning Kamp if (error) 5175c13541SPoul-Henning Kamp return (error); 5275c13541SPoul-Henning Kamp error = copyin(uap->jail, &j, sizeof j); 5375c13541SPoul-Henning Kamp if (error) 5475c13541SPoul-Henning Kamp return (error); 55978f8d93SPoul-Henning Kamp if (j.version != 0) 56978f8d93SPoul-Henning Kamp return (EINVAL); 5775c13541SPoul-Henning Kamp MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK); 5875c13541SPoul-Henning Kamp bzero((caddr_t)pr, sizeof *pr); 5975c13541SPoul-Henning Kamp error = copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0); 6075c13541SPoul-Henning Kamp if (error) 6175c13541SPoul-Henning Kamp goto bail; 6275c13541SPoul-Henning Kamp pr->pr_ip = j.ip_number; 6375c13541SPoul-Henning Kamp 6475c13541SPoul-Henning Kamp ca.path = j.path; 6575c13541SPoul-Henning Kamp error = chroot(p, &ca); 6675c13541SPoul-Henning Kamp if (error) 6775c13541SPoul-Henning Kamp goto bail; 6875c13541SPoul-Henning Kamp 6975c13541SPoul-Henning Kamp pr->pr_ref++; 7075c13541SPoul-Henning Kamp p->p_prison = pr; 7175c13541SPoul-Henning Kamp p->p_flag |= P_JAILED; 7275c13541SPoul-Henning Kamp return (0); 7375c13541SPoul-Henning Kamp 7475c13541SPoul-Henning Kamp bail: 7575c13541SPoul-Henning Kamp FREE(pr, M_PRISON); 7675c13541SPoul-Henning Kamp return (error); 7775c13541SPoul-Henning Kamp } 7875c13541SPoul-Henning Kamp 7975c13541SPoul-Henning Kamp int 8075c13541SPoul-Henning Kamp prison_ip(struct proc *p, int flag, u_int32_t *ip) 8175c13541SPoul-Henning Kamp { 8275c13541SPoul-Henning Kamp u_int32_t tmp; 8375c13541SPoul-Henning Kamp 8475c13541SPoul-Henning Kamp if (!p->p_prison) 8575c13541SPoul-Henning Kamp return (0); 8675c13541SPoul-Henning Kamp if (flag) 8775c13541SPoul-Henning Kamp tmp = *ip; 8875c13541SPoul-Henning Kamp else 8975c13541SPoul-Henning Kamp tmp = ntohl(*ip); 9075c13541SPoul-Henning Kamp if (tmp == INADDR_ANY) { 9175c13541SPoul-Henning Kamp if (flag) 9275c13541SPoul-Henning Kamp *ip = p->p_prison->pr_ip; 9375c13541SPoul-Henning Kamp else 9475c13541SPoul-Henning Kamp *ip = htonl(p->p_prison->pr_ip); 9575c13541SPoul-Henning Kamp return (0); 9675c13541SPoul-Henning Kamp } 9775c13541SPoul-Henning Kamp if (p->p_prison->pr_ip != tmp) 9875c13541SPoul-Henning Kamp return (1); 9975c13541SPoul-Henning Kamp return (0); 10075c13541SPoul-Henning Kamp } 10175c13541SPoul-Henning Kamp 10275c13541SPoul-Henning Kamp void 10375c13541SPoul-Henning Kamp prison_remote_ip(struct proc *p, int flag, u_int32_t *ip) 10475c13541SPoul-Henning Kamp { 10575c13541SPoul-Henning Kamp u_int32_t tmp; 10675c13541SPoul-Henning Kamp 107430210c0SPoul-Henning Kamp if (!p || !p->p_prison) 10875c13541SPoul-Henning Kamp return; 10975c13541SPoul-Henning Kamp if (flag) 11075c13541SPoul-Henning Kamp tmp = *ip; 11175c13541SPoul-Henning Kamp else 11275c13541SPoul-Henning Kamp tmp = ntohl(*ip); 11375c13541SPoul-Henning Kamp if (tmp == 0x7f000001) { 11475c13541SPoul-Henning Kamp if (flag) 11575c13541SPoul-Henning Kamp *ip = p->p_prison->pr_ip; 11675c13541SPoul-Henning Kamp else 11775c13541SPoul-Henning Kamp *ip = htonl(p->p_prison->pr_ip); 11875c13541SPoul-Henning Kamp return; 11975c13541SPoul-Henning Kamp } 12075c13541SPoul-Henning Kamp return; 12175c13541SPoul-Henning Kamp } 12275c13541SPoul-Henning Kamp 12375c13541SPoul-Henning Kamp int 12475c13541SPoul-Henning Kamp prison_if(struct proc *p, struct sockaddr *sa) 12575c13541SPoul-Henning Kamp { 12675c13541SPoul-Henning Kamp struct sockaddr_in *sai = (struct sockaddr_in*) sa; 12775c13541SPoul-Henning Kamp int ok; 12875c13541SPoul-Henning Kamp 12975c13541SPoul-Henning Kamp if (sai->sin_family != AF_INET) 13075c13541SPoul-Henning Kamp ok = 0; 13175c13541SPoul-Henning Kamp else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr)) 13275c13541SPoul-Henning Kamp ok = 1; 13375c13541SPoul-Henning Kamp else 13475c13541SPoul-Henning Kamp ok = 0; 13575c13541SPoul-Henning Kamp return (ok); 13675c13541SPoul-Henning Kamp } 137