[systemd-commits] 7 commits - Makefile.am man/systemd-journald.service.xml man/systemd.unit.xml src/core src/journal src/shared units/systemd-journald-audit.socket units/systemd-journald.service.in units/systemd-udevd-kernel.socket
Lennart Poettering
lennart at kemper.freedesktop.org
Mon Nov 3 13:02:32 PST 2014
Makefile.am | 8
man/systemd-journald.service.xml | 36 +-
man/systemd.unit.xml | 15 -
src/core/condition.c | 3
src/journal/journald-audit.c | 489 ++++++++++++++++++++++++++++++++++++
src/journal/journald-audit.h | 29 ++
src/journal/journald-console.c | 2
src/journal/journald-console.h | 2
src/journal/journald-kmsg.c | 4
src/journal/journald-kmsg.h | 2
src/journal/journald-native.c | 16 -
src/journal/journald-native.h | 4
src/journal/journald-server.c | 70 +++--
src/journal/journald-server.h | 4
src/journal/journald-syslog.c | 47 +--
src/journal/journald-syslog.h | 4
src/journal/journald-wall.c | 2
src/journal/journald-wall.h | 2
src/shared/audit.c | 18 +
src/shared/audit.h | 2
src/shared/missing.h | 9
units/systemd-journald-audit.socket | 19 +
units/systemd-journald.service.in | 6
units/systemd-udevd-kernel.socket | 2
24 files changed, 708 insertions(+), 87 deletions(-)
New commits:
commit a6e841b454e076ecbab6abc0bceb85ed06fd5c70
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 22:02:23 2014 +0100
man: document audit input for journald
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index 1f1a7f1..fa6e97e 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -63,13 +63,31 @@
<para><filename>systemd-journald</filename> is a
system service that collects and stores logging data.
It creates and maintains structured, indexed journals
- based on logging information that is received from the
- kernel, from user processes via the libc
- <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call, from standard input and standard error of system
- services or via its native API. It will implicitly
- collect numerous metadata fields for each log
- messages in a secure and unfakeable way. See
+ based on logging information that is received from a
+ variety of sources:</para>
+
+ <itemizedlist>
+ <listitem><para>Kernel log messages, via kmsg</para></listitem>
+
+ <listitem><para>Simple system log messages, via the
+ libc <citerefentry
+ project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ call</para></listitem>
+
+ <listitem><para>Structured system log messages via the
+ native Journal API, see
+ <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>4</manvolnum></citerefentry></para></listitem>
+
+ <listitem><para>Standard output and
+ standard error of system
+ services</para></listitem>
+
+ <listitem><para>Audit records, via the audit subsystem</para></listitem>
+ </itemizedlist>
+
+ <para>The daemon will implicitly collect numerous
+ metadata fields for each log messages in a secure and
+ unfakeable way. See
<citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for more information about the collected metadata.
</para>
@@ -89,8 +107,7 @@
the data.</para>
<para><filename>systemd-journald</filename> will
- forward all received log messages to the <constant>AF_UNIX</constant>
- <constant>SOCK_DGRAM</constant> socket
+ forward all received log messages to the <constant>AF_UNIX</constant>/<constant>SOCK_DGRAM</constant> socket
<filename>/run/systemd/journal/syslog</filename>, if it exists, which
may be used by Unix syslog daemons to process the data
further.</para>
@@ -250,6 +267,7 @@
<citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>setfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
<command>pydoc systemd.journal</command>.
</para>
</refsect1>
commit d5d78543a2174a6bae349080ed3bcfdac5610b48
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 21:11:49 2014 +0100
units: make ReceiveBuffer= line more readable by using M suffix
diff --git a/units/systemd-udevd-kernel.socket b/units/systemd-udevd-kernel.socket
index 39b7809..1a16206 100644
--- a/units/systemd-udevd-kernel.socket
+++ b/units/systemd-udevd-kernel.socket
@@ -14,6 +14,6 @@ ConditionPathIsReadWrite=/sys
[Socket]
Service=systemd-udevd.service
-ReceiveBuffer=134217728
+ReceiveBuffer=128M
ListenNetlink=kobject-uevent 1
PassCredentials=yes
commit 99d0966e75a984bed4f117c888ecc93e16e7b7b6
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 21:11:16 2014 +0100
journald: fix minor memory leak
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index e062427..cf6bbcc 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1690,6 +1690,7 @@ void server_done(Server *s) {
free(s->buffer);
free(s->tty_path);
free(s->cgroup_root);
+ free(s->hostname_field);
if (s->mmap)
mmap_cache_unref(s->mmap);
commit cfb1f5df7ce6868d3edb7333591b91c9809d64d3
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 21:09:38 2014 +0100
core: introduce ConditionSecurity=audit
And conditionalize journald audit support with it
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 803eff2..6d4c5c1 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1080,14 +1080,15 @@
<para><varname>ConditionSecurity=</varname>
may be used to check whether the given
security module is enabled on the
- system. Currently the recognized values
- values are <varname>selinux</varname>,
+ system. Currently the recognized
+ values values are
+ <varname>selinux</varname>,
<varname>apparmor</varname>,
- <varname>ima</varname> and
- <varname>smack</varname>.
- The test may be negated by prepending
- an exclamation
- mark.</para>
+ <varname>ima</varname>,
+ <varname>smack</varname> and
+ <varname>audit</varname>. The test may
+ be negated by prepending an
+ exclamation mark.</para>
<para><varname>ConditionCapability=</varname>
may be used to check whether the given
diff --git a/src/core/condition.c b/src/core/condition.c
index ec78169..8e2e311 100644
--- a/src/core/condition.c
+++ b/src/core/condition.c
@@ -38,6 +38,7 @@
#include "apparmor-util.h"
#include "ima-util.h"
#include "selinux-util.h"
+#include "audit.h"
static bool condition_test_security(Condition *c) {
assert(c);
@@ -50,6 +51,8 @@ static bool condition_test_security(Condition *c) {
return mac_smack_use() == !c->negate;
if (streq(c->parameter, "apparmor"))
return mac_apparmor_use() == !c->negate;
+ if (streq(c->parameter, "audit"))
+ return use_audit() == !c->negate;
if (streq(c->parameter, "ima"))
return use_ima() == !c->negate;
diff --git a/src/shared/audit.c b/src/shared/audit.c
index f101050..4701c0a 100644
--- a/src/shared/audit.c
+++ b/src/shared/audit.c
@@ -80,3 +80,21 @@ int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
*uid = (uid_t) u;
return 0;
}
+
+bool use_audit(void) {
+ static int cached_use = -1;
+
+ if (cached_use < 0) {
+ int fd;
+
+ fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
+ if (fd < 0)
+ cached_use = errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT;
+ else {
+ cached_use = true;
+ safe_close(fd);
+ }
+ }
+
+ return cached_use;
+}
diff --git a/src/shared/audit.h b/src/shared/audit.h
index 0effc0b..b4aecff 100644
--- a/src/shared/audit.h
+++ b/src/shared/audit.h
@@ -27,3 +27,5 @@
int audit_session_from_pid(pid_t pid, uint32_t *id);
int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
+
+bool use_audit(void);
diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket
index ce849da..35397aa 100644
--- a/units/systemd-journald-audit.socket
+++ b/units/systemd-journald-audit.socket
@@ -10,6 +10,7 @@ Description=Journal Audit Socket
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Before=sockets.target
+ConditionSecurity=audit
[Socket]
Service=systemd-journald.service
commit 875c2e220e2611165e09051c4747971811f1de58
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 20:58:24 2014 +0100
journald: if available pull audit messages from the kernel into journal logs
diff --git a/Makefile.am b/Makefile.am
index 3800a22..ff5f61b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4073,6 +4073,8 @@ libsystemd_journal_core_la_SOURCES = \
src/journal/journald-wall.h \
src/journal/journald-native.c \
src/journal/journald-native.h \
+ src/journal/journald-audit.c \
+ src/journal/journald-audit.h \
src/journal/journald-rate-limit.c \
src/journal/journald-rate-limit.h \
src/journal/journal-internal.h
@@ -4224,7 +4226,8 @@ bin_PROGRAMS += \
dist_systemunit_DATA += \
units/systemd-journald.socket \
- units/systemd-journald-dev-log.socket
+ units/systemd-journald-dev-log.socket \
+ units/systemd-journald-audit.socket
nodist_systemunit_DATA += \
units/systemd-journald.service \
@@ -4243,7 +4246,8 @@ dist_catalog_DATA = \
SOCKETS_TARGET_WANTS += \
systemd-journald.socket \
- systemd-journald-dev-log.socket
+ systemd-journald-dev-log.socket \
+ systemd-journald-audit.socket
SYSINIT_TARGET_WANTS += \
systemd-journald.service \
diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
new file mode 100644
index 0000000..fe0eec8
--- /dev/null
+++ b/src/journal/journald-audit.c
@@ -0,0 +1,489 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "missing.h"
+#include "journald-audit.h"
+
+typedef struct MapField {
+ const char *audit_field;
+ const char *journal_field;
+ int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov);
+} MapField;
+
+static int map_simple_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+ _cleanup_free_ char *c = NULL;
+ size_t l = 0, allocated = 0;
+ const char *e;
+
+ assert(field);
+ assert(p);
+ assert(iov);
+ assert(n_iov);
+
+ l = strlen(field);
+ allocated = l + 1;
+ c = malloc(allocated);
+ if (!c)
+ return -ENOMEM;
+
+ memcpy(c, field, l);
+ for (e = *p; *e != ' ' && *e != 0; e++) {
+ if (!GREEDY_REALLOC(c, allocated, l+2))
+ return -ENOMEM;
+
+ c[l++] = *e;
+ }
+
+ c[l] = 0;
+
+ if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
+ return -ENOMEM;
+
+ (*iov)[*n_iov].iov_base = c;
+ (*iov)[*n_iov].iov_len = l;
+ (*n_iov) ++;
+
+ *p = e;
+ c = NULL;
+
+ return 1;
+}
+
+static int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+ _cleanup_free_ char *c = NULL;
+ const char *s, *e;
+ size_t l;
+
+ assert(field);
+ assert(p);
+ assert(iov);
+ assert(n_iov);
+
+ /* The kernel formats string fields in one of two formats. */
+
+ if (**p == '"') {
+ /* Normal quoted syntax */
+ s = *p + 1;
+ e = strchr(s, '"');
+ if (!e)
+ return 0;
+
+ l = strlen(field) + (e - s);
+ c = malloc(l+1);
+ if (!c)
+ return -ENOMEM;
+
+ *((char*) mempcpy(stpcpy(c, field), s, e - s)) = 0;
+
+ e += 1;
+
+ } else if (unhexchar(**p) >= 0) {
+ /* Hexadecimal escaping */
+ size_t allocated = 0;
+
+ l = strlen(field);
+ allocated = l + 2;
+ c = malloc(allocated);
+ if (!c)
+ return -ENOMEM;
+
+ memcpy(c, field, l);
+ for (e = *p; *e != ' ' && *e != 0; e += 2) {
+ int a, b;
+
+ a = unhexchar(e[0]);
+ if (a < 0)
+ return 0;
+
+ b = unhexchar(e[1]);
+ if (b < 0)
+ return 0;
+
+ if (!GREEDY_REALLOC(c, allocated, l+2))
+ return -ENOMEM;
+
+ c[l++] = (char) ((uint8_t) a << 4 | (uint8_t) b);
+ }
+
+ c[l] = 0;
+ } else
+ return 0;
+
+ if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
+ return -ENOMEM;
+
+ (*iov)[*n_iov].iov_base = c;
+ (*iov)[*n_iov].iov_len = l;
+ (*n_iov) ++;
+
+ *p = e;
+ c = NULL;
+
+ return 1;
+}
+
+static int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
+ const char *e, *f;
+ char *c, *t;
+ int r;
+
+ /* Implements fallback mappings for all fields we don't know */
+
+ for (e = *p; e < *p + 16; e++) {
+
+ if (*e == 0 || *e == ' ')
+ return 0;
+
+ if (*e == '=')
+ break;
+
+ if (!((*e >= 'a' && *e <= 'z') ||
+ (*e >= 'A' && *e <= 'Z') ||
+ (*e >= '0' && *e <= '9') ||
+ (*e == '_')))
+ return 0;
+ }
+
+ if (e <= *p || e >= *p + 16)
+ return 0;
+
+ c = alloca(strlen(prefix) + (e - *p) + 2);
+
+ t = stpcpy(c, prefix);
+ for (f = *p; f < e; f++)
+ *(t++) = *f >= 'a' && *f <= 'z' ? ((*f - 'a') + 'A') : *f;
+ strcpy(t, "=");
+
+ e ++;
+
+ r = map_simple_field(c, &e, iov, n_iov_allocated, n_iov);
+ if (r < 0)
+ return r;
+
+ *p = e;
+ return r;
+}
+
+/* Kernel fields are those occuring in the audit string before
+ * msg='. All of these fields are trusted, hence carry the "_" prefix.
+ * We try to translate the fields we know into our native names. The
+ * other's are generically mapped to _AUDIT_FIELD_XYZ= */
+static const MapField map_fields_kernel[] = {
+
+ /* First, we map certain well-known audit fields into native
+ * well-known fields */
+ { "pid=", "_PID=", map_simple_field },
+ { "ppid=", "_PPID=", map_simple_field },
+ { "uid=", "_UID=", map_simple_field },
+ { "euid=", "_EUID=", map_simple_field },
+ { "fsuid=", "_FSUID=", map_simple_field },
+ { "gid=", "_GID=", map_simple_field },
+ { "egid=", "_EGID=", map_simple_field },
+ { "fsgid=", "_FSGID=", map_simple_field },
+ { "tty=", "_TTY=", map_simple_field },
+ { "ses=", "_AUDIT_SESSION=", map_simple_field },
+ { "auid=", "_AUDIT_LOGINUID=", map_simple_field },
+ { "subj=", "_SELINUX_CONTEXT=", map_simple_field },
+ { "comm=", "_COMM=", map_string_field },
+ { "exe=", "_EXE=", map_string_field },
+ { "proctitle=", "_CMDLINE=", map_string_field },
+
+ /* Some fields don't map to native well-known fields. However,
+ * we know that they are string fields, hence let's undo
+ * string field escaping for them, though we stick to the
+ * generic field names. */
+ { "path=", "_AUDIT_FIELD_PATH=", map_string_field },
+ { "dev=", "_AUDIT_FIELD_DEV=", map_string_field },
+ { "name=", "_AUDIT_FIELD_NAME=", map_string_field },
+ {}
+};
+
+/* Userspace fields are thos occuring in the audit string after
+ * msg='. All of these fields are untrusted, hence carry no "_"
+ * prefix. We map the fields we don't know to AUDIT_FIELD_XYZ= */
+static const MapField map_fields_userspace[] = {
+ { "cwd=", "AUDIT_FIELD_CWD=", map_string_field },
+ { "cmd=", "AUDIT_FIELD_CMD=", map_string_field },
+ { "acct=", "AUDIT_FIELD_ACCT=", map_string_field },
+ { "exe=", "AUDIT_FIELD_EXE=", map_string_field },
+ { "comm=", "AUDIT_FIELD_COMM=", map_string_field },
+ {}
+};
+
+static int map_all_fields(
+ const char *p,
+ const MapField map_fields[],
+ const char *prefix,
+ bool handle_msg,
+ struct iovec **iov,
+ size_t *n_iov_allocated,
+ unsigned *n_iov) {
+
+ int r;
+
+ assert(p);
+ assert(iov);
+ assert(n_iov_allocated);
+ assert(n_iov);
+
+ for (;;) {
+ bool mapped = false;
+ const MapField *m;
+ const char *v;
+
+ p += strspn(p, WHITESPACE);
+
+ if (*p == 0)
+ return 0;
+
+ if (handle_msg) {
+ v = startswith(p, "msg='");
+ if (v) {
+ const char *e;
+ char *c;
+
+ /* Userspace message. It's enclosed in
+ simple quotation marks, is not
+ escaped, but the last field in the
+ line, hence let's remove the
+ quotation mark, and apply the
+ userspace mapping instead of the
+ kernel mapping. */
+
+ e = endswith(v, "'");
+ if (!e)
+ return 0; /* don't continue splitting up if the final quotation mark is missing */
+
+ c = strndupa(v, e - v);
+ return map_all_fields(c, map_fields_userspace, "AUDIT_FIELD_", false, iov, n_iov_allocated, n_iov);
+ }
+ }
+
+ /* Try to map the kernel fields to our own names */
+ for (m = map_fields; m->audit_field; m++) {
+ v = startswith(p, m->audit_field);
+ if (!v)
+ continue;
+
+ r = m->map(m->journal_field, &v, iov, n_iov_allocated, n_iov);
+ if (r < 0) {
+ log_debug("Failed to parse audit array: %s", strerror(-r));
+ return r;
+ }
+
+ if (r > 0) {
+ mapped = true;
+ p = v;
+ break;
+ }
+ }
+
+ if (!mapped) {
+ r = map_generic_field(prefix, &p, iov, n_iov_allocated, n_iov);
+ if (r < 0) {
+ log_debug("Failed to parse audit array: %s", strerror(-r));
+ return r;
+ }
+
+ if (r == 0) {
+ /* Couldn't process as generic field, let's just skip over it */
+ p += strcspn(p, WHITESPACE);
+ }
+ }
+ }
+}
+
+static void process_audit_string(Server *s, int type, const char *data, size_t size, const struct timeval *tv) {
+ _cleanup_free_ struct iovec *iov = NULL;
+ size_t n_iov_allocated = 0;
+ unsigned n_iov = 0, k;
+ uint64_t seconds, msec, id;
+ const char *p;
+ unsigned z;
+ char id_field[sizeof("_AUDIT_ID=") + DECIMAL_STR_MAX(uint64_t)],
+ type_field[sizeof("_AUDIT_TYPE=") + DECIMAL_STR_MAX(int)],
+ source_time_field[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
+ const char *m;
+
+ assert(s);
+
+ if (size <= 0)
+ return;
+
+ if (!data)
+ return;
+
+ /* Note that the input buffer is NUL terminated, but let's
+ * check whether there is a spurious NUL byte */
+ if (memchr(data, 0, size))
+ return;
+
+ p = startswith(data, "audit");
+ if (!p)
+ return;
+
+ if (sscanf(p, "(%" PRIi64 ".%" PRIi64 ":%" PRIi64 "): %n",
+ &seconds,
+ &msec,
+ &id,
+ &k) != 3)
+ return;
+
+ p += k;
+
+ n_iov_allocated = N_IOVEC_META_FIELDS + 5;
+ iov = new(struct iovec, n_iov_allocated);
+ if (!iov) {
+ log_oom();
+ return;
+ }
+
+ IOVEC_SET_STRING(iov[n_iov++], "_TRANSPORT=audit");
+
+ sprintf(source_time_field, "_SOURCE_REALTIME_TIMESTAMP=%" PRIu64,
+ (usec_t) seconds * USEC_PER_SEC + (usec_t) msec * USEC_PER_MSEC);
+ IOVEC_SET_STRING(iov[n_iov++], source_time_field);
+
+ sprintf(type_field, "_AUDIT_TYPE=%i", type);
+ IOVEC_SET_STRING(iov[n_iov++], type_field);
+
+ sprintf(id_field, "_AUDIT_ID=%" PRIu64, id);
+ IOVEC_SET_STRING(iov[n_iov++], id_field);
+
+ m = strappenda("MESSAGE=", data);
+ IOVEC_SET_STRING(iov[n_iov++], m);
+
+ z = n_iov;
+
+ map_all_fields(p, map_fields_kernel, "_AUDIT_FIELD_", true, &iov, &n_iov_allocated, &n_iov);
+
+ if (!GREEDY_REALLOC(iov, n_iov_allocated, n_iov + N_IOVEC_META_FIELDS)) {
+ log_oom();
+ goto finish;
+ }
+
+ server_dispatch_message(s, iov, n_iov, n_iov_allocated, NULL, tv, NULL, 0, NULL, LOG_NOTICE, 0);
+
+finish:
+ /* free() all entries that map_all_fields() added. All others
+ * are allocated on the stack or are constant. */
+
+ for (; z < n_iov; z++)
+ free(iov[z].iov_base);
+}
+
+void server_process_audit_message(
+ Server *s,
+ const void *buffer,
+ size_t buffer_size,
+ const struct ucred *ucred,
+ const struct timeval *tv,
+ const union sockaddr_union *sa,
+ socklen_t salen) {
+
+ const struct nlmsghdr *nl = buffer;
+
+ assert(s);
+
+ if (buffer_size < ALIGN(sizeof(struct nlmsghdr)))
+ return;
+
+ assert(buffer);
+
+ /* Filter out fake data */
+ if (!sa ||
+ salen != sizeof(struct sockaddr_nl) ||
+ sa->nl.nl_family != AF_NETLINK ||
+ sa->nl.nl_pid != 0) {
+ log_debug("Audit netlink message from invalid sender.");
+ return;
+ }
+
+ if (!ucred || ucred->pid != 0) {
+ log_debug("Audit netlink message with invalid credentials.");
+ return;
+ }
+
+ if (!NLMSG_OK(nl, buffer_size)) {
+ log_error("Audit netlink message truncated.");
+ return;
+ }
+
+ /* Ignore special Netlink messages */
+ if (IN_SET(nl->nlmsg_type, NLMSG_NOOP, NLMSG_ERROR))
+ return;
+
+ /* Below AUDIT_FIRST_USER_MSG theer are only control messages, let's ignore those */
+ if (nl->nlmsg_type < AUDIT_FIRST_USER_MSG)
+ return;
+
+ process_audit_string(s, nl->nlmsg_type, NLMSG_DATA(nl), nl->nlmsg_len - ALIGN(sizeof(struct nlmsghdr)), tv);
+}
+
+int server_open_audit(Server *s) {
+ static const int one = 1;
+ int r;
+
+ if (s->audit_fd < 0) {
+ static const union sockaddr_union sa = {
+ .nl.nl_family = AF_NETLINK,
+ .nl.nl_pid = 0,
+ .nl.nl_groups = AUDIT_NLGRP_READLOG,
+ };
+
+ s->audit_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
+ if (s->audit_fd < 0) {
+ if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
+ log_debug("Audit not supported in the kernel.");
+ else
+ log_warning("Failed to create audit socket, ignoring: %m");
+
+ return 0;
+ }
+
+ r = bind(s->audit_fd, &sa.sa, sizeof(sa.nl));
+ if (r < 0) {
+ log_error("Failed to join audit multicast group: %m");
+ return -errno;
+ }
+ } else
+ fd_nonblock(s->audit_fd, 1);
+
+ r = setsockopt(s->audit_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+ if (r < 0) {
+ log_error("Failed to set SO_PASSCRED on audit socket: %m");
+ return -errno;
+ }
+
+ r = setsockopt(s->audit_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
+ if (r < 0) {
+ log_error("Failed to set SO_TIMESTAMP on audit socket: %m");
+ return -errno;
+ }
+
+ r = sd_event_add_io(s->event, &s->audit_event_source, s->audit_fd, EPOLLIN, process_datagram, s);
+ if (r < 0) {
+ log_error("Failed to add audit fd to event loop: %s", strerror(-r));
+ return r;
+ }
+
+ return 0;
+}
diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h
new file mode 100644
index 0000000..29bff07
--- /dev/null
+++ b/src/journal/journald-audit.h
@@ -0,0 +1,29 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "socket-util.h"
+#include "journald-server.h"
+
+void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const struct timeval *tv, const union sockaddr_union *sa, socklen_t salen);
+
+int server_open_audit(Server*s);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index ac6dc36..e062427 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -50,6 +50,7 @@
#include "journald-stream.h"
#include "journald-console.h"
#include "journald-native.h"
+#include "journald-audit.h"
#include "journald-server.h"
#ifdef HAVE_ACL
@@ -1112,7 +1113,7 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
Server *s = userdata;
assert(s);
- assert(fd == s->native_fd || fd == s->syslog_fd);
+ assert(fd == s->native_fd || fd == s->syslog_fd || fd == s->audit_fd);
if (revents != EPOLLIN) {
log_error("Got invalid event from epoll for datagram fd: %"PRIx32, revents);
@@ -1142,28 +1143,37 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
CMSG_SPACE(sizeof(int)) + /* fd */
CMSG_SPACE(NAME_MAX)]; /* selinux label */
} control = {};
+ union sockaddr_union sa = {};
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = &control,
.msg_controllen = sizeof(control),
+ .msg_name = &sa,
+ .msg_namelen = sizeof(sa),
};
ssize_t n;
- int v;
int *fds = NULL;
unsigned n_fds = 0;
+ int v = 0;
+ size_t m;
- if (ioctl(fd, SIOCINQ, &v) < 0) {
- log_error("SIOCINQ failed: %m");
- return -errno;
- }
+ /* Try to get the right size, if we can. (Not all
+ * sockets support SIOCINQ, hence we just try, but
+ * don't rely on it. */
+ (void) ioctl(fd, SIOCINQ, &v);
+
+ /* Fix it up, if it is too small. We use the same fixed value as auditd here. Awful!*/
+ m = PAGE_ALIGN(MAX3((size_t) v + 1,
+ (size_t) LINE_MAX,
+ ALIGN(sizeof(struct nlmsghdr)) + ALIGN((size_t) MAX_AUDIT_MESSAGE_LENGTH)) + 1);
- if (!GREEDY_REALLOC(s->buffer, s->buffer_size, LINE_MAX + (size_t) v))
+ if (!GREEDY_REALLOC(s->buffer, s->buffer_size, m))
return log_oom();
iovec.iov_base = s->buffer;
- iovec.iov_len = s->buffer_size;
+ iovec.iov_len = s->buffer_size - 1; /* Leave room for trailing NUL we add later */
n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (n < 0) {
@@ -1195,20 +1205,30 @@ int process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userda
}
}
+ /* And a trailing NUL, just in case */
+ s->buffer[n] = 0;
+
if (fd == s->syslog_fd) {
- if (n > 0 && n_fds == 0) {
- s->buffer[n] = 0;
+ if (n > 0 && n_fds == 0)
server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
- } else if (n_fds > 0)
+ else if (n_fds > 0)
log_warning("Got file descriptors via syslog socket. Ignoring.");
- } else {
+ } else if (fd == s->native_fd) {
if (n > 0 && n_fds == 0)
server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
else if (n == 0 && n_fds == 1)
server_process_native_file(s, fds[0], ucred, tv, label, label_len);
else if (n_fds > 0)
log_warning("Got too many file descriptors via native socket. Ignoring.");
+
+ } else {
+ assert(fd == s->audit_fd);
+
+ if (n > 0 && n_fds == 0)
+ server_process_audit_message(s, s->buffer, n, ucred, tv, &sa, msghdr.msg_namelen);
+ else if (n_fds > 0)
+ log_warning("Got file descriptors via audit socket. Ignoring.");
}
close_many(fds, n_fds);
@@ -1452,7 +1472,7 @@ int server_init(Server *s) {
assert(s);
zero(*s);
- s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->hostname_fd = -1;
+ s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->audit_fd = s->hostname_fd = -1;
s->compress = true;
s->seal = true;
@@ -1537,6 +1557,15 @@ int server_init(Server *s) {
s->syslog_fd = fd;
+ } else if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
+
+ if (s->audit_fd >= 0) {
+ log_error("Too many audit sockets passed.");
+ return -EINVAL;
+ }
+
+ s->audit_fd = fd;
+
} else {
log_error("Unknown socket passed.");
return -EINVAL;
@@ -1559,6 +1588,10 @@ int server_init(Server *s) {
if (r < 0)
return r;
+ r = server_open_audit(s);
+ if (r < 0)
+ return r;
+
r = server_open_kernel_seqnum(s);
if (r < 0)
return r;
@@ -1632,6 +1665,7 @@ void server_done(Server *s) {
sd_event_source_unref(s->native_event_source);
sd_event_source_unref(s->stdout_event_source);
sd_event_source_unref(s->dev_kmsg_event_source);
+ sd_event_source_unref(s->audit_event_source);
sd_event_source_unref(s->sync_event_source);
sd_event_source_unref(s->sigusr1_event_source);
sd_event_source_unref(s->sigusr2_event_source);
@@ -1644,6 +1678,7 @@ void server_done(Server *s) {
safe_close(s->native_fd);
safe_close(s->stdout_fd);
safe_close(s->dev_kmsg_fd);
+ safe_close(s->audit_fd);
safe_close(s->hostname_fd);
if (s->rate_limit)
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 65a2b71..9c7fa50 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -59,6 +59,7 @@ typedef struct Server {
int native_fd;
int stdout_fd;
int dev_kmsg_fd;
+ int audit_fd;
int hostname_fd;
sd_event *event;
@@ -67,6 +68,7 @@ typedef struct Server {
sd_event_source *native_event_source;
sd_event_source *stdout_event_source;
sd_event_source *dev_kmsg_event_source;
+ sd_event_source *audit_event_source;
sd_event_source *sync_event_source;
sd_event_source *sigusr1_event_source;
sd_event_source *sigusr2_event_source;
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 0d7c559..cc81c98 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -33,6 +33,7 @@
#include <linux/input.h>
#include <linux/if_link.h>
#include <linux/loop.h>
+#include <linux/audit.h>
#ifdef HAVE_AUDIT
#include <libaudit.h>
@@ -557,3 +558,11 @@ static inline int setns(int fd, int nstype) {
#ifndef LOOPBACK_IFINDEX
#define LOOPBACK_IFINDEX 1
#endif
+
+#ifndef MAX_AUDIT_MESSAGE_LENGTH
+#define MAX_AUDIT_MESSAGE_LENGTH 8970
+#endif
+
+#ifndef AUDIT_NLGRP_MAX
+#define AUDIT_NLGRP_READLOG 1
+#endif
diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket
new file mode 100644
index 0000000..ce849da
--- /dev/null
+++ b/units/systemd-journald-audit.socket
@@ -0,0 +1,18 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Journal Audit Socket
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+Service=systemd-journald.service
+ReceiveBuffer=128M
+ListenNetlink=audit 1
+PassCredentials=yes
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 4de38fa..7ee67fd 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -10,17 +10,17 @@ Description=Journal Service
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Requires=systemd-journald.socket
-After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket
+After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket
Before=sysinit.target
[Service]
-Sockets=systemd-journald.socket systemd-journald-dev-log.socket
+Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket
ExecStart=@rootlibexecdir@/systemd-journald
Restart=always
RestartSec=0
NotifyAccess=all
StandardOutput=null
-CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
WatchdogSec=1min
# Increase the default a bit in order to allow many simultaneous
commit 8457f8d6ac7adc6c6ef31378e6e7761cce522141
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 20:24:43 2014 +0100
journald: remove a number of malloc()s from the syslog message handling
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 4725031..ce6c2a3 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -356,11 +356,13 @@ void server_process_syslog_message(
const char *label,
size_t label_len) {
- char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
+ char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
+ syslog_facility[sizeof("SYSLOG_FACILITY") + DECIMAL_STR_MAX(int)];
+ const char *message = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
struct iovec iovec[N_IOVEC_META_FIELDS + 6];
unsigned n = 0;
int priority = LOG_USER | LOG_INFO;
- char *identifier = NULL, *pid = NULL;
+ _cleanup_free_ char *identifier = NULL, *pid = NULL;
const char *orig;
assert(s);
@@ -386,38 +388,31 @@ void server_process_syslog_message(
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
- if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
- IOVEC_SET_STRING(iovec[n++], syslog_priority);
+ sprintf(syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK);
+ IOVEC_SET_STRING(iovec[n++], syslog_priority);
- if (priority & LOG_FACMASK)
- if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
- IOVEC_SET_STRING(iovec[n++], syslog_facility);
+ if (priority & LOG_FACMASK) {
+ sprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
+ IOVEC_SET_STRING(iovec[n++], syslog_facility);
+ }
if (identifier) {
- syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
+ syslog_identifier = strappenda("SYSLOG_IDENTIFIER=", identifier);
if (syslog_identifier)
IOVEC_SET_STRING(iovec[n++], syslog_identifier);
}
if (pid) {
- syslog_pid = strappend("SYSLOG_PID=", pid);
+ syslog_pid = strappenda("SYSLOG_PID=", pid);
if (syslog_pid)
IOVEC_SET_STRING(iovec[n++], syslog_pid);
}
- message = strappend("MESSAGE=", buf);
+ message = strappenda("MESSAGE=", buf);
if (message)
IOVEC_SET_STRING(iovec[n++], message);
server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, label, label_len, NULL, priority, 0);
-
- free(message);
- free(identifier);
- free(pid);
- free(syslog_priority);
- free(syslog_facility);
- free(syslog_identifier);
- free(syslog_pid);
}
int server_open_syslog_socket(Server *s) {
commit 3b3154df7e2773332bb814e167187367a0ccae4a
Author: Lennart Poettering <lennart at poettering.net>
Date: Sun Nov 2 21:46:42 2014 +0100
journald: constify all things!
diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c
index 6ec2528..19d077a 100644
--- a/src/journal/journald-console.c
+++ b/src/journal/journald-console.c
@@ -48,7 +48,7 @@ void server_forward_console(
int priority,
const char *identifier,
const char *message,
- struct ucred *ucred) {
+ const struct ucred *ucred) {
struct iovec iovec[5];
char header_pid[16];
diff --git a/src/journal/journald-console.h b/src/journal/journald-console.h
index aa8e657..d8af226 100644
--- a/src/journal/journald-console.h
+++ b/src/journal/journald-console.h
@@ -23,4 +23,4 @@
#include "journald-server.h"
-void server_forward_console(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
+void server_forward_console(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred);
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index fb8ea08..126126b 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -37,7 +37,7 @@ void server_forward_kmsg(
int priority,
const char *identifier,
const char *message,
- struct ucred *ucred) {
+ const struct ucred *ucred) {
struct iovec iovec[5];
char header_priority[6], header_pid[16];
@@ -104,7 +104,7 @@ static bool is_us(const char *pid) {
return t == getpid();
}
-static void dev_kmsg_record(Server *s, char *p, size_t l) {
+static void dev_kmsg_record(Server *s, const char *p, size_t l) {
struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
int priority, r;
diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h
index f60f605..9a9d089 100644
--- a/src/journal/journald-kmsg.h
+++ b/src/journal/journald-kmsg.h
@@ -26,6 +26,6 @@
int server_open_dev_kmsg(Server *s);
int server_flush_dev_kmsg(Server *s);
-void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
+void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred);
int server_open_kernel_seqnum(Server *s);
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index ace8d5c..3c60b22 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -70,15 +70,15 @@ bool valid_user_field(const char *p, size_t l, bool allow_protected) {
return true;
}
-static bool allow_object_pid(struct ucred *ucred) {
+static bool allow_object_pid(const struct ucred *ucred) {
return ucred && ucred->uid == 0;
}
void server_process_native_message(
Server *s,
const void *buffer, size_t buffer_size,
- struct ucred *ucred,
- struct timeval *tv,
+ const struct ucred *ucred,
+ const struct timeval *tv,
const char *label, size_t label_len) {
struct iovec *iovec = NULL;
@@ -303,8 +303,8 @@ finish:
void server_process_native_file(
Server *s,
int fd,
- struct ucred *ucred,
- struct timeval *tv,
+ const struct ucred *ucred,
+ const struct timeval *tv,
const char *label, size_t label_len) {
struct stat st;
@@ -412,7 +412,8 @@ void server_process_native_file(
}
int server_open_native_socket(Server*s) {
- int one, r;
+ static const int one = 1;
+ int r;
assert(s);
@@ -440,7 +441,6 @@ int server_open_native_socket(Server*s) {
} else
fd_nonblock(s->native_fd, 1);
- one = 1;
r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
if (r < 0) {
log_error("SO_PASSCRED failed: %m");
@@ -449,14 +449,12 @@ int server_open_native_socket(Server*s) {
#ifdef HAVE_SELINUX
if (mac_selinux_use()) {
- one = 1;
r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning("SO_PASSSEC failed: %m");
}
#endif
- one = 1;
r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
if (r < 0) {
log_error("SO_TIMESTAMP failed: %m");
diff --git a/src/journal/journald-native.h b/src/journal/journald-native.h
index e82a5b8..2f9d458 100644
--- a/src/journal/journald-native.h
+++ b/src/journal/journald-native.h
@@ -30,8 +30,8 @@
bool valid_user_field(const char *p, size_t l, bool allow_protected);
-void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+void server_process_native_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
-void server_process_native_file(Server *s, int fd, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+void server_process_native_file(Server *s, int fd, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
int server_open_native_socket(Server*s);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 12735c4..ac6dc36 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -537,8 +537,8 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
static void dispatch_message_real(
Server *s,
struct iovec *iovec, unsigned n, unsigned m,
- struct ucred *ucred,
- struct timeval *tv,
+ const struct ucred *ucred,
+ const struct timeval *tv,
const char *label, size_t label_len,
const char *unit_id,
int priority,
@@ -855,8 +855,8 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
void server_dispatch_message(
Server *s,
struct iovec *iovec, unsigned n, unsigned m,
- struct ucred *ucred,
- struct timeval *tv,
+ const struct ucred *ucred,
+ const struct timeval *tv,
const char *label, size_t label_len,
const char *unit_id,
int priority,
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 6888187..65a2b71 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -148,7 +148,7 @@ typedef struct Server {
#define N_IOVEC_UDEV_FIELDS 32
#define N_IOVEC_OBJECT_FIELDS 11
-void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority, pid_t object_pid);
+void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority, pid_t object_pid);
void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_(3,4);
/* gperf lookup function */
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 79c07ff..4725031 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -35,7 +35,7 @@
/* Warn once every 30s if we missed syslog message */
#define WARN_FORWARD_SYSLOG_MISSED_USEC (30 * USEC_PER_SEC)
-static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
+static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, const struct ucred *ucred, const struct timeval *tv) {
static const union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
@@ -109,7 +109,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
log_debug("Failed to forward syslog message: %m");
}
-static void forward_syslog_raw(Server *s, int priority, const char *buffer, struct ucred *ucred, struct timeval *tv) {
+static void forward_syslog_raw(Server *s, int priority, const char *buffer, const struct ucred *ucred, const struct timeval *tv) {
struct iovec iovec;
assert(s);
@@ -122,7 +122,7 @@ static void forward_syslog_raw(Server *s, int priority, const char *buffer, stru
forward_syslog_iovec(s, &iovec, 1, ucred, tv);
}
-void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) {
+void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv) {
struct iovec iovec[5];
char header_priority[6], header_time[64], header_pid[16];
int n = 0;
@@ -351,8 +351,8 @@ static void syslog_skip_date(char **buf) {
void server_process_syslog_message(
Server *s,
const char *buf,
- struct ucred *ucred,
- struct timeval *tv,
+ const struct ucred *ucred,
+ const struct timeval *tv,
const char *label,
size_t label_len) {
@@ -421,7 +421,8 @@ void server_process_syslog_message(
}
int server_open_syslog_socket(Server *s) {
- int one, r;
+ static const int one = 1;
+ int r;
assert(s);
@@ -449,7 +450,6 @@ int server_open_syslog_socket(Server *s) {
} else
fd_nonblock(s->syslog_fd, 1);
- one = 1;
r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
if (r < 0) {
log_error("SO_PASSCRED failed: %m");
@@ -458,14 +458,12 @@ int server_open_syslog_socket(Server *s) {
#ifdef HAVE_SELINUX
if (mac_selinux_use()) {
- one = 1;
r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning("SO_PASSSEC failed: %m");
}
#endif
- one = 1;
r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
if (r < 0) {
log_error("SO_TIMESTAMP failed: %m");
diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h
index 057ea79..25f8988 100644
--- a/src/journal/journald-syslog.h
+++ b/src/journal/journald-syslog.h
@@ -28,9 +28,9 @@ int syslog_fixup_facility(int priority) _const_;
void syslog_parse_priority(const char **p, int *priority, bool with_facility);
size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid);
-void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv);
+void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv);
-void server_process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv, const char *label, size_t label_len);
+void server_process_syslog_message(Server *s, const char *buf, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
int server_open_syslog_socket(Server *s);
void server_maybe_warn_forward_syslog_missed(Server *s);
diff --git a/src/journal/journald-wall.c b/src/journal/journald-wall.c
index fcbd918..1bdddb0 100644
--- a/src/journal/journald-wall.c
+++ b/src/journal/journald-wall.c
@@ -28,7 +28,7 @@ void server_forward_wall(
int priority,
const char *identifier,
const char *message,
- struct ucred *ucred) {
+ const struct ucred *ucred) {
_cleanup_free_ char *ident_buf = NULL, *l_buf = NULL;
const char *l;
diff --git a/src/journal/journald-wall.h b/src/journal/journald-wall.h
index 93c3cec..45c5285 100644
--- a/src/journal/journald-wall.h
+++ b/src/journal/journald-wall.h
@@ -23,4 +23,4 @@
#include "journald-server.h"
-void server_forward_wall(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred);
+void server_forward_wall(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred);
More information about the systemd-commits
mailing list