Index: contrib/pf/man/pf.conf.5
===================================================================
RCS file: /home/ncvs/src/contrib/pf/man/pf.conf.5,v
retrieving revision 1.7
diff -u -p -r1.7 pf.conf.5
--- contrib/pf/man/pf.conf.5	7 Feb 2005 23:20:12 -0000	1.7
+++ contrib/pf/man/pf.conf.5	13 Feb 2005 16:54:19 -0000
@@ -1322,13 +1322,13 @@ pass in proto tcp from any os "OpenBSD" 
 This is equivalent to "from any to any".
 .It Ar group <group>
 Similar to
-.Ar user ,
+.Ar user,
 this rule only applies to packets of sockets owned by the specified group.
 .Pp
 The use of
-.Ar group
+.Ar group, user, rgroup or
 or
-.Ar user
+.Ar ruser
 in
 .Va debug.mpsafenet Ns = Ns 1
 environments may result in a deadlock.
@@ -1387,6 +1387,14 @@ block out proto { tcp, udp } all
 pass  out proto { tcp, udp } all \e
       user { < 1000, dhartmei } keep state
 .Ed
+.It Ar rgroup <group>
+Similar to
+.Ar group,
+except that we match the real group ID instead of the effective ID.
+.It Ar ruser <user>
+Similar to
+.Ar user,
+except that we match the real user ID instead of the effective ID.
 .It Ar flags <a>/<b> | /<b>
 This rule only applies to TCP packets that have the flags
 .Ar <a>
@@ -2454,7 +2462,8 @@ pf-rule        = action [ ( "in" | "out"
                  hosts [ filteropt-list ]
 
 filteropt-list = filteropt-list filteropt | filteropt
-filteropt      = user | group | flags | icmp-type | icmp6-type | tos |
+filteropt      = user | group | ruser | rgroup |
+                 flags | icmp-type | icmp6-type | tos |
                  ( "keep" | "modulate" | "synproxy" ) "state"
                  [ "(" state-opts ")" ] |
                  "fragment" | "no-df" | "min-ttl" number |
@@ -2552,6 +2561,8 @@ portspec       = "port" ( number | name 
 os             = "os"  ( os-name | "{" os-list "}" )
 user           = "user" ( unary-op | binary-op | "{" op-list "}" )
 group          = "group" ( unary-op | binary-op | "{" op-list "}" )
+ruser          = "ruser" ( unary-op | binary-op | "{" op-list "}" )
+rgroup         = "rgroup" ( unary-op | binary-op | "{" op-list "}" )
 
 unary-op       = [ "=" | "!=" | "<" | "<=" | ">" | ">=" ]
                  ( name | number )
Index: contrib/pf/pfctl/parse.y
===================================================================
RCS file: /home/ncvs/src/contrib/pf/pfctl/parse.y,v
retrieving revision 1.6
diff -u -p -r1.6 parse.y
--- contrib/pf/pfctl/parse.y	16 Jun 2004 23:39:31 -0000	1.6
+++ contrib/pf/pfctl/parse.y	13 Feb 2005 16:54:23 -0000
@@ -174,6 +174,8 @@ struct filter_opts {
 #define FOM_SRCTRACK	0x10
 	struct node_uid		*uid;
 	struct node_gid		*gid;
+	struct node_uid		*ruid;
+	struct node_gid		*rgid;
 	struct {
 		u_int8_t	 b1;
 		u_int8_t	 b2;
@@ -268,7 +270,8 @@ void	expand_label(char *, size_t, const 
 void	expand_rule(struct pf_rule *, struct node_if *, struct node_host *,
 	    struct node_proto *, struct node_os*, struct node_host *,
 	    struct node_port *, struct node_host *, struct node_port *,
-	    struct node_uid *, struct node_gid *, struct node_icmp *);
+	    struct node_uid *, struct node_gid *, struct node_icmp *,
+	    struct node_uid *, struct node_gid *);
 int	expand_altq(struct pf_altq *, struct node_if *, struct node_queue *,
 	    struct node_queue_bw bwspec, struct node_queue_opt *);
 int	expand_queue(struct pf_altq *, struct node_if *, struct node_queue *,
@@ -337,6 +340,8 @@ typedef struct {
 		struct node_port	*port;
 		struct node_uid		*uid;
 		struct node_gid		*gid;
+		struct node_uid		*ruid;
+		struct node_gid		*rgid;
 		struct node_state_opt	*state_opt;
 		struct peer		 peer;
 		struct {
@@ -411,6 +416,7 @@ typedef struct {
 %token	LOAD
 %token	STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
 %token	TAGGED TAG IFBOUND GRBOUND FLOATING STATEPOLICY
+%token	RUSER RGROUP
 %token	<v.string>		STRING
 %token	<v.i>			PORTBINARY
 %type	<v.interface>		interface if_list if_item_not if_item
@@ -434,6 +440,8 @@ typedef struct {
 %type	<v.port>		portspec port_list port_item
 %type	<v.uid>			uids uid_list uid_item
 %type	<v.gid>			gids gid_list gid_item
+%type	<v.ruid>		ruids
+%type	<v.rgid>		rgids
 %type	<v.route>		route
 %type	<v.redirection>		redirection redirpool
 %type	<v.string>		label string tag
@@ -625,7 +633,7 @@ anchorrule	: ANCHOR string	dir interface
 
 			expand_rule(&r, $4, NULL, $6, $7.src_os,
 			    $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
-			    0, 0, 0);
+			    0, 0, 0, 0, 0);
 		}
 		| NATANCHOR string interface af proto fromto {
 			struct pf_rule	r;
@@ -645,7 +653,7 @@ anchorrule	: ANCHOR string	dir interface
 
 			expand_rule(&r, $3, NULL, $5, $6.src_os,
 			    $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
-			    0, 0, 0);
+			    0, 0, 0, 0, 0);
 		}
 		| RDRANCHOR string interface af proto fromto {
 			struct pf_rule	r;
@@ -686,7 +694,7 @@ anchorrule	: ANCHOR string	dir interface
 
 			expand_rule(&r, $3, NULL, $5, $6.src_os,
 			    $6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
-			    0, 0, 0);
+			    0, 0, 0, 0, 0);
 		}
 		| BINATANCHOR string interface af proto fromto {
 			struct pf_rule	r;
@@ -804,7 +812,7 @@ scrubrule	: SCRUB dir logquick interface
 
 			expand_rule(&r, $4, NULL, $6, $7.src_os,
 			    $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
-			    NULL, NULL, NULL);
+			    NULL, NULL, NULL, NULL, NULL);
 		}
 		;
 
@@ -920,7 +928,8 @@ antispoof	: ANTISPOOF logquick antispoof
 
 				if (h != NULL)
 					expand_rule(&r, j, NULL, NULL, NULL, h,
-					    NULL, NULL, NULL, NULL, NULL, NULL);
+					    NULL, NULL, NULL, NULL, NULL, NULL,
+					    NULL, NULL);
 
 				if ((i->ifa_flags & IFF_LOOPBACK) == 0) {
 					bzero(&r, sizeof(r));
@@ -936,7 +945,8 @@ antispoof	: ANTISPOOF logquick antispoof
 					if (h != NULL)
 						expand_rule(&r, NULL, NULL,
 						    NULL, NULL, h, NULL, NULL,
-						    NULL, NULL, NULL, NULL);
+						    NULL, NULL, NULL, NULL,
+						    NULL, NULL);
 				}
 			}
 			free($5.label);
@@ -1705,7 +1715,7 @@ pfrule		: action dir logquick interface 
 
 			expand_rule(&r, $4, $5.host, $7, $8.src_os,
 			    $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
-			    $9.uid, $9.gid, $9.icmpspec);
+			    $9.uid, $9.gid, $9.icmpspec, $9.ruid, $9.rgid);
 		}
 		;
 
@@ -1732,6 +1742,16 @@ filter_opt	: USER uids {
 				$2->tail->next = filter_opts.gid;
 			filter_opts.gid = $2;
 		}
+		| RUSER ruids {
+			if (filter_opts.ruid)
+				$2->tail->next = filter_opts.ruid;
+			filter_opts.ruid = $2;
+		}
+		| RGROUP rgids {
+			if (filter_opts.rgid)
+				$2->tail->next = filter_opts.rgid;
+			filter_opts.rgid = $2;
+		}
 		| flags {
 			if (filter_opts.marker & FOM_FLAGS) {
 				yyerror("flags cannot be redefined");
@@ -2320,6 +2340,10 @@ uids		: uid_item			{ $$ = $1; }
 		| '{' uid_list '}'		{ $$ = $2; }
 		;
 
+ruids		: uid_item			{ $$ = $1; }
+		| '{' uid_list '}'		{ $$ = $2; }
+		;
+
 uid_list	: uid_item			{ $$ = $1; }
 		| uid_list comma uid_item	{
 			$1->tail->next = $3;
@@ -2402,6 +2426,10 @@ gids		: gid_item			{ $$ = $1; }
 		| '{' gid_list '}'		{ $$ = $2; }
 		;
 
+rgids		: gid_item			{ $$ = $1; }
+		| '{' gid_list '}'		{ $$ = $2; }
+		;
+
 gid_list	: gid_item			{ $$ = $1; }
 		| gid_list comma gid_item	{
 			$1->tail->next = $3;
@@ -3164,7 +3192,7 @@ natrule		: nataction interface af proto 
 
 			expand_rule(&r, $2, $7 == NULL ? NULL : $7->host, $4,
 			    $5.src_os, $5.src.host, $5.src.port, $5.dst.host,
-			    $5.dst.port, 0, 0, 0);
+			    $5.dst.port, 0, 0, 0, 0, 0);
 			free($7);
 		}
 		;
@@ -4112,7 +4140,8 @@ expand_rule(struct pf_rule *r,
     struct node_proto *protos, struct node_os *src_oses,
     struct node_host *src_hosts, struct node_port *src_ports,
     struct node_host *dst_hosts, struct node_port *dst_ports,
-    struct node_uid *uids, struct node_gid *gids, struct node_icmp *icmp_types)
+    struct node_uid *uids, struct node_gid *gids, struct node_icmp *icmp_types,
+    struct node_uid *ruids, struct node_gid *rgids)
 {
 	sa_family_t		 af = r->af;
 	int			 added = 0, error = 0;
@@ -4145,6 +4174,8 @@ expand_rule(struct pf_rule *r,
 	LOOP_THROUGH(struct node_port, dst_port, dst_ports,
 	LOOP_THROUGH(struct node_uid, uid, uids,
 	LOOP_THROUGH(struct node_gid, gid, gids,
+	LOOP_THROUGH(struct node_uid, ruid, ruids,
+	LOOP_THROUGH(struct node_gid, rgid, rgids,
 
 		r->af = af;
 		/* for link-local IPv6 address, interface must match up */
@@ -4211,6 +4242,12 @@ expand_rule(struct pf_rule *r,
 		r->gid.op = gid->op;
 		r->gid.gid[0] = gid->gid[0];
 		r->gid.gid[1] = gid->gid[1];
+		r->ruid.op = ruid->op;
+		r->ruid.uid[0] = ruid->uid[0];
+		r->ruid.uid[1] = ruid->uid[1];
+		r->rgid.op = rgid->op;
+		r->rgid.gid[0] = rgid->gid[0];
+		r->rgid.gid[1] = rgid->gid[1];
 		r->type = icmp_type->type;
 		r->code = icmp_type->code;
 
@@ -4268,7 +4305,7 @@ expand_rule(struct pf_rule *r,
 			added++;
 		}
 
-	))))))))));
+	))))))))))));
 
 	FREE_LIST(struct node_if, interfaces);
 	FREE_LIST(struct node_proto, protos);
@@ -4279,6 +4316,8 @@ expand_rule(struct pf_rule *r,
 	FREE_LIST(struct node_port, dst_ports);
 	FREE_LIST(struct node_uid, uids);
 	FREE_LIST(struct node_gid, gids);
+	FREE_LIST(struct node_uid, ruids);
+	FREE_LIST(struct node_gid, rgids);
 	FREE_LIST(struct node_icmp, icmp_types);
 	FREE_LIST(struct node_host, rpool_hosts);
 
@@ -4394,9 +4433,11 @@ lookup(char *s)
 		{ "return-icmp",	RETURNICMP},
 		{ "return-icmp6",	RETURNICMP6},
 		{ "return-rst",		RETURNRST},
+		{ "rgroup",		RGROUP},
 		{ "round-robin",	ROUNDROBIN},
 		{ "route-to",		ROUTETO},
 		{ "rule",		RULE},
+		{ "ruser",		RUSER},
 		{ "scrub",		SCRUB},
 		{ "set",		SET},
 		{ "source-hash",	SOURCEHASH},
Index: contrib/pf/pfctl/pfctl_parser.c
===================================================================
RCS file: /home/ncvs/src/contrib/pf/pfctl/pfctl_parser.c,v
retrieving revision 1.6
diff -u -p -r1.6 pfctl_parser.c
--- contrib/pf/pfctl/pfctl_parser.c	17 Jun 2004 15:23:51 -0000	1.6
+++ contrib/pf/pfctl/pfctl_parser.c	13 Feb 2005 16:54:24 -0000
@@ -746,6 +746,12 @@ print_rule(struct pf_rule *r, int verbos
 	if (r->gid.op)
 		print_ugid(r->gid.op, r->gid.gid[0], r->gid.gid[1], "group",
 		    GID_MAX);
+	if (r->ruid.op)
+		print_ugid(r->ruid.op, r->ruid.uid[0], r->ruid.uid[1], "ruser",
+		    UID_MAX);
+	if (r->rgid.op)
+		print_ugid(r->rgid.op, r->rgid.gid[0], r->rgid.gid[1], "rgroup",
+		    GID_MAX);
 	if (r->flags || r->flagset) {
 		printf(" flags ");
 		print_flags(r->flags);
Index: sys/contrib/pf/net/pf.c
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pf.c,v
retrieving revision 1.26
diff -u -p -r1.26 pf.c
--- sys/contrib/pf/net/pf.c	20 Jan 2005 18:07:35 -0000	1.26
+++ sys/contrib/pf/net/pf.c	13 Feb 2005 16:54:31 -0000
@@ -238,7 +238,7 @@ void			 pf_route(struct mbuf **, struct 
 void			 pf_route6(struct mbuf **, struct pf_rule *, int,
 			    struct ifnet *, struct pf_state *);
 #ifdef __FreeBSD__
-int			 pf_socket_lookup(uid_t *, gid_t *,
+int			 pf_socket_lookup(uid_t *, gid_t *, uid_t *, gid_t *,
 			    int, struct pf_pdesc *, struct inpcb *);
 #else
 int			 pf_socket_lookup(uid_t *, gid_t *,
@@ -2392,8 +2392,8 @@ pf_get_translation(struct pf_pdesc *pd, 
 
 int
 #ifdef __FreeBSD__
-pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd,
-    struct inpcb *inp_arg)
+pf_socket_lookup(uid_t *uid, gid_t *gid, uid_t *ruid, gid_t *rgid,
+    int direction, struct pf_pdesc *pd, struct inpcb *inp_arg)
 #else
 pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
 #endif
@@ -2409,12 +2409,16 @@ pf_socket_lookup(uid_t *uid, gid_t *gid,
 
 	*uid = UID_MAX;
 	*gid = GID_MAX;
+	*ruid = UID_MAX;
+	*rgid = GID_MAX;
 #ifdef __FreeBSD__
 	if (inp_arg != NULL) {
 		INP_LOCK_ASSERT(inp_arg);
 		if (inp_arg->inp_socket) {
 			*uid = inp_arg->inp_socket->so_cred->cr_uid;
 			*gid = inp_arg->inp_socket->so_cred->cr_groups[0];
+			*ruid = inp_arg->inp_socket->so_cred->cr_ruid;
+			*rgid = inp_arg->inp_socket->so_cred->cr_rgid;
 			return (1);
 		} else
 			return (0);
@@ -2515,6 +2519,8 @@ pf_socket_lookup(uid_t *uid, gid_t *gid,
 	}
 	*uid = inp->inp_socket->so_cred->cr_uid;
 	*gid = inp->inp_socket->so_cred->cr_groups[0];
+	*ruid = inp->inp_socket->so_cred->cr_ruid;
+	*rgid = inp->inp_socket->so_cred->cr_rgid;
 	INP_UNLOCK(inp);
 	INP_INFO_RUNLOCK(pi);
 #else
@@ -2712,8 +2718,8 @@ pf_test_tcp(struct pf_rule **rm, struct 
 	u_int16_t		 bport, nport = 0;
 	sa_family_t		 af = pd->af;
 	int			 lookup = -1;
-	uid_t			 uid;
-	gid_t			 gid;
+	uid_t			 uid, ruid;
+	gid_t			 gid, rgid;
 	struct pf_rule		*r, *a = NULL;
 	struct pf_ruleset	*ruleset = NULL;
 	struct pf_src_node	*nsn = NULL;
@@ -2784,22 +2790,40 @@ pf_test_tcp(struct pf_rule **rm, struct 
 			r = TAILQ_NEXT(r, entries);
 		else if (r->uid.op && (lookup != -1 || (lookup =
 #ifdef __FreeBSD__
-		    pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
 #else
 		    pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 #endif
 		    !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
 		    uid))
 			r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+		else if (r->ruid.op && (lookup != -1 || (lookup =
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
+		    !pf_match_uid(r->ruid.op, r->ruid.uid[0], r->ruid.uid[1],
+		    ruid))
+			r = TAILQ_NEXT(r, entries);
+#endif
 		else if (r->gid.op && (lookup != -1 || (lookup =
 #ifdef __FreeBSD__
-		    pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
 #else
 		    pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 #endif
 		    !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
 		    gid))
 			r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+		else if (r->rgid.op && (lookup != -1 || (lookup =
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
+		    !pf_match_gid(r->rgid.op, r->rgid.gid[0], r->rgid.gid[1],
+		    rgid))
+			r = TAILQ_NEXT(r, entries);
+#endif
 		else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag))
 			r = TAILQ_NEXT(r, entries);
 		else if (r->anchorname[0] && r->anchor == NULL)
@@ -3085,8 +3109,8 @@ pf_test_udp(struct pf_rule **rm, struct 
 	u_int16_t		 bport, nport = 0;
 	sa_family_t		 af = pd->af;
 	int			 lookup = -1;
-	uid_t			 uid;
-	gid_t			 gid;
+	uid_t			 uid, ruid;
+	gid_t			 gid, rgid;
 	struct pf_rule		*r, *a = NULL;
 	struct pf_ruleset	*ruleset = NULL;
 	struct pf_src_node	*nsn = NULL;
@@ -3154,22 +3178,40 @@ pf_test_udp(struct pf_rule **rm, struct 
 			r = TAILQ_NEXT(r, entries);
 		else if (r->uid.op && (lookup != -1 || (lookup =
 #ifdef __FreeBSD__
-		    pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
 #else
 		    pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 #endif
 		    !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
 		    uid))
 			r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+		else if (r->ruid.op && (lookup != -1 || (lookup =
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
+		    !pf_match_uid(r->ruid.op, r->ruid.uid[0], r->ruid.uid[1],
+		    ruid))
+			r = TAILQ_NEXT(r, entries);
+#endif
 		else if (r->gid.op && (lookup != -1 || (lookup =
 #ifdef __FreeBSD__
-		    pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
 #else
 		    pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
 #endif
 		    !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
 		    gid))
 			r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+		else if (r->rgid.op && (lookup != -1 || (lookup =
+		    pf_socket_lookup(&uid, &gid, &ruid, &rgid, direction,
+		        pd, inp), 1)) &&
+		    !pf_match_gid(r->rgid.op, r->rgid.gid[0], r->rgid.gid[1],
+		    rgid))
+			r = TAILQ_NEXT(r, entries);
+#endif
 		else if (r->match_tag && !pf_match_tag(m, r, nr, pftag, &tag))
 			r = TAILQ_NEXT(r, entries);
 		else if (r->anchorname[0] && r->anchor == NULL)
Index: sys/contrib/pf/net/pfvar.h
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pfvar.h,v
retrieving revision 1.10
diff -u -p -r1.10 pfvar.h
--- sys/contrib/pf/net/pfvar.h	29 Sep 2004 04:54:32 -0000	1.10
+++ sys/contrib/pf/net/pfvar.h	13 Feb 2005 16:54:33 -0000
@@ -591,6 +591,8 @@ struct pf_rule {
 
 	struct pf_rule_uid	 uid;
 	struct pf_rule_gid	 gid;
+	struct pf_rule_uid	 ruid;
+	struct pf_rule_gid	 rgid;
 
 	u_int32_t		 rule_flag;
 	u_int8_t		 action;
