From 324fd7ec40439e6b3916429a69956d7acf74eb19 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Thu, 4 Jan 2024 13:45:56 +0100 Subject: libpfctl: introduce a handle-enabled variant of pfctl_add_rule() Introduce pfctl_add_rule_h(), which takes a pfctl_handle rather than a file descriptor (which it didn't use). This means that library users can open the handle while they're running as root, but later drop privileges and still add rules to pf. Sponsored by: Rubicon Communications, LLC ("Netgate") --- lib/libpfctl/libpfctl.c | 29 +++++++++++++++++++++++------ lib/libpfctl/libpfctl.h | 3 +++ 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 94949a5a7337..2db3f0ede99f 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -1116,20 +1116,37 @@ snl_add_msg_attr_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfct int pfctl_add_rule(int dev __unused, const struct pfctl_rule *r, const char *anchor, const char *anchor_call, uint32_t ticket, uint32_t pool_ticket) +{ + struct pfctl_handle *h; + int ret; + + h = pfctl_open(PF_DEVICE); + if (h == NULL) + return (ENODEV); + + ret = pfctl_add_rule_h(h, r, anchor, anchor_call, ticket, pool_ticket); + + pfctl_close(h); + + return (ret); +} + +int +pfctl_add_rule_h(struct pfctl_handle *h, const struct pfctl_rule *r, + const char *anchor, const char *anchor_call, uint32_t ticket, + uint32_t pool_ticket) { struct snl_writer nw; - struct snl_state ss = {}; struct snl_errmsg_data e = {}; struct nlmsghdr *hdr; uint32_t seq_id; int family_id; - snl_init(&ss, NETLINK_GENERIC); - family_id = snl_get_genl_family(&ss, PFNL_FAMILY_NAME); + family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME); if (family_id == 0) return (ENOTSUP); - snl_init_writer(&ss, &nw); + snl_init_writer(&h->ss, &nw); hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_ADDRULE); hdr->nlmsg_flags |= NLM_F_DUMP; snl_add_msg_attr_u32(&nw, PF_ART_TICKET, ticket); @@ -1144,10 +1161,10 @@ pfctl_add_rule(int dev __unused, const struct pfctl_rule *r, const char *anchor, seq_id = hdr->nlmsg_seq; - if (! snl_send_message(&ss, hdr)) + if (! snl_send_message(&h->ss, hdr)) return (ENXIO); - while ((hdr = snl_read_reply_multi(&ss, seq_id, &e)) != NULL) { + while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { } return (e.error); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index f128e5340891..cd72d04d6715 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -421,6 +421,9 @@ int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket, int pfctl_add_rule(int dev, const struct pfctl_rule *r, const char *anchor, const char *anchor_call, uint32_t ticket, uint32_t pool_ticket); +int pfctl_add_rule_h(struct pfctl_handle *h, const struct pfctl_rule *r, + const char *anchor, const char *anchor_call, uint32_t ticket, + uint32_t pool_ticket); int pfctl_set_keepcounters(int dev, bool keep); int pfctl_get_creatorids(struct pfctl_handle *h, uint32_t *creators, size_t *len); -- cgit v1.3