diff options
author | green <green@FreeBSD.org> | 1999-06-19 18:43:33 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 1999-06-19 18:43:33 +0000 |
commit | 280f8f95b4045e45c9f5d18632bd0ccb8cc0fad2 (patch) | |
tree | 4e405b30a98c2925095bc6ccbe3bc96d159a4741 /sys/netinet | |
parent | c9ce3ad902bd134472a439f97b9421bd66dead3c (diff) | |
download | FreeBSD-src-280f8f95b4045e45c9f5d18632bd0ccb8cc0fad2.zip FreeBSD-src-280f8f95b4045e45c9f5d18632bd0ccb8cc0fad2.tar.gz |
This is the much-awaited cleaned up version of IPFW [ug]id support.
All relevant changes have been made (including ipfw.8).
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_fw.c | 107 | ||||
-rw-r--r-- | sys/netinet/ip_fw.h | 10 | ||||
-rw-r--r-- | sys/netinet/udp_usrreq.c | 4 | ||||
-rw-r--r-- | sys/netinet/udp_var.h | 3 |
4 files changed, 110 insertions, 14 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index 2375cac..49c7110 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -12,7 +12,7 @@ * * This software is provided ``AS IS'' without any warranties of any kind. * - * $Id: ip_fw.c,v 1.112 1999/05/24 10:01:15 luigi Exp $ + * $Id: ip_fw.c,v 1.113 1999/06/11 11:27:35 ru Exp $ */ /* @@ -34,18 +34,21 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> +#include <sys/ucred.h> #include <net/if.h> +#include <net/route.h> #include <netinet/in.h> #include <netinet/in_systm.h> +#include <netinet/in_pcb.h> #include <netinet/ip.h> #include <netinet/ip_var.h> #include <netinet/ip_icmp.h> #include <netinet/ip_fw.h> #ifdef DUMMYNET -#include <net/route.h> #include <netinet/ip_dummynet.h> #endif #include <netinet/tcp.h> @@ -53,6 +56,7 @@ #include <netinet/tcp_var.h> #include <netinet/tcpip.h> #include <netinet/udp.h> +#include <netinet/udp_var.h> #include <netinet/if_ether.h> /* XXX ethertype_ip */ @@ -615,13 +619,14 @@ again: if (f->fw_ipopt != f->fw_ipnopt && !ipopts_match(ip, f)) continue; - /* Check protocol; if wildcard, match */ - if (f->fw_prot == IPPROTO_IP) - goto got_match; - - /* If different, don't match */ - if (ip->ip_p != f->fw_prot) - continue; + /* Check protocol; if wildcard, and no [ug]id, match */ + if (f->fw_prot == IPPROTO_IP) { + if (!(f->fw_flg & (IP_FW_F_UID|IP_FW_F_GID))) + goto got_match; + } else + /* If different, don't match */ + if (ip->ip_p != f->fw_prot) + continue; /* * here, pip==NULL for bridged pkts -- they include the ethernet @@ -641,6 +646,88 @@ again: } \ } while (0) + /* Protocol specific checks for uid only */ + if (f->fw_flg & (IP_FW_F_UID|IP_FW_F_GID)) { + switch (ip->ip_p) { + case IPPROTO_TCP: + { + struct tcphdr *tcp; + struct inpcb *P; + + if (offset == 1) /* cf. RFC 1858 */ + goto bogusfrag; + if (offset != 0) + continue; + + PULLUP_TO(hlen + 14); + tcp =(struct tcphdr *)((u_int32_t *)ip + ip->ip_hl); + + if (oif) + P = in_pcblookup_hash(&tcbinfo, ip->ip_dst, + tcp->th_dport, ip->ip_src, tcp->th_sport, 0); + else + P = in_pcblookup_hash(&tcbinfo, ip->ip_src, + tcp->th_sport, ip->ip_dst, tcp->th_dport, 0); + + if (P && P->inp_socket && P->inp_socket->so_cred) { + if (f->fw_flg & IP_FW_F_UID) { + if (P->inp_socket->so_cred->p_ruid != + f->fw_uid) + continue; + } else if (!groupmember(f->fw_gid, + P->inp_socket->so_cred->pc_ucred)) + continue; + } else continue; + + break; + } + + case IPPROTO_UDP: + { + struct udphdr *udp; + struct inpcb *P; + + if (offset != 0) + continue; + + PULLUP_TO(hlen + 4); + udp =(struct udphdr *)((u_int32_t *)ip + ip->ip_hl); + + if (oif) + P = in_pcblookup_hash(&udbinfo, ip->ip_dst, + udp->uh_dport, ip->ip_src, udp->uh_sport, 1); + else + P = in_pcblookup_hash(&udbinfo, ip->ip_src, + udp->uh_sport, ip->ip_dst, udp->uh_dport, 1); + + if (P && P->inp_socket && P->inp_socket->so_cred) { + if (f->fw_flg & IP_FW_F_UID) { + if (P->inp_socket->so_cred->p_ruid != + f->fw_uid) + continue; + } else if (!groupmember(f->fw_gid, + P->inp_socket->so_cred->pc_ucred)) + continue; + } else continue; + + break; + } + + default: + continue; +/* + * XXX Shouldn't GCC be allowing two bogusfrag labels if they're both inside + * separate blocks? Hmm.... It seems it's got incorrect behavior here. + */ +#if 0 +bogusfrag: + if (fw_verbose) + ipfw_report(NULL, ip, rif, oif); + goto dropit; +#endif + } + } + /* Protocol specific checks */ switch (ip->ip_p) { case IPPROTO_TCP: @@ -1134,6 +1221,8 @@ check_ipfw_struct(struct ip_fw *frwl) #ifdef IPFIREWALL_FORWARD case IP_FW_F_FWD: #endif + case IP_FW_F_UID: + case IP_FW_F_GID: break; default: dprintf(("%s invalid command\n", err_prefix)); diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 3dc3c0e..ba15dbd 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -11,7 +11,7 @@ * * This software is provided ``AS IS'' without any warranties of any kind. * - * $Id: ip_fw.h,v 1.36 1998/12/14 18:09:13 luigi Exp $ + * $Id: ip_fw.h,v 1.37 1999/04/20 13:32:05 peter Exp $ */ #ifndef _IP_FW_H @@ -81,6 +81,8 @@ struct ip_fw { /* count of 0 means match all ports) */ void *pipe_ptr; /* Pipe ptr in case of dummynet pipe */ void *next_rule_ptr ; /* next rule in case of match */ + uid_t fw_uid; /* uid to match */ + gid_t fw_gid; /* gid to match */ }; #define IP_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f) @@ -144,7 +146,11 @@ struct ip_fw_chain { #define IP_FW_F_ICMPBIT 0x00100000 /* ICMP type bitmap is valid */ -#define IP_FW_F_MASK 0x001FFFFF /* All possible flag bits mask */ +#define IP_FW_F_UID 0x00200000 /* filter by uid */ + +#define IP_FW_F_GID 0x00400000 /* filter by uid */ + +#define IP_FW_F_MASK 0x007FFFFF /* All possible flag bits mask */ /* * For backwards compatibility with rules specifying "via iface" but diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index b0d293c..fac3405 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 - * $Id: udp_usrreq.c,v 1.50 1999/04/28 11:37:51 phk Exp $ + * $Id: udp_usrreq.c,v 1.51 1999/05/03 23:57:32 billf Exp $ */ #include <sys/param.h> @@ -78,7 +78,7 @@ SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW, &log_in_vain, 0, "Log all incoming UDP packets"); static struct inpcbhead udb; /* from udp_var.h */ -static struct inpcbinfo udbinfo; +struct inpcbinfo udbinfo; #ifndef UDBHASHSIZE #define UDBHASHSIZE 16 diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 2615e9c..4784a35 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)udp_var.h 8.1 (Berkeley) 6/10/93 - * $Id: udp_var.h,v 1.16 1998/11/17 10:53:37 dfr Exp $ + * $Id: udp_var.h,v 1.17 1999/02/16 10:49:52 dfr Exp $ */ #ifndef _NETINET_UDP_VAR_H_ @@ -103,6 +103,7 @@ struct udpstat { SYSCTL_DECL(_net_inet_udp); extern struct pr_usrreqs udp_usrreqs; +extern struct inpcbinfo udbinfo; void udp_ctlinput __P((int, struct sockaddr *, void *)); void udp_init __P((void)); |