journald-native.c revision 4871690d9e32608bbd9b18505b5326c2079c9690
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2011 Lennart Poettering
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 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 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/>.
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic bool valid_user_field(const char *p, size_t l) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers const char *a;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We kinda enforce POSIX syntax recommendations for
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering environment variables here, but make a couple of additional
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering /* No empty field names */
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers /* Don't allow names longer than 64 chars */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Variables starting with an underscore are protected */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (p[0] == '_')
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Don't allow digits as first character */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Only allow A-Z0-9 and '_' */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (a = p; a < p + l; a++)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned n = 0, m = 0, j, tn = (unsigned) -1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *p;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *identifier = NULL, *message = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *e, *q;
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 /* Entry separator */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* Ignore control commands for now, and
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers * comments too. */
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers /* A property follows */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* If the field name starts with an
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * underscore, skip the variable,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * since that indidates a trusted
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We need to determine the priority
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * of this entry for the rate limiting
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (l == 10 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering priority = (priority & LOG_FACMASK) | (p[9] - '0');
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers else if (l == 17 &&
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers else if (l == 18 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcmp(p, "SYSLOG_FACILITY=", 16) == 0 &&
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (l >= 19 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else if (l >= 8 &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Failed to parse message, ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Failed to parse message, ignoring.");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna k[e - p] = '=';
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_syslog(s, priority, identifier, message, ucred, tv);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_kmsg(s, priority, identifier, message, ucred);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_forward_console(s, priority, identifier, message, ucred);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (j = 0; j < n; j++) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
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 log_error("Failed to stat passed file, ignoring: %m");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("File passed is not regular. Ignoring.");
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("File passed too large. Ignoring.");
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);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmekint server_open_native_socket(Server*s) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("SO_PASSCRED failed: %m");
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_warning("SO_PASSSEC failed: %m");
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one));
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0) {
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");