summaryrefslogtreecommitdiff
path: root/usr.sbin/authpf
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2003-01-07 03:32:16 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2003-01-07 03:32:16 +0000
commit3f76daf4f5fcae18120159825475126dd8325f81 (patch)
tree264dd3b50c410c41743683ff46be40f0c6ed1c78 /usr.sbin/authpf
parente9b7c577a43839ed0ceb3c93f576dbc7950209d2 (diff)
Add function to search for and remove stale rulesets from other authpf
processes which have terminated unexpectedly. ok beck@
Diffstat (limited to 'usr.sbin/authpf')
-rw-r--r--usr.sbin/authpf/authpf.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/usr.sbin/authpf/authpf.c b/usr.sbin/authpf/authpf.c
index 53a74848d63..9c6f68f243c 100644
--- a/usr.sbin/authpf/authpf.c
+++ b/usr.sbin/authpf/authpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: authpf.c,v 1.43 2003/01/06 18:43:02 deraadt Exp $ */
+/* $OpenBSD: authpf.c,v 1.44 2003/01/07 03:32:15 dhartmei Exp $ */
/*
* Copyright (C) 1998 - 2002 Bob Beck (beck@openbsd.org).
@@ -70,6 +70,7 @@ static int read_config(FILE *);
static void print_message(char *);
static int allowed_luser(char *);
static int check_luser(char *, char *);
+static int remove_stale_rulesets(void);
static int change_filter(int, const char *, const char *);
static void authpf_kill_states(void);
@@ -256,6 +257,9 @@ main(int argc, char *argv[])
if (config != NULL && read_config(config))
do_death(0);
+ if (remove_stale_rulesets())
+ do_death(0);
+
/* We appear to be making headway, so actually mark our pid */
rewind(pidfp);
fprintf(pidfp, "%ld\n%s\n", (long)getpid(), luser);
@@ -522,6 +526,61 @@ check_luser(char *luserdir, char *luser)
return (0);
}
+/*
+ * Search for rulesets left by other authpf processes (either because they
+ * died ungracefully or were terminated) and remove them.
+ */
+static int
+remove_stale_rulesets()
+{
+ struct pfioc_ruleset prs;
+ const int action[PF_RULESET_MAX] = { PF_SCRUB,
+ PF_PASS, PF_NAT, PF_BINAT, PF_RDR };
+ u_int32_t nr, mnr;
+
+ memset(&prs, 0, sizeof(prs));
+ strlcpy(prs.anchor, anchorname, sizeof(prs.anchor));
+ if (ioctl(dev, DIOCGETRULESETS, &prs)) {
+ if (errno == EINVAL)
+ return (0);
+ else
+ return (1);
+ }
+
+ mnr = prs.nr;
+ nr = 0;
+ while (nr < mnr) {
+ char *s;
+ pid_t pid;
+
+ prs.nr = nr;
+ if (ioctl(dev, DIOCGETRULESET, &prs))
+ return (1);
+ errno = 0;
+ pid = strtoul(prs.name, &s, 10);
+ if (!prs.name[0] || errno || *s)
+ return (1);
+ if (kill(pid, 0)) {
+ int i;
+
+ for (i = 0; i < PF_RULESET_MAX; ++i) {
+ struct pfioc_rule pr;
+
+ memset(&pr, 0, sizeof(pr));
+ memcpy(pr.anchor, prs.anchor, sizeof(pr.anchor));
+ memcpy(pr.ruleset, prs.name, sizeof(pr.ruleset));
+ pr.rule.action = action[i];
+ if ((ioctl(dev, DIOCBEGINRULES, &pr) ||
+ ioctl(dev, DIOCCOMMITRULES, &pr)) &&
+ errno != EINVAL)
+ return (1);
+ }
+ mnr--;
+ } else
+ nr++;
+ }
+ return (0);
+}
/*
* Add/remove filter entries for user "luser" from ip "ipsrc"
@@ -676,6 +735,7 @@ do_death(int active)
if (active) {
change_filter(0, luser, ipsrc);
authpf_kill_states();
+ remove_stale_rulesets();
}
if (pidfp)
ftruncate(fileno(pidfp), 0);