예제 #1
0
파일: authpf.c 프로젝트: SylvestreG/bitrig
static int
recursive_ruleset_purge(char *an, char *rs)
{
	struct pfioc_trans_e     *t_e = NULL;
	struct pfioc_trans	 *t = NULL;
	struct pfioc_ruleset	 *prs = NULL;

	/* purge rules */
	errno = 0;
	if ((t = calloc(1, sizeof(struct pfioc_trans))) == NULL)
		goto no_mem;
	if ((t_e = calloc(2, sizeof(struct pfioc_trans_e))) == NULL)
		goto no_mem;
	t->size = 2;
	t->esize = sizeof(struct pfioc_trans_e);
	t->array = t_e;
	t_e[0].type = PF_TRANS_RULESET;
	snprintf(t_e[0].anchor, sizeof(t_e[0].anchor), "%s/%s", an, rs);
	t_e[1].type = PF_TRANS_TABLE;

	if ((ioctl(dev, DIOCXBEGIN, t) ||
	    ioctl(dev, DIOCXCOMMIT, t)) &&
	    errno != EINVAL)
		goto cleanup;

	/* purge any children */
	if ((prs = calloc(1, sizeof(struct pfioc_ruleset))) == NULL)
		goto no_mem;
	snprintf(prs->path, sizeof(prs->path), "%s/%s", an, rs);
	if (ioctl(dev, DIOCGETRULESETS, prs)) {
		if (errno != EINVAL)
			goto cleanup;
		errno = 0;
	} else {
		int nr = prs->nr;

		while (nr) {
			prs->nr = 0;
			if (ioctl(dev, DIOCGETRULESET, prs))
				goto cleanup;

			if (recursive_ruleset_purge(prs->path, prs->name))
				goto cleanup;
			nr--;
		}
	}

no_mem:
	if (errno == ENOMEM)
		syslog(LOG_ERR, "calloc failed");

cleanup:
	free(t);
	free(t_e);
	free(prs);
	return (errno);
}
예제 #2
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(void)
{
	struct pfioc_ruleset	 prs;
	u_int32_t		 nr;

	memset(&prs, 0, sizeof(prs));
	strlcpy(prs.path, anchorname, sizeof(prs.path));
	if (ioctl(dev, DIOCGETRULESETS, &prs)) {
		if (errno == EINVAL)
			return (0);
		else
			return (1);
	}

	nr = prs.nr;
	while (nr) {
		char	*s, *t;
		pid_t	 pid;

		prs.nr = nr - 1;
		if (ioctl(dev, DIOCGETRULESET, &prs))
			return (1);
		errno = 0;
		if ((t = strchr(prs.name, '(')) == NULL)
			t = prs.name;
		else
			t++;
		pid = strtoul(t, &s, 10);
		if (!prs.name[0] || errno ||
		    (*s && (t == prs.name || *s != ')')))
			return (1);
		if ((kill(pid, 0) && errno != EPERM) || pid == getpid()) {
			if (recursive_ruleset_purge(anchorname, prs.name))
				return (1);
		}
		nr--;
	}
	return (0);
}