journald-native.c revision d18d46ecea80a7f07415edb9264af6a254fd70bb
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/***
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2011 Lennart Poettering
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer under the terms of the GNU Lesser General Public License as published by
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt Lesser General Public License for more details.
c50a4525aa8151b180d5a325e88c5f3812e66c36Martin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier***/
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <unistd.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <stddef.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/epoll.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "socket-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "path-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "selinux-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-server.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-native.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-kmsg.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-console.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-syslog.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "journald-wall.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierbool valid_user_field(const char *p, size_t l, bool allow_protected) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *a;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier /* We kinda enforce POSIX syntax recommendations for
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier environment variables here, but make a couple of additional
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier requirements.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* No empty field names */
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer if (l <= 0)
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer return false;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer /* Don't allow names longer than 64 chars */
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer if (l > 64)
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer return false;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer /* Variables starting with an underscore are protected */
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin if (!allow_protected && p[0] == '_')
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin return false;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin /* Don't allow digits as first character */
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin if (p[0] >= '0' && p[0] <= '9')
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return false;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier /* Only allow A-Z0-9 and '_' */
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier for (a = p; a < p + l; a++)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if ((*a < 'A' || *a > 'Z') &&
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier (*a < '0' || *a > '9') &&
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier *a != '_')
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return false;
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return true;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier}
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic bool allow_object_pid(struct ucred *ucred) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return ucred && ucred->uid == 0;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier}
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevaliervoid server_process_native_message(
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier Server *s,
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const void *buffer, size_t buffer_size,
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier struct ucred *ucred,
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier struct timeval *tv,
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *label, size_t label_len) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier struct iovec *iovec = NULL;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier unsigned n = 0, j, tn = (unsigned) -1;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *p;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier size_t remaining, m = 0;
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek int priority = LOG_INFO;
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek char *identifier = NULL, *message = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pid_t object_pid = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(s);
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek assert(buffer || buffer_size == 0);
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p = buffer;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier remaining = buffer_size;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier while (remaining > 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *e, *q;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier e = memchr(p, '\n', remaining);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!e) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Trailing noise, let's ignore it, and flush what we collected */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Received message with trailing noise, ignoring.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (e == p) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Entry separator */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier priority = LOG_INFO;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p++;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier remaining--;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (*p == '.' || *p == '#') {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Ignore control commands for now, and
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * comments too. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier remaining -= (e - p) + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p = e + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* A property follows */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* n received properties, +1 for _TRANSPORT */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS +
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_oom();
2375607039517c88df51ef16ddbb624ec1c10654Kay Sievers break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier q = memchr(p, '=', e - p);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (q) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (valid_user_field(p, q - p, false)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier size_t l;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier l = e - p;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* If the field name starts with an
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * underscore, skip the variable,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * since that indidates a trusted
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * field */
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek iovec[n].iov_base = (char*) p;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier iovec[n].iov_len = l;
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek n++;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek /* We need to determine the priority
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * of this entry for the rate limiting
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer * logic */
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer if (l == 10 &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier startswith(p, "PRIORITY=") &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p[9] >= '0' && p[9] <= '9')
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier priority = (priority & LOG_FACMASK) | (p[9] - '0');
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (l == 17 &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier startswith(p, "SYSLOG_FACILITY=") &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p[16] >= '0' && p[16] <= '9')
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (l == 18 &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier startswith(p, "SYSLOG_FACILITY=") &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p[16] >= '0' && p[16] <= '9' &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p[17] >= '0' && p[17] <= '9')
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (l >= 19 &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier startswith(p, "SYSLOG_IDENTIFIER=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char *t;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier t = strndup(p + 18, l - 18);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (t) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(identifier);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier identifier = t;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (l >= 8 &&
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier startswith(p, "MESSAGE=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char *t;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier t = strndup(p + 8, l - 8);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (t) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier message = t;
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin }
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin } else if (l > strlen("OBJECT_PID=") &&
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin startswith(p, "OBJECT_PID=") &&
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin allow_object_pid(ucred)) {
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin char buf[DECIMAL_STR_MAX(pid_t)];
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin char_array_0(buf);
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin /* ignore error */
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin parse_pid(buf, &object_pid);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier remaining -= (e - p) + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p = e + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier le64_t l_le;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint64_t l;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char *k;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Failed to parse message, ignoring.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier memcpy(&l_le, e + 1, sizeof(uint64_t));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier l = le64toh(l_le);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (l > DATA_SIZE_MAX) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Received binary data block too large, ignoring.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier e[1+sizeof(uint64_t)+l] != '\n') {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_debug("Failed to parse message, ignoring.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier k = malloc((e - p) + 1 + l);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!k) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_oom();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
bf3a947cb44f31359bba313e0252cbcc0dc95b03Evgeny Vereshchagin
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier memcpy(k, p, e - p);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier k[e - p] = '=';
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (valid_user_field(p, e - p, false)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier iovec[n].iov_base = k;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier iovec[n].iov_len = (e - p) + 1 + l;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier n++;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(k);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p = e + 1 + sizeof(uint64_t) + l + 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (n <= 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier tn = n++;
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt if (message) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (s->forward_to_syslog)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier server_forward_syslog(s, priority, identifier, message, ucred, tv);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (s->forward_to_kmsg)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier server_forward_kmsg(s, priority, identifier, message, ucred);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (s->forward_to_console)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier server_forward_console(s, priority, identifier, message, ucred);
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt
99877b7e3782a51b31bf191825f0335500f52fe5Harald Hoyer if (s->forward_to_wall)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier server_forward_wall(s, priority, identifier, message, ucred);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierfinish:
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier for (j = 0; j < n; j++) {
e63b61be5350dbe92ea12e1eeb96dde251ed9292Evgeny Vereshchagin if (j == tn)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (iovec[j].iov_base < buffer ||
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(iovec[j].iov_base);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin free(iovec);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(identifier);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevaliervoid server_process_native_file(
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin Server *s,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int fd,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct ucred *ucred,
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin struct timeval *tv,
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin const char *label, size_t label_len) {
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct stat st;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_free_ void *p = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier ssize_t n;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(s);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(fd >= 0);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!ucred || ucred->uid != 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_free_ char *sl = NULL, *k = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *e;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (asprintf(&sl, "/proc/self/fd/%i", fd) < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_oom();
25b47f96d9601ff566257b2a31bfb5f4bd25d661Marko Myllynen return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = readlink_malloc(sl, &k);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("readlink(%s) failed: %m", sl);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier e = path_startswith(k, "/dev/shm/");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!e)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier e = path_startswith(k, "/tmp/");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!e)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier e = path_startswith(k, "/var/tmp/");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!e) {
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt log_error("Received file outside of allowed directories. Refusing.");
5c404f1ab8e96efedb983806443ca982a1b2a372Evgeny Vereshchagin return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!filename_is_safe(e)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Received file in subdirectory of allowed directories. Refusing.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Data is in the passed file, since it didn't fit in a
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * datagram. We can't map the file here, since clients might
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * then truncate it and trigger a SIGBUS for us. So let's
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * stupidly read it */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (fstat(fd, &st) < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to stat passed file, ignoring: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!S_ISREG(st.st_mode)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("File passed is not regular. Ignoring.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (st.st_size <= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (st.st_size > ENTRY_SIZE_MAX) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("File passed too large. Ignoring.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = malloc(st.st_size);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!p) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer n = pread(fd, p, st.st_size, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (n < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to read file, ignoring: %s", strerror(-n));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (n > 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer server_process_native_message(s, p, n, ucred, tv, label, label_len);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint server_open_native_socket(Server*s) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer union sockaddr_union sa;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int one, r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(s);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (s->native_fd < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (s->native_fd < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("socket() failed: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -errno;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer zero(sa);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer sa.un.sun_family = AF_UNIX;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unlink(sa.un.sun_path);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("bind() failed: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -errno;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier chmod(sa.un.sun_path, 0666);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier fd_nonblock(s->native_fd, 1);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer one = 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("SO_PASSCRED failed: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -errno;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#ifdef HAVE_SELINUX
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (use_selinux()) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer one = 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("SO_PASSSEC failed: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#endif
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer one = 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("SO_TIMESTAMP failed: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -errno;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_event_add_io(s->event, &s->native_event_source, s->native_fd, EPOLLIN, process_datagram, s);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to add native server fd to event loop: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer