This is the much-awaited cleaned up version of IPFW [ug]id support.
All relevant changes have been made (including ipfw.8).
This commit is contained in:
parent
6ea5bd80fe
commit
7a2aab80b0
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" $Id: ipfw.8,v 1.52 1999/05/29 08:12:37 kris Exp $
|
||||
.\" $Id: ipfw.8,v 1.53 1999/06/15 12:56:38 ru Exp $
|
||||
.\"
|
||||
.Dd July 20, 1996
|
||||
.Dt IPFW 8
|
||||
@ -384,6 +384,18 @@ Skip all subsequent rules numbered less than
|
||||
The search continues with the first rule numbered
|
||||
.Ar number
|
||||
or higher.
|
||||
.It Ar uid user
|
||||
Match all TCP or UDP packets sent by or received for a
|
||||
.Ar user .
|
||||
A
|
||||
.Ar user
|
||||
may be matched by name or identification number.
|
||||
.It Ar gid group
|
||||
Match all TCP or UDP packets sent by or received for a
|
||||
.Ar group .
|
||||
A
|
||||
.Ar group
|
||||
may be matched by name or identification number.
|
||||
.El
|
||||
.Pp
|
||||
If a packet matches more than one
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id: ipfw.c,v 1.69 1999/06/04 11:20:59 ru Exp $";
|
||||
"$Id: ipfw.c,v 1.70 1999/06/11 09:43:53 ru Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -33,8 +33,10 @@ static const char rcsid[] =
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -334,6 +336,24 @@ show_ipfw(struct ip_fw *chain, int pcwidth, int bcwidth)
|
||||
}
|
||||
}
|
||||
|
||||
if (chain->fw_flg & IP_FW_F_UID) {
|
||||
struct passwd *pwd = getpwuid(chain->fw_uid);
|
||||
|
||||
if (pwd)
|
||||
printf(" uid %s", pwd->pw_name);
|
||||
else
|
||||
printf(" uid %u", chain->fw_uid);
|
||||
}
|
||||
|
||||
if (chain->fw_flg & IP_FW_F_GID) {
|
||||
struct group *grp = getgrgid(chain->fw_gid);
|
||||
|
||||
if (grp)
|
||||
printf(" gid %s", grp->gr_name);
|
||||
else
|
||||
printf(" gid %u", chain->fw_gid);
|
||||
}
|
||||
|
||||
/* Direction */
|
||||
if ((chain->fw_flg & IP_FW_F_IN) && !(chain->fw_flg & IP_FW_F_OUT))
|
||||
printf(" in");
|
||||
@ -589,6 +609,8 @@ show_usage(const char *fmt, ...)
|
||||
" src: from [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||
" dst: to [not] {any|ip[{/bits|:mask}]} [{port|port-port},[port],...]\n"
|
||||
" extras:\n"
|
||||
" uid {user id}\n"
|
||||
" gid {group id}\n"
|
||||
" fragment (may not be used with ports or tcpflags)\n"
|
||||
" in\n"
|
||||
" out\n"
|
||||
@ -1215,6 +1237,32 @@ add(ac,av)
|
||||
}
|
||||
|
||||
while (ac) {
|
||||
if (!strncmp(*av,"uid",strlen(*av))) {
|
||||
struct passwd *pwd;
|
||||
|
||||
rule.fw_flg |= IP_FW_F_UID;
|
||||
ac--; av++;
|
||||
if (!ac)
|
||||
show_usage("``uid'' requires argument");
|
||||
|
||||
rule.fw_uid = (pwd = getpwnam(*av)) ? pwd->pw_uid
|
||||
: strtoul(*av, NULL, 0);
|
||||
ac--; av++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(*av,"gid",strlen(*av))) {
|
||||
struct group *grp;
|
||||
|
||||
rule.fw_flg |= IP_FW_F_GID;
|
||||
ac--; av++;
|
||||
if (!ac)
|
||||
show_usage("``gid'' requires argument");
|
||||
|
||||
rule.fw_gid = (grp = getgrnam(*av)) ? (gid_t)grp->gr_gid
|
||||
: strtoul(*av, NULL, 0);
|
||||
ac--; av++;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(*av,"in",strlen(*av))) {
|
||||
rule.fw_flg |= IP_FW_F_IN;
|
||||
av++; ac--; continue;
|
||||
|
@ -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 @@ non_ip: ip = NULL ;
|
||||
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 @@ non_ip: ip = NULL ;
|
||||
} \
|
||||
} 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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user