summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>1999-06-19 18:43:33 +0000
committergreen <green@FreeBSD.org>1999-06-19 18:43:33 +0000
commit280f8f95b4045e45c9f5d18632bd0ccb8cc0fad2 (patch)
tree4e405b30a98c2925095bc6ccbe3bc96d159a4741 /sys
parentc9ce3ad902bd134472a439f97b9421bd66dead3c (diff)
downloadFreeBSD-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')
-rw-r--r--sys/netinet/ip_fw.c107
-rw-r--r--sys/netinet/ip_fw.h10
-rw-r--r--sys/netinet/udp_usrreq.c4
-rw-r--r--sys/netinet/udp_var.h3
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));
OpenPOWER on IntegriCloud