Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108639542
D41464.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
25 KB
Referenced Files
None
Subscribers
None
D41464.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D41464: syslogd: Refresh configuration using libcasper
Attached
Detach File
Event Timeline
Log In to Comment