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 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 +Similar to +.Ar group, +except that we match the real group ID instead of the effective ID. +.It Ar ruser +Similar to +.Ar user, +except that we match the real user ID instead of the effective ID. .It Ar flags / | / This rule only applies to TCP packets that have the flags .Ar @@ -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 STRING %token PORTBINARY %type interface if_list if_item_not if_item @@ -434,6 +440,8 @@ typedef struct { %type portspec port_list port_item %type uids uid_list uid_item %type gids gid_list gid_item +%type ruids +%type rgids %type route %type redirection redirpool %type 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;