journald-audit.c revision 23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2014 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "missing.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "journald-audit.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersentypedef struct MapField {
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering const char *audit_field;
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering const char *journal_field;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering int (*map)(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov);
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering} MapField;
a5a807e63a50314e190e9166d8a453cd8dd258e3Zbigniew Jędrzejewski-Szmek
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic int map_simple_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
c004493cdefc1f43a3956ca529e8070f8d70be56Lennart Poettering _cleanup_free_ char *c = NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering size_t l = 0, allocated = 0;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering const char *e;
822db23cfa98a9fbc48f41e11caafb6f1017e052Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(field);
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier assert(p);
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering assert(iov);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert(n_iov);
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering
5f402ae84bbc08fe8de5682e371b3f66c387da52Daniel Mack l = strlen(field);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering allocated = l + 1;
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack c = malloc(allocated);
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering if (!c)
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return -ENOMEM;
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering memcpy(c, field, l);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering for (e = *p; *e != ' ' && *e != 0; e++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!GREEDY_REALLOC(c, allocated, l+2))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen c[l++] = *e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c[l] = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*iov)[*n_iov].iov_base = c;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*iov)[*n_iov].iov_len = l;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen (*n_iov) ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *p = e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int map_string_field_internal(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov, bool filter_printable) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *c = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *s, *e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t l;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering assert(field);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(p);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering assert(iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(n_iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* The kernel formats string fields in one of two formats. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (**p == '"') {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Normal quoted syntax */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s = *p + 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = strchr(s, '"');
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering return 0;
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering l = strlen(field) + (e - s);
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering c = malloc(l+1);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (!c)
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering return -ENOMEM;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *((char*) mempcpy(stpcpy(c, field), s, e - s)) = 0;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e += 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (unhexchar(**p) >= 0) {
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering /* Hexadecimal escaping */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t allocated = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l = strlen(field);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering allocated = l + 2;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = malloc(allocated);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!c)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcpy(c, field, l);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt for (e = *p; *e != ' ' && *e != 0; e += 2) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int a, b;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint8_t x;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen a = unhexchar(e[0]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (a < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering b = unhexchar(e[1]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (b < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering x = ((uint8_t) a << 4 | (uint8_t) b);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (filter_printable && x < (uint8_t) ' ')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering x = (uint8_t) ' ';
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!GREEDY_REALLOC(c, allocated, l+2))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c[l++] = (char) x;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c[l] = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!GREEDY_REALLOC(*iov, *n_iov_allocated, *n_iov + 1))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*iov)[*n_iov].iov_base = c;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*iov)[*n_iov].iov_len = l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*n_iov) ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *p = e;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen c = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int map_string_field(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, false);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int map_string_field_printable(const char *field, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return map_string_field_internal(field, p, iov, n_iov_allocated, n_iov, true);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int map_generic_field(const char *prefix, const char **p, struct iovec **iov, size_t *n_iov_allocated, unsigned *n_iov) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *e, *f;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *c, *t;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Implements fallback mappings for all fields we don't know */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (e = *p; e < *p + 16; e++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*e == 0 || *e == ' ')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*e == '=')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!((*e >= 'a' && *e <= 'z') ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*e >= 'A' && *e <= 'Z') ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (*e >= '0' && *e <= '9') ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *e == '_' || *e == '-'))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (e <= *p || e >= *p + 16)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = alloca(strlen(prefix) + (e - *p) + 2);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering t = stpcpy(c, prefix);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (f = *p; f < e; f++) {
3e044c492e3ebe64f4e3175c94f9db8a62557b82Markus Elfring char x;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*f >= 'a' && *f <= 'z')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering x = (*f - 'a') + 'A'; /* uppercase */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (*f == '-')
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering x = '_'; /* dashes → underscores */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt x = *f;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *(t++) = x;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering strcpy(t, "=");
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen e ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = map_simple_field(c, &e, iov, n_iov_allocated, n_iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen *p = e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering/* Kernel fields are those occuring in the audit string before
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * msg='. All of these fields are trusted, hence carry the "_" prefix.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * We try to translate the fields we know into our native names. The
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * other's are generically mapped to _AUDIT_FIELD_XYZ= */
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic const MapField map_fields_kernel[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* First, we map certain well-known audit fields into native
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * well-known fields */
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "pid=", "_PID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "ppid=", "_PPID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "uid=", "_UID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "euid=", "_EUID=", map_simple_field },
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "fsuid=", "_FSUID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "gid=", "_GID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "egid=", "_EGID=", map_simple_field },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { "fsgid=", "_FSGID=", map_simple_field },
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "tty=", "_TTY=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "ses=", "_AUDIT_SESSION=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "auid=", "_AUDIT_LOGINUID=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "subj=", "_SELINUX_CONTEXT=", map_simple_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "comm=", "_COMM=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "exe=", "_EXE=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "proctitle=", "_CMDLINE=", map_string_field_printable },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Some fields don't map to native well-known fields. However,
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen * we know that they are string fields, hence let's undo
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * string field escaping for them, though we stick to the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * generic field names. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "path=", "_AUDIT_FIELD_PATH=", map_string_field },
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "dev=", "_AUDIT_FIELD_DEV=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "name=", "_AUDIT_FIELD_NAME=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering {}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering};
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/* Userspace fields are thos occuring in the audit string after
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * msg='. All of these fields are untrusted, hence carry no "_"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * prefix. We map the fields we don't know to AUDIT_FIELD_XYZ= */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic const MapField map_fields_userspace[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "cwd=", "AUDIT_FIELD_CWD=", map_string_field },
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "cmd=", "AUDIT_FIELD_CMD=", map_string_field },
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen { "acct=", "AUDIT_FIELD_ACCT=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "exe=", "AUDIT_FIELD_EXE=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "comm=", "AUDIT_FIELD_COMM=", map_string_field },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering {}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int map_all_fields(
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen const char *p,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const MapField map_fields[],
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *prefix,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool handle_msg,
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen struct iovec **iov,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t *n_iov_allocated,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned *n_iov) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(p);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(n_iov_allocated);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(n_iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (;;) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool mapped = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const MapField *m;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *v;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering p += strspn(p, WHITESPACE);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (*p == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (handle_msg) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering v = startswith(p, "msg='");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (v) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *e;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering char *c;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Userspace message. It's enclosed in
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering simple quotation marks, is not
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering escaped, but the last field in the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering line, hence let's remove the
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt quotation mark, and apply the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering userspace mapping instead of the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering kernel mapping. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering e = endswith(v, "'");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!e)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0; /* don't continue splitting up if the final quotation mark is missing */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering c = strndupa(v, e - v);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return map_all_fields(c, map_fields_userspace, "AUDIT_FIELD_", false, iov, n_iov_allocated, n_iov);
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Try to map the kernel fields to our own names */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (m = map_fields; m->audit_field; m++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering v = startswith(p, m->audit_field);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!v)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = m->map(m->journal_field, &v, iov, n_iov_allocated, n_iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_debug_errno(r, "Failed to parse audit array: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r > 0) {
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering mapped = true;
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering p = v;
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering break;
2d8950384f3137aafcce22b29912b2b61e6d86fbLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering if (!mapped) {
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering r = map_generic_field(prefix, &p, iov, n_iov_allocated, n_iov);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_debug_errno(r, "Failed to parse audit array: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r == 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* Couldn't process as generic field, let's just skip over it */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering p += strcspn(p, WHITESPACE);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering}
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic void process_audit_string(Server *s, int type, const char *data, size_t size) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering _cleanup_free_ struct iovec *iov = NULL;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering size_t n_iov_allocated = 0;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering unsigned n_iov = 0, k;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering uint64_t seconds, msec, id;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const char *p;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering unsigned z;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering char id_field[sizeof("_AUDIT_ID=") + DECIMAL_STR_MAX(uint64_t)],
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering type_field[sizeof("_AUDIT_TYPE=") + DECIMAL_STR_MAX(int)],
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering source_time_field[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering char *m;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering assert(s);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (size <= 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!data)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Note that the input buffer is NUL terminated, but let's
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering * check whether there is a spurious NUL byte */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (memchr(data, 0, size))
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering p = startswith(data, "audit");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!p)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return;
422baca0f230913158078fddf884e06c8c64a316Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (sscanf(p, "(%" PRIi64 ".%" PRIi64 ":%" PRIi64 "):%n",
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering &seconds,
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering &msec,
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering &id,
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering &k) != 3)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering p += k;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering p += strspn(p, WHITESPACE);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (isempty(p))
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering n_iov_allocated = N_IOVEC_META_FIELDS + 5;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering iov = new(struct iovec, n_iov_allocated);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!iov) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering IOVEC_SET_STRING(iov[n_iov++], "_TRANSPORT=audit");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sprintf(source_time_field, "_SOURCE_REALTIME_TIMESTAMP=%" PRIu64,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering (usec_t) seconds * USEC_PER_SEC + (usec_t) msec * USEC_PER_MSEC);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering IOVEC_SET_STRING(iov[n_iov++], source_time_field);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sprintf(type_field, "_AUDIT_TYPE=%i", type);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering IOVEC_SET_STRING(iov[n_iov++], type_field);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering sprintf(id_field, "_AUDIT_ID=%" PRIu64, id);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering IOVEC_SET_STRING(iov[n_iov++], id_field);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering m = alloca(strlen("MESSAGE=<audit-") + DECIMAL_STR_MAX(int) + strlen("> ") + strlen(p) + 1);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering sprintf(m, "MESSAGE=<audit-%i> %s", type, p);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering IOVEC_SET_STRING(iov[n_iov++], m);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering z = n_iov;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering map_all_fields(p, map_fields_kernel, "_AUDIT_FIELD_", true, &iov, &n_iov_allocated, &n_iov);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!GREEDY_REALLOC(iov, n_iov_allocated, n_iov + N_IOVEC_META_FIELDS)) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_oom();
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering server_dispatch_message(s, iov, n_iov, n_iov_allocated, NULL, NULL, NULL, 0, NULL, LOG_NOTICE, 0);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringfinish:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* free() all entries that map_all_fields() added. All others
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering * are allocated on the stack or are constant. */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering for (; z < n_iov; z++)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering free(iov[z].iov_base);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringvoid server_process_audit_message(
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering Server *s,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const void *buffer,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering size_t buffer_size,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const struct ucred *ucred,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const union sockaddr_union *sa,
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering socklen_t salen) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt const struct nlmsghdr *nl = buffer;
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal Schmidt
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(s);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering if (buffer_size < ALIGN(sizeof(struct nlmsghdr)))
aa4a9deb7d3db95ffb1fd18791be66f58d06a69eLennart Poettering return;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(buffer);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Filter out fake data */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!sa ||
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering salen != sizeof(struct sockaddr_nl) ||
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering sa->nl.nl_family != AF_NETLINK ||
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering sa->nl.nl_pid != 0) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_debug("Audit netlink message from invalid sender.");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (!ucred || ucred->pid != 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_debug("Audit netlink message with invalid credentials.");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (!NLMSG_OK(nl, buffer_size)) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering log_error("Audit netlink message truncated.");
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering }
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering /* Ignore special Netlink messages */
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (IN_SET(nl->nlmsg_type, NLMSG_NOOP, NLMSG_ERROR))
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering /* Below AUDIT_FIRST_USER_MSG theer are only control messages, let's ignore those */
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (nl->nlmsg_type < AUDIT_FIRST_USER_MSG)
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering return;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering process_audit_string(s, nl->nlmsg_type, NLMSG_DATA(nl), nl->nlmsg_len - ALIGN(sizeof(struct nlmsghdr)));
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering}
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poetteringstatic int enable_audit(int fd, bool b) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering struct {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering union {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering struct nlmsghdr header;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering uint8_t header_space[NLMSG_HDRLEN];
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering };
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering struct audit_status body;
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering } _packed_ request = {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen .header.nlmsg_len = NLMSG_LENGTH(sizeof(struct audit_status)),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .header.nlmsg_type = AUDIT_SET,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen .header.nlmsg_flags = NLM_F_REQUEST,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen .header.nlmsg_seq = 1,
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering .header.nlmsg_pid = 0,
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering .body.mask = AUDIT_STATUS_ENABLED,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen .body.enabled = b,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen };
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen union sockaddr_union sa = {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen .nl.nl_family = AF_NETLINK,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering .nl.nl_pid = 0,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering };
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack struct iovec iovec = {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering .iov_base = &request,
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering .iov_len = NLMSG_LENGTH(sizeof(struct audit_status)),
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering };
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering struct msghdr mh = {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering .msg_iov = &iovec,
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering .msg_iovlen = 1,
00fa60ae3b2823036cb3e7734f16bce30cb7441dLennart Poettering .msg_name = &sa.sa,
dd0bc0f1414cc1d0fa73a29470bd14944e4942d3Lennart Poettering .msg_namelen = sizeof(sa.nl),
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen };
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering ssize_t n;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering n = sendmsg(fd, &mh, MSG_NOSIGNAL);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (n < 0)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return -errno;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (n != NLMSG_LENGTH(sizeof(struct audit_status)))
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return -EIO;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen /* We don't wait for the result here, we can't do anything
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen * about it anyway */
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenint server_open_audit(Server *s) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen static const int one = 1;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (s->audit_fd < 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering static const union sockaddr_union sa = {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering .nl.nl_family = AF_NETLINK,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .nl.nl_pid = 0,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .nl.nl_groups = AUDIT_NLGRP_READLOG,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering };
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s->audit_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_AUDIT);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (s->audit_fd < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Audit not supported in the kernel.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to create audit socket, ignoring: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = bind(s->audit_fd, &sa.sa, sizeof(sa.nl));
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering if (r < 0) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering log_error("Failed to join audit multicast group: %m");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return -errno;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen } else
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen fd_nonblock(s->audit_fd, 1);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = setsockopt(s->audit_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_error("Failed to set SO_PASSCRED on audit socket: %m");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return -errno;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering }
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_event_add_io(s->event, &s->audit_event_source, s->audit_fd, EPOLLIN, process_datagram, s);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return log_error_errno(r, "Failed to add audit fd to event loop: %m");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack /* We are listening now, try to enable audit */
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack r = enable_audit(s->audit_fd, true);
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack if (r < 0)
bc7702b098b63031767174206f5df14a8ccb45cfDaniel Mack log_warning_errno(r, "Failed to issue audit enable call: %m");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return 0;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering