journald-native.c revision 4871690d9e32608bbd9b18505b5326c2079c9690
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/***
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2011 Lennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering***/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <unistd.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <stddef.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/epoll.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "socket-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-native.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-kmsg.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-console.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-syslog.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#define ENTRY_SIZE_MAX (1024*1024*32)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic bool valid_user_field(const char *p, size_t l) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers const char *a;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We kinda enforce POSIX syntax recommendations for
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering environment variables here, but make a couple of additional
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering requirements.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering /* No empty field names */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (l <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers /* Don't allow names longer than 64 chars */
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallace if (l > 64)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Variables starting with an underscore are protected */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (p[0] == '_')
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Don't allow digits as first character */
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer if (p[0] >= '0' && p[0] <= '9')
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Only allow A-Z0-9 and '_' */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (a = p; a < p + l; a++)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!((*a >= 'A' && *a <= 'Z') ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (*a >= '0' && *a <= '9') ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *a == '_'))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering return true;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_process_native_message(
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Server *s,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const void *buffer, size_t buffer_size,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct ucred *ucred,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct timeval *tv,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *label, size_t label_len) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct iovec *iovec = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned n = 0, m = 0, j, tn = (unsigned) -1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *p;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering size_t remaining;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int priority = LOG_INFO;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *identifier = NULL, *message = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(buffer || buffer_size == 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = buffer;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering remaining = buffer_size;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering while (remaining > 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *e, *q;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e = memchr(p, '\n', remaining);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!e) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Trailing noise, let's ignore it, and flush what we collected */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Received message with trailing noise, ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (e == p) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Entry separator */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering n = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering priority = LOG_INFO;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p++;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers remaining--;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek continue;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (*p == '.' || *p == '#') {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* Ignore control commands for now, and
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * comments too. */
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers remaining -= (e - p) + 1;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers p = e + 1;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers continue;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers /* A property follows */
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (n+N_IOVEC_META_FIELDS >= m) {
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers struct iovec *c;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned u;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers c = realloc(iovec, u * sizeof(struct iovec));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (!c) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_oom();
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers break;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering iovec = c;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers m = u;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers q = memchr(p, '=', e - p);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (q) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (valid_user_field(p, q - p)) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers size_t l;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers l = e - p;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* If the field name starts with an
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * underscore, skip the variable,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * since that indidates a trusted
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * field */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering iovec[n].iov_base = (char*) p;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering iovec[n].iov_len = l;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering n++;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We need to determine the priority
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * of this entry for the rate limiting
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * logic */
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (l == 10 &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers memcmp(p, "PRIORITY=", 9) == 0 &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers p[9] >= '0' && p[9] <= '9')
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering priority = (priority & LOG_FACMASK) | (p[9] - '0');
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers else if (l == 17 &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p[16] >= '0' && p[16] <= '9')
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers else if (l == 18 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers p[16] >= '0' && p[16] <= '9' &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers p[17] >= '0' && p[17] <= '9')
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (l >= 19 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers char *t;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering t = strndup(p + 18, l - 18);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (t) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(identifier);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering identifier = t;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else if (l >= 8 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcmp(p, "MESSAGE=", 8) == 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *t;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering t = strndup(p + 8, l - 8);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (t) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(message);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering message = t;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering remaining -= (e - p) + 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = e + 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering le64_t l_le;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uint64_t l;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *k;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Failed to parse message, ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcpy(&l_le, e + 1, sizeof(uint64_t));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering l = le64toh(l_le);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e[1+sizeof(uint64_t)+l] != '\n') {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Failed to parse message, ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering k = malloc((e - p) + 1 + l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!k) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcpy(k, p, e - p);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna k[e - p] = '=';
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (valid_user_field(p, e - p)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering iovec[n].iov_base = k;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering iovec[n].iov_len = (e - p) + 1 + l;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering n++;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(k);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = e + 1 + sizeof(uint64_t) + l + 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (n <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering tn = n++;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (message) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->forward_to_syslog)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_syslog(s, priority, identifier, message, ucred, tv);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->forward_to_kmsg)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_kmsg(s, priority, identifier, message, ucred);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->forward_to_console)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_console(s, priority, identifier, message, ucred);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringfinish:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (j = 0; j < n; j++) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (j == tn)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
2f7a4867babd3fd382e5495f21724358f30fa67dMichal Sekletar
2f7a4867babd3fd382e5495f21724358f30fa67dMichal Sekletar if (iovec[j].iov_base < buffer ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(iovec[j].iov_base);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(iovec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(identifier);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(message);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poetteringvoid server_process_native_file(
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering Server *s,
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering int fd,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct ucred *ucred,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct timeval *tv,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *label, size_t label_len) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct stat st;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering void *p;
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek ssize_t n;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(fd >= 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Data is in the passed file, since it didn't fit in a
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * datagram. We can't map the file here, since clients might
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna * then truncate it and trigger a SIGBUS for us. So let's
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna * stupidly read it */
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (fstat(fd, &st) < 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to stat passed file, ignoring: %m");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (!S_ISREG(st.st_mode)) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("File passed is not regular. Ignoring.");
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer return;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (st.st_size <= 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (st.st_size > ENTRY_SIZE_MAX) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("File passed too large. Ignoring.");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna p = malloc(st.st_size);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (!p) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_oom();
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna n = pread(fd, p, st.st_size, 0);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (n < 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to read file, ignoring: %s", strerror(-n));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna else if (n > 0)
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek server_process_native_message(s, p, n, ucred, tv, label, label_len);
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna free(p);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek}
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmekint server_open_native_socket(Server*s) {
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek union sockaddr_union sa;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna int one, r;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna struct epoll_event ev;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna assert(s);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
8333c77edf8fd1654cd96f3f6ee0f078dd64b58bZbigniew Jędrzejewski-Szmek if (s->native_fd < 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (s->native_fd < 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("socket() failed: %m");
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek return -errno;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers zero(sa);
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek sa.un.sun_family = AF_UNIX;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna unlink(sa.un.sun_path);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (r < 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("bind() failed: %m");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return -errno;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna chmod(sa.un.sun_path, 0666);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna } else
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna fd_nonblock(s->native_fd, 1);
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna one = 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek if (r < 0) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("SO_PASSCRED failed: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -errno;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_SELINUX
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering one = 1;
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_warning("SO_PASSSEC failed: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers one = 1;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("SO_TIMESTAMP failed: %m");
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering return -errno;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering zero(ev);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ev.events = EPOLLIN;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ev.data.fd = s->native_fd;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to add native server fd to epoll object: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -errno;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering