Page MenuHomeFreeBSD

D41464.diff
No OneTemporary

D41464.diff

diff --git a/usr.sbin/syslogd/Makefile b/usr.sbin/syslogd/Makefile
--- a/usr.sbin/syslogd/Makefile
+++ b/usr.sbin/syslogd/Makefile
@@ -14,7 +14,8 @@
LIBADD= util
.if ${MK_CASPER} != "no"
-SRCS+= syslogd_cap.c
+SRCS+= syslogd_cap.c \
+ syslogd_cap_config.c
CFLAGS+= -DWITH_CASPER
LIBADD+= cap_net casper nv
.endif
diff --git a/usr.sbin/syslogd/syslogd.h b/usr.sbin/syslogd/syslogd.h
--- a/usr.sbin/syslogd/syslogd.h
+++ b/usr.sbin/syslogd/syslogd.h
@@ -64,6 +64,7 @@
#define _SYSLOGD_H_
#include <sys/param.h>
+#include <sys/nv.h>
#include <sys/queue.h>
#include <sys/time.h>
@@ -71,6 +72,8 @@
#include <sys/syslog.h>
#include <regex.h>
+#include <stdbool.h>
+#include <stdio.h>
#define MAXLINE 8192 /* maximum line length */
#define MAXSVLINE MAXLINE /* maximum saved line length */
@@ -107,7 +110,6 @@
#define FILT_FLAG_EXTENDED (1 << 1)
#define FILT_FLAG_ICASE (1 << 2)
char *pflt_strval;
- size_t pflt_strlen;
regex_t *pflt_re;
};
@@ -132,8 +134,8 @@
enum f_type f_type;
/* Used for filtering. */
- char *f_host; /* host from which to recd. */
- char *f_program; /* program this applies to */
+ char f_host[MAXHOSTNAMELEN]; /* host from which to recd. */
+ char f_program[MAXPATHLEN]; /* program this applies to */
struct prop_filter *f_prop_filter; /* property-based filter */
u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */
u_char f_pcmp[LOG_NFACILITIES+1]; /* compare priority */
@@ -170,4 +172,11 @@
STAILQ_ENTRY(filed) next; /* next in linked list */
};
+extern const char *ConfFile;
+extern char LocalHostName[MAXHOSTNAMELEN];
+
+void closelogfiles(void);
+void logerror(const char *);
+nvlist_t *readconfigfile(const char *);
+
#endif /* !_SYSLOGD_H_ */
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -131,7 +131,7 @@
#include "syslogd_cap.h"
#include "ttymsg.h"
-static const char *ConfFile = _PATH_LOGCONF;
+const char *ConfFile = _PATH_LOGCONF;
static const char *PidFile = _PATH_LOGPID;
static const char include_str[] = "include";
static const char include_ext[] = ".conf";
@@ -276,7 +276,7 @@
static bool Debug; /* debug flag */
static bool Foreground = false; /* Run in foreground, instead of daemonizing */
static bool resolve = true; /* resolve hostname */
-static char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */
+char LocalHostName[MAXHOSTNAMELEN]; /* our hostname */
static const char *LocalDomain; /* our local domain name */
static bool Initialized; /* set when we have initialized ourselves */
static int MarkInterval = 20 * 60; /* interval between marks in seconds */
@@ -313,7 +313,7 @@
static bool allowaddr(char *);
static void addpeer(const char *, const char *, mode_t);
static void addsock(const char *, const char *, mode_t);
-static void cfline(const char *, const char *, const char *, const char *);
+static nvlist_t *cfline(const char *, const char *, const char *, const char *);
static const char *cvthname(struct sockaddr *);
static void deadq_enter(int);
static void deadq_remove(struct deadq_entry *);
@@ -325,7 +325,6 @@
static void fprintlog_write(struct filed *, struct iovlist *, int);
static void fprintlog_successive(struct filed *, int);
static void init(bool);
-static void logerror(const char *);
static void logmsg(int, const struct logtime *, const char *, const char *,
const char *, const char *, const char *, const char *, int);
static void markit(void);
@@ -335,7 +334,7 @@
static int skip_message(const char *, const char *, int);
static int evaluate_prop_filter(const struct prop_filter *filter,
const char *value);
-static struct prop_filter *prop_filter_compile(const char *);
+static nvlist_t *prop_filter_compile(const char *);
static void parsemsg(const char *, char *);
static void printsys(char *);
static int p_open(const char *, pid_t *);
@@ -1387,7 +1386,7 @@
int exclude = 0;
/* Behaviour on explicit match */
- if (spec == NULL)
+ if (spec == NULL || *spec == '\0')
return (0);
switch (*spec) {
case '-':
@@ -1445,7 +1444,7 @@
/* a shortcut for equal with different length is always false */
if (filter->cmp_type == FILT_CMP_EQUAL &&
- valuelen != filter->pflt_strlen)
+ valuelen != strlen(filter->pflt_strval))
return (!exclude);
if (filter->cmp_flags & FILT_FLAG_ICASE)
@@ -2178,7 +2177,7 @@
/*
* Print syslogd errors some place.
*/
-static void
+void
logerror(const char *msg)
{
char buf[512];
@@ -2255,8 +2254,8 @@
return (1);
}
-static void
-parseconfigfile(FILE *cf, bool allow_includes)
+static nvlist_t *
+parseconfigfile(FILE *cf, bool allow_includes, nvlist_t *nvl_conf)
{
FILE *cf2;
struct dirent **ent;
@@ -2316,7 +2315,7 @@
if (cf2 == NULL)
continue;
dprintf("reading %s\n", file);
- parseconfigfile(cf2, false);
+ parseconfigfile(cf2, false, nvl_conf);
fclose(cf2);
}
free(ent);
@@ -2386,29 +2385,55 @@
}
for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--)
cline[i] = '\0';
- cfline(cline, prog, host, pfilter);
+ nvlist_append_nvlist_array(nvl_conf, "filed_list",
+ cfline(cline, prog, host, pfilter));
+
}
+ return (nvl_conf);
}
-static void
+nvlist_t *
readconfigfile(const char *path)
{
FILE *cf;
+ nvlist_t *nvl_conf = nvlist_create(0);
if ((cf = fopen(path, "r")) != NULL) {
- parseconfigfile(cf, true);
+ nvl_conf = parseconfigfile(cf, true, nvl_conf);
(void)fclose(cf);
} else {
- dprintf("cannot open %s\n", ConfFile);
- cfline("*.ERR\t/dev/console", "*", "*", "*");
- cfline("*.PANIC\t*", "*", "*", "*");
+ dprintf("cannot open %s\n", path);
+ nvlist_append_nvlist_array(nvl_conf, "filed_list",
+ cfline("*.ERR\t/dev/console", "*", "*", "*"));
+ nvlist_append_nvlist_array(nvl_conf, "filed_list",
+ cfline("*.PANIC\t*", "*", "*", "*"));
+ }
+ return (nvl_conf);
+}
+
+static void
+fill_flist(nvlist_t *nvl_conf)
+{
+ const nvlist_t * const *filed_list;
+ size_t nfileds;
+
+ if (!nvlist_exists_nvlist_array(nvl_conf, "filed_list"))
+ return;
+ filed_list = nvlist_get_nvlist_array(nvl_conf, "filed_list",
+ &nfileds);
+ for (size_t i = 0; i < nfileds; ++i) {
+ struct filed *f;
+
+ f = nvlist_to_filed(filed_list[i]);
+ STAILQ_INSERT_TAIL(&fhead, f, next);
}
+ nvlist_destroy(nvl_conf);
}
/*
* Close all open log files.
*/
-static void
+void
closelogfiles(void)
{
struct filed *f;
@@ -2433,14 +2458,12 @@
break;
}
- free(f->f_program);
- free(f->f_host);
if (f->f_prop_filter) {
switch (f->f_prop_filter->cmp_type) {
case FILT_CMP_REGEX:
regfree(f->f_prop_filter->pflt_re);
free(f->f_prop_filter->pflt_re);
- break;
+ /* FALLTHROUGH */
case FILT_CMP_CONTAINS:
case FILT_CMP_EQUAL:
case FILT_CMP_STARTS:
@@ -2504,7 +2527,7 @@
Initialized = false;
closelogfiles();
- readconfigfile(ConfFile);
+ fill_flist(readconfigfile(ConfFile));
Initialized = true;
if (Debug) {
@@ -2561,7 +2584,7 @@
default:
break;
}
- if (f->f_program)
+ if (*f->f_program != '\0')
printf(" (%s)", f->f_program);
printf("\n");
}
@@ -2597,29 +2620,18 @@
/*
* Compile property-based filter.
*/
-static struct prop_filter *
+static nvlist_t *
prop_filter_compile(const char *cfilter)
{
- struct prop_filter *pfilter;
+ nvlist_t *nvl_pfilter;
+ struct prop_filter pfilter = { };
char *filter, *filter_endpos, *filter_begpos, *p;
char **ap, *argv[2] = {NULL, NULL};
- int re_flags = REG_NOSUB;
int escaped;
- pfilter = calloc(1, sizeof(*pfilter));
- if (pfilter == NULL) {
- logerror("pfilter calloc");
- exit(1);
- }
- if (*cfilter == '*') {
- pfilter->prop_type = FILT_PROP_NOOP;
- return (pfilter);
- }
filter = strdup(cfilter);
- if (filter == NULL) {
- logerror("strdup");
- exit(1);
- }
+ if (filter == NULL)
+ err(1, "strdup");
filter_begpos = filter;
/*
@@ -2640,48 +2652,48 @@
}
if (argv[0] == NULL || argv[1] == NULL) {
- logerror("filter parse error");
+ dprintf("filter parse error");
goto error;
}
/* fill in prop_type */
if (strcasecmp(argv[0], "msg") == 0)
- pfilter->prop_type = FILT_PROP_MSG;
+ pfilter.prop_type = FILT_PROP_MSG;
else if (strcasecmp(argv[0], "hostname") == 0)
- pfilter->prop_type = FILT_PROP_HOSTNAME;
+ pfilter.prop_type = FILT_PROP_HOSTNAME;
else if (strcasecmp(argv[0], "source") == 0)
- pfilter->prop_type = FILT_PROP_HOSTNAME;
+ pfilter.prop_type = FILT_PROP_HOSTNAME;
else if (strcasecmp(argv[0], "programname") == 0)
- pfilter->prop_type = FILT_PROP_PROGNAME;
+ pfilter.prop_type = FILT_PROP_PROGNAME;
else {
- logerror("unknown property");
+ dprintf("unknown property");
goto error;
}
/* full in cmp_flags (i.e. !contains, icase_regex, etc.) */
if (*argv[1] == '!') {
- pfilter->cmp_flags |= FILT_FLAG_EXCLUDE;
+ pfilter.cmp_flags |= FILT_FLAG_EXCLUDE;
argv[1]++;
}
if (strncasecmp(argv[1], "icase_", (sizeof("icase_") - 1)) == 0) {
- pfilter->cmp_flags |= FILT_FLAG_ICASE;
+ pfilter.cmp_flags |= FILT_FLAG_ICASE;
argv[1] += sizeof("icase_") - 1;
}
/* fill in cmp_type */
if (strcasecmp(argv[1], "contains") == 0)
- pfilter->cmp_type = FILT_CMP_CONTAINS;
+ pfilter.cmp_type = FILT_CMP_CONTAINS;
else if (strcasecmp(argv[1], "isequal") == 0)
- pfilter->cmp_type = FILT_CMP_EQUAL;
+ pfilter.cmp_type = FILT_CMP_EQUAL;
else if (strcasecmp(argv[1], "startswith") == 0)
- pfilter->cmp_type = FILT_CMP_STARTS;
+ pfilter.cmp_type = FILT_CMP_STARTS;
else if (strcasecmp(argv[1], "regex") == 0)
- pfilter->cmp_type = FILT_CMP_REGEX;
+ pfilter.cmp_type = FILT_CMP_REGEX;
else if (strcasecmp(argv[1], "ereregex") == 0) {
- pfilter->cmp_type = FILT_CMP_REGEX;
- re_flags |= REG_EXTENDED;
+ pfilter.cmp_type = FILT_CMP_REGEX;
+ pfilter.cmp_flags |= REG_EXTENDED;
} else {
- logerror("unknown cmp function");
+ dprintf("unknown cmp function");
goto error;
}
@@ -2693,7 +2705,7 @@
/* remove leading whitespace and check for '"' next character */
filter += strspn(filter, ", \t\n");
if (*filter != '"' || strlen(filter) < 3) {
- logerror("property value parse error");
+ dprintf("property value parse error");
goto error;
}
filter++;
@@ -2725,33 +2737,18 @@
/* We should not have anything but whitespace left after closing '"' */
if (*p != '\0' && strspn(p, " \t\n") != strlen(p)) {
- logerror("property value parse error");
+ dprintf("property value parse error");
goto error;
}
- if (pfilter->cmp_type == FILT_CMP_REGEX) {
- pfilter->pflt_re = calloc(1, sizeof(*pfilter->pflt_re));
- if (pfilter->pflt_re == NULL) {
- logerror("RE calloc() error");
- goto error;
- }
- if (pfilter->cmp_flags & FILT_FLAG_ICASE)
- re_flags |= REG_ICASE;
- if (regcomp(pfilter->pflt_re, filter, re_flags) != 0) {
- logerror("RE compilation error");
- goto error;
- }
- } else {
- pfilter->pflt_strval = strdup(filter);
- pfilter->pflt_strlen = strlen(filter);
- }
+ pfilter.pflt_strval = filter;
+ /* An nvlist is heap allocated heap here. */
+ nvl_pfilter = prop_filter_to_nvlist(&pfilter);
free(filter_begpos);
- return (pfilter);
+ return (nvl_pfilter);
error:
free(filter_begpos);
- free(pfilter->pflt_re);
- free(pfilter);
return (NULL);
}
@@ -2760,7 +2757,7 @@
{
int i, pri;
int pri_done = 0, pri_cmp = 0, pri_invert = 0;
- char *bp, buf[LINE_MAX], ebuf[100];
+ char *bp, buf[LINE_MAX];
const char *q;
/* find the end of this facility name list */
@@ -2812,10 +2809,7 @@
pri = decode(buf, prioritynames);
if (pri < 0) {
- errno = 0;
- (void)snprintf(ebuf, sizeof(ebuf),
- "unknown priority name \"%s\"", buf);
- logerror(ebuf);
+ dprintf("unknown priority name \"%s\"", buf);
free(f);
return (NULL);
}
@@ -2839,11 +2833,7 @@
} else {
i = decode(buf, facilitynames);
if (i < 0) {
- errno = 0;
- (void)snprintf(ebuf, sizeof(ebuf),
- "unknown facility name \"%s\"",
- buf);
- logerror(ebuf);
+ dprintf("unknown facility name \"%s\"", buf);
free(f);
return (NULL);
}
@@ -2870,6 +2860,7 @@
} else
syncfile = true;
+ f->f_file = -1;
switch (*p) {
case '@':
{
@@ -2910,7 +2901,7 @@
};
error = getaddrinfo(f->f_hname, p ? p : "syslog", &hints, &res);
if (error) {
- logerror(gai_strerror(error));
+ dprintf("%s\n", gai_strerror(error));
break;
}
f->f_addr = res;
@@ -2920,7 +2911,7 @@
case '/':
if ((f->f_file = open(p, logflags, 0600)) < 0) {
f->f_type = F_UNUSED;
- logerror(p);
+ dprintf("%s\n", p);
break;
}
if (syncfile)
@@ -2969,74 +2960,59 @@
/*
* Crack a configuration file line
*/
-static void
+static nvlist_t *
cfline(const char *line, const char *prog, const char *host,
const char *pfilter)
{
- struct filed *f;
+ nvlist_t *nvl_filed;
+ struct filed f = { };
const char *p;
dprintf("cfline(\"%s\", f, \"%s\", \"%s\", \"%s\")\n", line, prog,
host, pfilter);
- f = calloc(1, sizeof(*f));
- if (f == NULL) {
- logerror("malloc");
- exit(1);
- }
- errno = 0; /* keep strerror() stuff out of logerror messages */
-
for (int i = 0; i <= LOG_NFACILITIES; i++)
- f->f_pmask[i] = INTERNAL_NOPRI;
+ f.f_pmask[i] = INTERNAL_NOPRI;
/* save hostname if any */
- if (host && *host == '*')
- host = NULL;
- if (host) {
+ if (host != NULL && *host != '*') {
int hl;
- f->f_host = strdup(host);
- if (f->f_host == NULL) {
- logerror("strdup");
- exit(1);
- }
- hl = strlen(f->f_host);
- if (hl > 0 && f->f_host[hl-1] == '.')
- f->f_host[--hl] = '\0';
+ strlcpy(f.f_host, host, sizeof(f.f_host));
+ hl = strlen(f.f_host);
+ if (hl > 0 && f.f_host[hl-1] == '.')
+ f.f_host[--hl] = '\0';
/* RFC 5424 prefers logging FQDNs. */
if (RFC3164OutputFormat)
- trimdomain(f->f_host, hl);
+ trimdomain(f.f_host, hl);
}
/* save program name if any */
- if (prog && *prog == '*')
- prog = NULL;
- if (prog) {
- f->f_program = strdup(prog);
- if (f->f_program == NULL) {
- logerror("strdup");
- exit(1);
- }
- }
-
- if (pfilter) {
- f->f_prop_filter = prop_filter_compile(pfilter);
- if (f->f_prop_filter == NULL) {
- logerror("filter compile error");
- exit(1);
- }
- }
+ if (prog != NULL && *prog != '*')
+ strlcpy(f.f_program, prog, sizeof(f.f_program));
/* scan through the list of selectors */
for (p = line; *p != '\0' && *p != '\t' && *p != ' ';)
- p = parse_selector(p, f);
+ p = parse_selector(p, &f);
/* skip to action part */
while (*p == '\t' || *p == ' ')
p++;
- parse_action(p, f);
+ parse_action(p, &f);
+
+ /* An nvlist is heap allocated heap here. */
+ nvl_filed = filed_to_nvlist(&f);
+
+ if (pfilter && *pfilter != '*') {
+ nvlist_t *nvl_pfilter;
+
+ nvl_pfilter = prop_filter_compile(pfilter);
+ if (nvl_pfilter == NULL)
+ err(1, "filter compile error");
+ nvlist_add_nvlist(nvl_filed, "f_prop_filter", nvl_pfilter);
+ }
- STAILQ_INSERT_TAIL(&fhead, f, next);
+ return (nvl_filed);
}
/*
diff --git a/usr.sbin/syslogd/syslogd_cap.h b/usr.sbin/syslogd/syslogd_cap.h
--- a/usr.sbin/syslogd/syslogd_cap.h
+++ b/usr.sbin/syslogd/syslogd_cap.h
@@ -47,6 +47,20 @@
#include "syslogd.h"
+nvlist_t *cap_readconfigfile(cap_channel_t *, const char *);
+int casper_readconfigfile(nvlist_t *, nvlist_t *);
+
+nvlist_t *filed_to_nvlist(const struct filed *);
+nvlist_t *prop_filter_to_nvlist(const struct prop_filter *pfilter);
+
+struct filed *nvlist_to_filed(const nvlist_t *);
+struct prop_filter *nvlist_to_prop_filter(const nvlist_t *nvl_prop_filter);
+
+#else /* !WITH_CASPER */
+
+#define cap_readconfigfile(chan, cf) \
+ readconfigfile(cf)
+
#endif /* WITH_CASPER */
#endif /* !_SYSLOGD_CAP_H_ */
diff --git a/usr.sbin/syslogd/syslogd_cap.c b/usr.sbin/syslogd/syslogd_cap.c
--- a/usr.sbin/syslogd/syslogd_cap.c
+++ b/usr.sbin/syslogd/syslogd_cap.c
@@ -32,6 +32,7 @@
#include <sys/socket.h>
#include <libcasper.h>
+#include <string.h>
#include <casper/cap_net.h>
@@ -39,10 +40,14 @@
/* This is where libcasper receives commands via nvlist. */
static int
-casper_command(const char *cmd __unused, const nvlist_t *limits __unused,
- nvlist_t *nvlin __unused, nvlist_t *nvlout __unused)
+casper_command(const char *cmd, const nvlist_t *limits __unused,
+ nvlist_t *nvlin, nvlist_t *nvlout)
{
int error = EINVAL;
+
+ if (strcmp(cmd, "readconfigfile") == 0)
+ error = casper_readconfigfile(nvlin, nvlout);
+
return (error);
}
diff --git a/usr.sbin/syslogd/syslogd_cap_config.c b/usr.sbin/syslogd/syslogd_cap_config.c
new file mode 100644
--- /dev/null
+++ b/usr.sbin/syslogd/syslogd_cap_config.c
@@ -0,0 +1,296 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 The FreeBSD Foundation
+ *
+ * This software was developed by Jake Freeland <jfree@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <assert.h>
+#include <err.h>
+#include <libcasper.h>
+#include <netdb.h>
+#include <string.h>
+
+#include <casper/cap_net.h>
+
+#include "syslogd_cap.h"
+
+/*
+ * Convert the given prop_filter structure into an nvlist.
+ * Return a heap allocated pointer to the resulting nvlist.
+ */
+nvlist_t *
+prop_filter_to_nvlist(const struct prop_filter *pfilter)
+{
+ nvlist_t *nvl_prop_filter = nvlist_create(0);
+
+ nvlist_add_number(nvl_prop_filter, "prop_type", pfilter->prop_type);
+ nvlist_add_number(nvl_prop_filter, "cmp_type", pfilter->cmp_type);
+ nvlist_add_number(nvl_prop_filter, "cmp_flags", pfilter->cmp_flags);
+ nvlist_add_string(nvl_prop_filter, "pflt_strval", pfilter->pflt_strval);
+ /*
+ * Do not bother adding pflt_re. It will be recompiled
+ * using pflt_strval later, if applicable.
+ */
+
+ return (nvl_prop_filter);
+}
+
+/*
+ * Convert the given nvlist into a prop_filter structure.
+ * Return a heap allocated pointer to the resulting prop_filter.
+ */
+struct prop_filter *
+nvlist_to_prop_filter(const nvlist_t *nvl_prop_filter)
+{
+ struct prop_filter *pfilter;
+
+ pfilter = calloc(1, sizeof(*pfilter));
+ if (pfilter == NULL)
+ err(1, "calloc");
+ pfilter->prop_type = nvlist_get_number(nvl_prop_filter, "prop_type");
+ pfilter->cmp_type = nvlist_get_number(nvl_prop_filter, "cmp_type");
+ pfilter->cmp_flags = nvlist_get_number(nvl_prop_filter, "cmp_flags");
+ pfilter->pflt_strval = strdup(nvlist_get_string(nvl_prop_filter,
+ "pflt_strval"));
+ if (pfilter->cmp_type == FILT_CMP_REGEX) {
+ int re_flags = REG_NOSUB;
+ pfilter->pflt_re = calloc(1, sizeof(*pfilter->pflt_re));
+ if (pfilter->pflt_re == NULL)
+ errx(1, "RE calloc() error");
+ if ((pfilter->cmp_flags & FILT_FLAG_EXTENDED) != 0)
+ re_flags |= REG_EXTENDED;
+ if ((pfilter->cmp_flags & FILT_FLAG_ICASE) != 0)
+ re_flags |= REG_ICASE;
+ if (regcomp(pfilter->pflt_re, pfilter->pflt_strval,
+ re_flags) != 0)
+ errx(1, "RE compilation error");
+ }
+
+ return (pfilter);
+}
+
+/*
+ * Convert the given struct filed into an nvl_filed nvlist.
+ * Return a heap allocated pointer to the resulting nvlist.
+ */
+nvlist_t *
+filed_to_nvlist(const struct filed *filed)
+{
+ nvlist_t *nvl_filed = nvlist_create(0);
+ enum f_type f_type = filed->f_type;
+ size_t i, sz;
+
+ nvlist_add_number(nvl_filed, "f_type", f_type);
+ nvlist_add_string(nvl_filed, "f_host", filed->f_host);
+ nvlist_add_string(nvl_filed, "f_program", filed->f_program);
+ if (filed->f_prop_filter != NULL) {
+ nvlist_add_nvlist(nvl_filed, "f_prop_filter",
+ prop_filter_to_nvlist(filed->f_prop_filter));
+ }
+ sz = nitems(filed->f_pmask);
+ for (i = 0; i < sz; ++i) {
+ nvlist_append_number_array(nvl_filed, "f_pmask",
+ filed->f_pmask[i]);
+ }
+ sz = nitems(filed->f_pcmp);
+ for (i = 0; i < sz; ++i) {
+ nvlist_append_number_array(nvl_filed, "f_pcmp",
+ filed->f_pcmp[i]);
+ }
+
+ if (filed->f_file >= 0)
+ nvlist_add_descriptor(nvl_filed, "f_file", filed->f_file);
+ nvlist_add_number(nvl_filed, "f_flags", filed->f_flags);
+ if (f_type == F_WALL || f_type == F_USERS) {
+ sz = nitems(filed->f_uname);
+ for (i = 0; i < sz; ++i) {
+ nvlist_append_string_array(nvl_filed, "f_uname",
+ filed->f_uname[i]);
+ }
+ } else if (f_type == F_FILE || f_type == F_CONSOLE || f_type == F_TTY) {
+ nvlist_add_string(nvl_filed, "f_fname", filed->f_fname);
+ } else if (f_type == F_FORW) {
+ struct addrinfo *ai = filed->f_addr, *cur;
+ nvlist_t *nvl_addrinfo;
+
+ nvlist_add_string(nvl_filed, "f_hname", filed->f_hname);
+ if (filed->f_addr != NULL) {
+ for (cur = ai; cur != NULL; cur = cur->ai_next) {
+ nvl_addrinfo = addrinfo_pack(cur);
+ nvlist_append_nvlist_array(nvl_filed,
+ "f_addr", nvl_addrinfo);
+ nvlist_destroy(nvl_addrinfo);
+ }
+ }
+ } else if (filed->f_type == F_PIPE) {
+ nvlist_add_string(nvl_filed, "f_pname", filed->f_pname);
+ if (filed->f_procdesc >= 0) {
+ nvlist_add_descriptor(nvl_filed, "f_procdesc",
+ filed->f_procdesc);
+ }
+ }
+
+ /*
+ * Book-keeping fields are not transferred.
+ */
+
+ return (nvl_filed);
+}
+
+/*
+ * Convert the given nvl_filed nvlist into a struct filed.
+ * Return a heap allocated pointer to the resulting struct
+ * filed.
+ */
+struct filed *
+nvlist_to_filed(const nvlist_t *nvl_filed)
+{
+ struct filed *filed;
+ enum f_type f_type;
+ const uint64_t *narr;
+ size_t i, sz;
+
+ filed = calloc(1, sizeof(*filed));
+ if (filed == NULL)
+ err(1, "calloc");
+
+ f_type = filed->f_type = nvlist_get_number(nvl_filed, "f_type");
+ (void)strlcpy(filed->f_host, nvlist_get_string(nvl_filed, "f_host"),
+ sizeof(filed->f_host));
+ (void)strlcpy(filed->f_program, nvlist_get_string(nvl_filed,
+ "f_program"), sizeof(filed->f_program));
+ if (nvlist_exists_nvlist(nvl_filed, "f_prop_filter")) {
+ filed->f_prop_filter = nvlist_to_prop_filter(
+ nvlist_get_nvlist(nvl_filed, "f_prop_filter"));
+ }
+ narr = nvlist_get_number_array(nvl_filed, "f_pmask", &sz);
+ assert(sz == nitems(filed->f_pmask));
+ for (i = 0; i < sz; ++i)
+ filed->f_pmask[i] = narr[i];
+ narr = nvlist_get_number_array(nvl_filed, "f_pcmp", &sz);
+ assert(sz == nitems(filed->f_pcmp));
+ for (i = 0; i < sz; ++i)
+ filed->f_pcmp[i] = narr[i];
+
+ if (nvlist_exists_descriptor(nvl_filed, "f_file"))
+ filed->f_file = dup(nvlist_get_descriptor(nvl_filed, "f_file"));
+ else
+ filed->f_file = -1;
+ filed->f_flags = nvlist_get_number(nvl_filed, "f_flags");
+ if (f_type == F_WALL || f_type == F_USERS) {
+ const char * const *f_uname;
+
+ f_uname = nvlist_get_string_array(nvl_filed, "f_uname", &sz);
+ assert(sz == nitems(filed->f_uname));
+ for (i = 0; i < sz; ++i) {
+ (void)strlcpy(filed->f_uname[i], f_uname[i],
+ sizeof(filed->f_uname[i]));
+ }
+ } else if (f_type == F_FILE || f_type == F_CONSOLE || f_type == F_TTY) {
+ (void)strlcpy(filed->f_fname, nvlist_get_string(nvl_filed,
+ "f_fname"), sizeof(filed->f_fname));
+ } else if (f_type == F_FORW) {
+ const nvlist_t * const *f_addr;
+ struct addrinfo *ai, **next = NULL;
+
+ (void)strlcpy(filed->f_hname, nvlist_get_string(nvl_filed,
+ "f_hname"), sizeof(filed->f_hname));
+ f_addr = nvlist_get_nvlist_array(nvl_filed, "f_addr", &sz);
+ for (i = 0; i < sz; ++i) {
+ ai = addrinfo_unpack(f_addr[i]);
+ if (next == NULL)
+ filed->f_addr = ai;
+ else
+ *next = ai;
+ next = &ai->ai_next;
+ }
+ } else if (filed->f_type == F_PIPE) {
+ (void)strlcpy(filed->f_pname, nvlist_get_string(nvl_filed,
+ "f_pname"), sizeof(filed->f_pname));
+ if (nvlist_exists_descriptor(nvl_filed, "f_procdesc")) {
+ filed->f_procdesc = dup(nvlist_get_descriptor(nvl_filed,
+ "f_procdesc"));
+ } else {
+ filed->f_procdesc = -1;
+ }
+ }
+
+ /*
+ * Book-keeping fields are not transferred.
+ */
+
+ return (filed);
+}
+
+nvlist_t *
+cap_readconfigfile(cap_channel_t *chan, const char *path)
+{
+ nvlist_t *nvl, *nvl_conf;
+
+ nvl = nvlist_create(0);
+ nvlist_add_string(nvl, "cmd", "readconfigfile");
+ nvlist_add_string(nvl, "path", path);
+ /* It is possible that our hostname has changed. */
+ nvlist_add_string(nvl, "LocalHostName", LocalHostName);
+ nvl = cap_xfer_nvlist(chan, nvl);
+ if (nvl == NULL) {
+ logerror("Failed to xfer configuration nvlist");
+ exit(1);
+ }
+ nvl_conf = nvlist_take_nvlist(nvl, "nvl_conf");
+
+ nvlist_destroy(nvl);
+ return (nvl_conf);
+}
+
+/*
+ * Now that we're executing as libcasper, we can obtain the
+ * resources specified in the configuration.
+ */
+int
+casper_readconfigfile(nvlist_t *nvlin, nvlist_t *nvlout)
+{
+ const char *path;
+
+ /*
+ * Verify that syslogd did not manipulate the
+ * configuration file path.
+ */
+ path = nvlist_get_string(nvlin, "path");
+ if (strcmp(path, ConfFile) != 0)
+ err(1, "Configuration file mismatch: %s != %s", path, ConfFile);
+
+ /* Refresh our copy of LocalHostName, in case it changed. */
+ strlcpy(LocalHostName, nvlist_get_string(nvlin, "LocalHostName"),
+ sizeof(LocalHostName));
+
+ nvlist_move_nvlist(nvlout, "nvl_conf", readconfigfile(path));
+ return (0);
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 28, 1:00 AM (10 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16230690
Default Alt Text
D41464.diff (25 KB)

Event Timeline