journald-native.c revision be2155ce705c1c1a25fa5b2927e2e02f4b3c7a35
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering/***
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering This file is part of systemd.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Copyright 2011 Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is free software; you can redistribute it and/or modify it
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering under the terms of the GNU Lesser General Public License as published by
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering (at your option) any later version.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering systemd is distributed in the hope that it will be useful, but
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Lesser General Public License for more details.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering You should have received a copy of the GNU Lesser General Public License
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering***/
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <unistd.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <stddef.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include <sys/epoll.h>
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include "socket-util.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "path-util.h"
73f860db9893deab6aebceb53dd7d0deb662e832Zbigniew Jędrzejewski-Szmek#include "journald-server.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "journald-native.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "journald-kmsg.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "journald-console.h"
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#include "journald-syslog.h"
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering
6482f6269c87d2249e52e889a63adbdd50f2d691Ronny Chevalier#define ENTRY_SIZE_MAX (1024*1024*64)
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier#define DATA_SIZE_MAX (1024*1024*64)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringstatic bool valid_user_field(const char *p, size_t l) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *a;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* We kinda enforce POSIX syntax recommendations for
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering environment variables here, but make a couple of additional
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering requirements.
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
3b97fcbd28f92a1e51887fef5de8844a89bde523Lennart Poettering
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek /* No empty field names */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (l <= 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return false;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Don't allow names longer than 64 chars */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (l > 64)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return false;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Variables starting with an underscore are protected */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (p[0] == '_')
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return false;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Don't allow digits as first character */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (p[0] >= '0' && p[0] <= '9')
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return false;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Only allow A-Z0-9 and '_' */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering for (a = p; a < p + l; a++)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!((*a >= 'A' && *a <= 'Z') ||
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering (*a >= '0' && *a <= '9') ||
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek *a == '_'))
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return false;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return true;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringvoid server_process_native_message(
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering Server *s,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const void *buffer, size_t buffer_size,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct ucred *ucred,
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek struct timeval *tv,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *label, size_t label_len) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct iovec *iovec = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering unsigned n = 0, m = 0, j, tn = (unsigned) -1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *p;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering size_t remaining;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int priority = LOG_INFO;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char *identifier = NULL, *message = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(s);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(buffer || buffer_size == 0);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p = buffer;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering remaining = buffer_size;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt while (remaining > 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *e, *q;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering e = memchr(p, '\n', remaining);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!e) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Trailing noise, let's ignore it, and flush what we collected */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Received message with trailing noise, ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (e == p) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Entry separator */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering n = 0;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering priority = LOG_INFO;
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p++;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering remaining--;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering continue;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (*p == '.' || *p == '#') {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Ignore control commands for now, and
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * comments too. */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering remaining -= (e - p) + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p = e + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering continue;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* A property follows */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (n+N_IOVEC_META_FIELDS >= m) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct iovec *c;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering unsigned u;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering c = realloc(iovec, u * sizeof(struct iovec));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!c) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_oom();
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering iovec = c;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering m = u;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering q = memchr(p, '=', e - p);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (q) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (valid_user_field(p, q - p)) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering size_t l;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering l = e - p;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* If the field name starts with an
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * underscore, skip the variable,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * since that indidates a trusted
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * field */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering iovec[n].iov_base = (char*) p;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering iovec[n].iov_len = l;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering n++;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* We need to determine the priority
507f22bd0172bff5e5d98145b1419bd472a2c57fZbigniew Jędrzejewski-Szmek * of this entry for the rate limiting
b9c488f60050248b35640f28e4d00958702ba1c3Eelco Dolstra * logic */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (l == 10 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcmp(p, "PRIORITY=", 9) == 0 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p[9] >= '0' && p[9] <= '9')
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering priority = (priority & LOG_FACMASK) | (p[9] - '0');
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else if (l == 17 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p[16] >= '0' && p[16] <= '9')
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else if (l == 18 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p[16] >= '0' && p[16] <= '9' &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p[17] >= '0' && p[17] <= '9')
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else if (l >= 19 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char *t;
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering t = strndup(p + 18, l - 18);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (t) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(identifier);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering identifier = t;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering } else if (l >= 8 &&
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcmp(p, "MESSAGE=", 8) == 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char *t;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering t = strndup(p + 8, l - 8);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (t) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(message);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering message = t;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
dc61b7e45d89a69f0469ab7b3289cdde7fcc55abTorstein Husebø
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering remaining -= (e - p) + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p = e + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering continue;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering } else {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering le64_t l_le;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering uint64_t l;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering char *k;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Failed to parse message, ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcpy(&l_le, e + 1, sizeof(uint64_t));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering l = le64toh(l_le);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (l > DATA_SIZE_MAX) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Received binary data block too large, ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering e[1+sizeof(uint64_t)+l] != '\n') {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Failed to parse message, ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering k = malloc((e - p) + 1 + l);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!k) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_oom();
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering break;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcpy(k, p, e - p);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering k[e - p] = '=';
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (valid_user_field(p, e - p)) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering iovec[n].iov_base = k;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering iovec[n].iov_len = (e - p) + 1 + l;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering n++;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering } else
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(k);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p = e + 1 + sizeof(uint64_t) + l + 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (n <= 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering goto finish;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering tn = n++;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (message) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (s->forward_to_syslog)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_forward_syslog(s, priority, identifier, message, ucred, tv);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (s->forward_to_kmsg)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_forward_kmsg(s, priority, identifier, message, ucred);
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek if (s->forward_to_console)
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek server_forward_console(s, priority, identifier, message, ucred);
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek }
4b94f3b8f7693f076e5c85bc2c02cf028192d8deZbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringfinish:
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering for (j = 0; j < n; j++) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (j == tn)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering continue;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (iovec[j].iov_base < buffer ||
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
e9f600f2fb4b0df55c7a8fb4b4d09f9979997223Lennart Poettering free(iovec[j].iov_base);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(iovec);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(identifier);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering free(message);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletarvoid server_process_native_file(
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar Server *s,
36dd072cdf03dcac0fcd2d6b42f261444dc7ac88Michal Sekletar int fd,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct ucred *ucred,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct timeval *tv,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *label, size_t label_len) {
e88baee88fad8bc59d33b55a7a2d640ef9e16cd6Zbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct stat st;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_free_ void *p = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering ssize_t n;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(s);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(fd >= 0);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!ucred || ucred->uid != 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering _cleanup_free_ char *sl = NULL, *k = NULL;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering const char *e;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_oom();
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = readlink_malloc(sl, &k);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (r < 0) {
527b7a421ff3927d4f3f170b1b143452e88ae1dcLennart Poettering log_error("readlink(%s) failed: %m", sl);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering e = path_startswith(k, "/dev/shm/");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!e)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering e = path_startswith(k, "/tmp/");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!e)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering e = path_startswith(k, "/var/tmp/");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!e) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("Received file outside of allowed directories. Refusing.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!filename_is_safe(e)) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("Received file in subdirectory of allowed directories. Refusing.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* Data is in the passed file, since it didn't fit in a
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * datagram. We can't map the file here, since clients might
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * then truncate it and trigger a SIGBUS for us. So let's
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering * stupidly read it */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (fstat(fd, &st) < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("Failed to stat passed file, ignoring: %m");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!S_ISREG(st.st_mode)) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("File passed is not regular. Ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (st.st_size <= 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (st.st_size > ENTRY_SIZE_MAX) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("File passed too large. Ignoring.");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering p = malloc(st.st_size);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (!p) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_oom();
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering n = pread(fd, p, st.st_size, 0);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (n < 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("Failed to read file, ignoring: %s", strerror(-n));
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering else if (n > 0)
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering server_process_native_message(s, p, n, ucred, tv, label, label_len);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering}
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poetteringint server_open_native_socket(Server*s) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering union sockaddr_union sa;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering int one, r;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering struct epoll_event ev;
2b43f939a4b3ad5aeb2650868b0234ff42ec0045Lennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering assert(s);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (s->native_fd < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (s->native_fd < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("socket() failed: %m");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -errno;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering zero(sa);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering sa.un.sun_family = AF_UNIX;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering unlink(sa.un.sun_path);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("bind() failed: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return -errno;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering chmod(sa.un.sun_path, 0666);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering } else
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering fd_nonblock(s->native_fd, 1);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering one = 1;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("SO_PASSCRED failed: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return -errno;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#ifdef HAVE_SELINUX
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering one = 1;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
445ea9be520b9549aee45d0b6427cf48b446987fLennart Poettering if (r < 0)
445ea9be520b9549aee45d0b6427cf48b446987fLennart Poettering log_warning("SO_PASSSEC failed: %m");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering#endif
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering one = 1;
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (r < 0) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_error("SO_TIMESTAMP failed: %m");
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering return -errno;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering zero(ev);
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering ev.events = EPOLLIN;
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering ev.data.fd = s->native_fd;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error("Failed to add native server fd to epoll object: %m");
c0f71f469fef3f3a0822e0021085e6d165df2b46Lennart Poettering return -errno;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering}
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt