bus-proxyd.c revision 52cfc0379a9d63f99cdb3d9f63c839bbc8889b4c
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/***
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen This file is part of systemd.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2010 Lennart Poettering
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2013 Daniel Mack
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2014 Kay Sievers
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is free software; you can redistribute it and/or modify it
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen under the terms of the GNU Lesser General Public License as published by
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (at your option) any later version.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is distributed in the hope that it will be useful, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Lesser General Public License for more details.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen You should have received a copy of the GNU Lesser General Public License
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen***/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <sys/socket.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <sys/un.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <sys/types.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <fcntl.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <unistd.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <string.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <errno.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <sys/poll.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <stddef.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <getopt.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "log.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "socket-util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "sd-daemon.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "sd-bus.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "bus-internal.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "bus-message.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "bus-util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "build.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "strv.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "def.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "capability.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "bus-policy.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic char *arg_address = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic char *arg_command_line_buffer = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic bool arg_drop_privileges = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic char **arg_configuration = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int help(void) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen printf("%s [OPTIONS...]\n\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Connect STDIO or a socket to a given bus address.\n\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " -h --help Show this help\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --version Show package version\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --drop-privileges Drop privileges\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --configuration=PATH Configuration file or directory\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --machine=MACHINE Connect to specified machine\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " (default: " DEFAULT_SYSTEM_BUS_PATH ")\n",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen program_invocation_short_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int parse_argv(int argc, char *argv[]) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen enum {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_VERSION = 0x100,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_ADDRESS,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_DROP_PRIVILEGES,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_CONFIGURATION,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ARG_MACHINE,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen static const struct option options[] = {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "help", no_argument, NULL, 'h' },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "version", no_argument, NULL, ARG_VERSION },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "address", required_argument, NULL, ARG_ADDRESS },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "drop-privileges", no_argument, NULL, ARG_DROP_PRIVILEGES },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "configuration", required_argument, NULL, ARG_CONFIGURATION },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen { "machine", required_argument, NULL, ARG_MACHINE },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen {},
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int c, r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argc >= 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(argv);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen switch (c) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case 'h':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen help();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_VERSION:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen puts(PACKAGE_STRING);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen puts(SYSTEMD_FEATURES);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_ADDRESS: {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *a;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a = strdup(optarg);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(arg_address);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_address = a;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_DROP_PRIVILEGES:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_drop_privileges = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_CONFIGURATION:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = strv_extend(&arg_configuration, optarg);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case ARG_MACHINE: {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *e = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *a;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen e = bus_address_escape(optarg);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!e)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef ENABLE_KDBUS
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a = strjoin("x-container-unix:machine=", e, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(arg_address);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen arg_address = a;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case '?':
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen default:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_not_reached("Unhandled option");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* If the first command line argument is only "x" characters
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * we'll write who we are talking to into it, so that "ps" is
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen * explanatory */
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen arg_command_line_buffer = argv[optind];
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen log_error("Too many arguments");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (!arg_address) {
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen arg_address = strdup(DEFAULT_SYSTEM_BUS_PATH);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (!arg_address)
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int rename_service(sd_bus *a, sd_bus *b) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *p = NULL, *name = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *comm;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **cmdline;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid_t uid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pid_t pid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(a);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen assert(b);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen
52d629010db73a9466c359201916494bd55186d1Tom Gundersen r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM, &creds);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_uid(creds, &uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
52d629010db73a9466c359201916494bd55186d1Tom Gundersen
52d629010db73a9466c359201916494bd55186d1Tom Gundersen r = sd_bus_creds_get_pid(creds, &pid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_cmdline(creds, &cmdline);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_comm(creds, &comm);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen name = uid_to_name(uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!name)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -ENOMEM;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p = strv_join(cmdline, " ");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!p)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -ENOMEM;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* The status string gets the full command line ... */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_notifyf(false,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pid, p,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid, name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* ... and the argv line only the short comm */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (arg_command_line_buffer) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t m, w;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen m = strlen(arg_command_line_buffer);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen w = snprintf(arg_command_line_buffer, m,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pid, comm,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid, name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m > w)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen memzero(arg_command_line_buffer + w, m - w);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pid, p,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid, name,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->unique_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int synthesize_name_acquired(sd_bus *a, sd_bus *b, sd_bus_message *m) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name, *old_owner, *new_owner;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* If we get NameOwnerChanged for our own name, we need to
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * synthesize NameLost/NameAcquired, since socket clients need
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * that, even though it is obsoleted on kdbus */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a->is_kernel)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged") ||
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen !streq_ptr(m->path, "/org/freedesktop/DBus") ||
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen !streq_ptr(m->sender, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "sss", &name, &old_owner, &new_owner);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_rewind(m, true);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(old_owner, a->unique_name)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_signal(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &n,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/DBus",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.DBus",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "NameLost");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (streq(new_owner, a->unique_name)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_signal(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &n,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/DBus",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.DBus",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "NameAcquired");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_append(n, "s", name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_message_append_sender(n, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_seal_synthetic_message(b, n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return sd_bus_send(b, n, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersenstatic int synthetic_driver_send(sd_bus *b, sd_bus_message *m) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_message_append_sender(m, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_seal_synthetic_message(b, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return sd_bus_send(b, m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int synthetic_reply_method_error(sd_bus_message *call, const sd_bus_error *e) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(call);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_error(call, &m, e);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_driver_send(call->bus, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int synthetic_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *p) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(call);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (sd_bus_error_is_set(p))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(call, p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_bus_error_set_errno(&berror, error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(call, &berror);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int synthetic_reply_method_return(sd_bus_message *call, const char *types, ...) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(call);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_return(call, &m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!isempty(types)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen va_list ap;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen va_start(ap, types);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_message_append_ap(m, types, ap);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen va_end(ap);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_driver_send(call->bus, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int synthetic_reply_return_strv(sd_bus_message *call, char **l) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(call);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_return(call, &m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(call, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_append_strv(m, l);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(call, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_driver_send(call->bus, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(bus);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(_creds);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_name_creds(bus, name, mask, &c);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -ESRCH || r == -ENXIO)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if ((c->mask & mask) != mask)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -ENOTSUP;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen *_creds = c;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen c = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(bus);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(_creds);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return get_creds_by_name(bus, name, mask, _creds, error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m, Policy *policy, const struct ucred *ucred, Set *owned_names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a->is_kernel)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* The "Hello()" call is is handled in process_hello() */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, ""))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "s",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "<node>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"Introspect\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </interface>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <interface name=\"org.freedesktop.DBus\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"AddMatch\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"RemoveMatch\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"GetConnectionSELinuxSecurityContext\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"ay\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"GetConnectionUnixProcessID\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"GetConnectionUnixUser\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"GetId\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"GetNameOwner\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"Hello\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"ListActivatableNames\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"as\" direction=\"out\"/>\n"
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen " </method>\n"
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen " <method name=\"ListNames\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"as\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"ListQueuedOwners\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"as\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"NameHasOwner\">\n"
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen " <arg type=\"b\" direction=\"out\"/>\n"
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen " </method>\n"
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen " <method name=\"ReleaseName\">\n"
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
2a2137401b3aef20618308d2b2694e21b0124f89Tom Gundersen " <arg type=\"u\" direction=\"out\"/>\n"
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"ReloadConfig\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"RequestName\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"StartServiceByName\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"u\" direction=\"out\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <method name=\"UpdateActivationEnvironment\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"a{ss}\" direction=\"in\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </method>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <signal name=\"NameAcquired\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </signal>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <signal name=\"NameLost\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </signal>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <signal name=\"NameOwnerChanged\">\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " <arg type=\"s\"/>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </signal>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen " </interface>\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "</node>\n");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "AddMatch")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *match;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &match);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_add_match(a, NULL, match, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RemoveMatch")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *match;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &match);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_remove_match_by_string(a, match, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule not found"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_creds_by_message(a, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "y", creds->label, strlen(creds->label));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_creds_by_message(a, m, SD_BUS_CREDS_PID, &creds, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", (uint32_t) creds->pid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", (uint32_t) creds->uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetId")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_id128_t server_id;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char buf[SD_ID128_STRING_MAX];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, ""))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_owner_id(a, &server_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetNameOwner")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(name, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "s", "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_creds_by_name(a, name, SD_BUS_CREDS_UNIQUE_NAME, &creds, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "s", creds->unique_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListActivatableNames")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_strv_free_ char **names = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, ""))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_list_names(a, NULL, &names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Let's sort the names list to make it stable */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strv_sort(names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_return_strv(m, names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListNames")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_strv_free_ char **names = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, ""))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_list_names(a, &names, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = strv_extend(&names, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Let's sort the names list to make it stable */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strv_sort(names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_return_strv(m, names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ListQueuedOwners")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct kdbus_cmd_name_list cmd = {};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct kdbus_name_list *name_list;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct kdbus_name_info *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_strv_free_ char **owners = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *arg0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int err = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &arg0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_name_creds(a, arg0, 0, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -ESRCH || r == -ENXIO) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_bus_error_setf(&error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name.", arg0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen cmd.flags = KDBUS_NAME_LIST_QUEUED;
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen r = ioctl(a->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -errno, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen name_list = (struct kdbus_name_list *) ((uint8_t *) a->kdbus_buffer + cmd.offset);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen KDBUS_ITEM_FOREACH(name, name_list, names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *entry_name = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct kdbus_item *item;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen KDBUS_ITEM_FOREACH(item, name, items)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (item->type == KDBUS_ITEM_OWNED_NAME)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen entry_name = item->name.name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!streq_ptr(entry_name, arg0))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen err = -ENOMEM;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = strv_consume(&owners, n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen err = r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_kernel_cmd_free(a, cmd.offset);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (err < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, err, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_return_strv(m, owners);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "NameHasOwner")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq(name, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "b", true);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_name_creds(a, name, 0, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0 && r != -ESRCH && r != -ENXIO)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "b", r >= 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReleaseName")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "s"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "s", &name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_release_name(a, name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -ESRCH)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_NON_EXISTENT);
85091685af65831f379580c75b40776c20e245eeTom Gundersen if (r == -EADDRINUSE)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_NOT_OWNER);
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen
5a917c064b23c1b8a12d6abd2f9f31c575ddebc6Tom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen set_remove(owned_names, (char*) name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_RELEASED);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "ReloadConfig")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, ""))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_error_setf(&error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RequestName")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uint32_t flags, param;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool in_queue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "su"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "su", &name, &flags);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy && !policy_check_own(policy, ucred->uid, ucred->gid, name))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -EPERM, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if ((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) != 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -EINVAL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen param = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (flags & BUS_NAME_ALLOW_REPLACEMENT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen param |= SD_BUS_NAME_ALLOW_REPLACEMENT;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (flags & BUS_NAME_REPLACE_EXISTING)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen param |= SD_BUS_NAME_REPLACE_EXISTING;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!(flags & BUS_NAME_DO_NOT_QUEUE))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen param |= SD_BUS_NAME_QUEUE;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = set_put_strdup(owned_names, name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_request_name(a, name, param);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -EALREADY)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_ALREADY_OWNER);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen set_remove(owned_names, (char*) name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -EEXIST)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_EXISTS);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen in_queue = (r == 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (in_queue)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_IN_QUEUE);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_NAME_PRIMARY_OWNER);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "StartServiceByName")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *name;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uint32_t flags;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "su"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "su", &name, &flags);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (flags != 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -EINVAL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_name_creds(a, name, 0, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0 || streq(name, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r != -ESRCH)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_call(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &msg,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen name,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.DBus.Peer",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Ping");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_send(a, msg, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_strv_free_ char **args = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_bus_message_has_signature(m, "a{ss}"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "ss")) > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *s = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *key;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *value;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_read(m, "ss", &key, &value);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s = strjoin(key, "=", value, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!s)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -ENOMEM, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = strv_extend(&args, s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_exit_container(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_exit_container(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!args)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, -EINVAL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_call(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &msg,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.systemd1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "/org/freedesktop/systemd1",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "org.freedesktop.systemd1.Manager",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "SetEnvironment");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_append_strv(msg, args);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_call(a, msg, 0, NULL, NULL);
afcac065c0f649ebcf0f450475a8d7c3bc776d14Tom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_return(m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_error_setf(&error, SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method '%s'.", m->member);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return synthetic_reply_method_errno(m, r, &error);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(from);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(to);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!policy)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (from->is_kernel) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid_t sender_uid = (uid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen gid_t sender_gid = (gid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **sender_names = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool granted = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Driver messages are always OK */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq_ptr(m->sender, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* The message came from the kernel, and is sent to our legacy client. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* First check whether the sender can send the message to our name */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (set_isempty(owned_names)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, NULL, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen granted = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Iterator i;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen SET_FOREACH(n, owned_names, i)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, n, m->path, m->interface, m->member)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen granted = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (granted) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Then check whether us, the recipient can recieve from the sender's name */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (strv_isempty(sender_names)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STRV_FOREACH(n, sender_names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Return an error back to the caller */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML receiver policy.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Return 1, indicating that the message shall not be processed any further */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (to->is_kernel) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *destination_creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid_t destination_uid = (uid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen gid_t destination_gid = (gid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *destination_unique = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **destination_names = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool granted = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Driver messages are always OK */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (streq_ptr(m->destination, "org.freedesktop.DBus"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* The message came from the legacy client, and is sent to kdbus. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m->destination) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_name_creds(to, m->destination,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID, &destination_creds);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* First check if we, the sender can send to this name */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (strv_isempty(destination_names)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen granted = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STRV_FOREACH(n, destination_names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* If we made a receiver decision,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen then remember which name's policy
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen we used, and to which unique ID it
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen mapped when we made the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen decision. Then, let's pass this to
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen the kernel when sending the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen message, so that it refuses the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen operation should the name and
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unique ID not map to each other
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen anymore. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = free_and_strdup(&m->destination_ptr, *n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_kernel_parse_unique_name(destination_unique, &m->verify_destination_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen granted = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Then check if the recipient can receive from our name */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (granted) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (set_isempty(owned_names)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, NULL, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Iterator i;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *n;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen SET_FOREACH(n, owned_names, i)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, n, m->path, m->interface, m->member))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Return an error back to the caller */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML sender policy.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Return 1, indicating that the message shall not be processed any further */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hello) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool is_hello;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(got_hello);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* As reaction to hello we need to respond with two messages:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * the callback reply and the NameAcquired for the unique
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * name, since hello is otherwise obsolete on kdbus. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen is_hello =
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "Hello") &&
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen streq_ptr(m->destination, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!is_hello) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (*got_hello)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("First packet isn't hello (it's %s.%s), aborting.", m->interface, m->member);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (*got_hello) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got duplicate hello, aborting.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen *got_hello = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a->is_kernel)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_method_return(m, &n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to generate HELLO reply: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_append(n, "s", a->unique_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to append unique name to HELLO reply: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_message_append_sender(n, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to append sender to HELLO reply: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_seal_synthetic_message(b, n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to seal HELLO reply: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_send(b, n, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to send HELLO reply: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen n = sd_bus_message_unref(n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_new_signal(
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen &n,
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen "/org/freedesktop/DBus",
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen "org.freedesktop.DBus",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "NameAcquired");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to allocate initial NameAcquired message: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
53fae771bcf1623cd28791c48fa60d9d5e5086e4Zbigniew Jędrzejewski-Szmek
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_message_append(n, "s", a->unique_name);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to append unique name to NameAcquired message: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
53fae771bcf1623cd28791c48fa60d9d5e5086e4Zbigniew Jędrzejewski-Szmek }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_message_append_sender(n, "org.freedesktop.DBus");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bus_seal_synthetic_message(b, n);
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen if (r < 0) {
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen log_error_errno(r, "Failed to seal NameAcquired message: %m");
4189708ad0cde8e211e38d27de943579772f8869Tom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_send(b, n, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
53fae771bcf1623cd28791c48fa60d9d5e5086e4Zbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to send NameAcquired message: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int patch_sender(sd_bus *a, sd_bus_message *m) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char **well_known = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_bus_creds *c;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen assert(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!a->is_kernel)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We will change the sender of messages from the bus driver
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * so that they originate from the bus driver. This is a
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * speciality originating from dbus1, where the bus driver did
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * not have a unique id, but only the well-known name. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen c = sd_bus_message_get_creds(m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!c)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_well_known_names(c, &well_known);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (strv_contains(well_known, "org.freedesktop.DBus"))
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen m->sender = "org.freedesktop.DBus";
7141e4f62c3f220872df3114c42d9e4b9525e43eTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenint main(int argc, char *argv[]) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_id128_t server_id;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r, in_fd, out_fd;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool got_hello = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool is_unix;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct ucred ucred = {};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *peersec = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Policy policy_buffer = {}, *policy = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_set_free_free_ Set *owned_names = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_parse_environment();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_open();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_argv(argc, argv);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r <= 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_listen_fds(0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen in_fd = STDIN_FILENO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen out_fd = STDOUT_FILENO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (r == 1) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen in_fd = SD_LISTEN_FDS_START;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen out_fd = SD_LISTEN_FDS_START;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Illegal number of file descriptors passed");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen is_unix =
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (is_unix) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) getpeercred(in_fd, &ucred);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void) getpeersec(in_fd, &peersec);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (arg_drop_privileges) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *user = "systemd-bus-proxy";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid_t uid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen gid_t gid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_user_creds(&user, &uid, &gid, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Cannot resolve user name %s: %m", user);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen owned_names = set_new(&string_hash_ops);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!owned_names) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_new(&a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to allocate bus: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen r = sd_bus_set_description(a, "sd-proxy");
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen if (r < 0) {
107f2e2526d476c6cc9b81a690391c111027d641Tom Gundersen log_error_errno(r, "Failed to set bus name: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_set_address(a, arg_address);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set address to connect to: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_negotiate_fds(a, is_unix);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set FD negotiation: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_negotiate_creds(a, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set credential negotiation: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (ucred.pid > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_pids.pid = ucred.pid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_pids_valid = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.uid = ucred.uid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.euid = (uid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.suid = (uid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.fsuid = (uid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.gid = ucred.gid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.egid = (gid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.sgid = (gid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds.fsgid = (gid_t) -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_creds_valid = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (peersec) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->fake_label = peersec;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen peersec = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen a->manual_peer_interface = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_start(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to start bus client: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_owner_id(a, &server_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get server ID: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (a->is_kernel) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_creds_unref_ sd_bus_creds *bus_creds = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid_t bus_uid;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_owner_creds(a, SD_BUS_CREDS_UID, &bus_creds);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get bus creds: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_creds_get_uid(bus_creds, &bus_uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get bus owner UID: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (bus_uid == 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We only enforce the old XML policy on
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * kernel busses owned by root users. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = policy_load(&policy_buffer, arg_configuration);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to load policy: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!policy_check_hello(&policy_buffer, ucred.uid, ucred.gid)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Policy denied connection");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = -EPERM;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen policy_dump(&policy_buffer);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen policy = &policy_buffer;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_new(&b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to allocate bus: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_set_fd(b, in_fd, out_fd);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set fds: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_set_server(b, 1, server_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set server mode: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_negotiate_fds(b, is_unix);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set FD negotiation: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set credential negotiation: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_set_anonymous(b, true);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to set anonymous authentication: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen b->manual_peer_interface = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_start(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to start bus client: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = rename_service(a, b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_debug_errno(r, "Failed to rename process: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (a->is_kernel) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *match = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *unique;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_unique_name(a, &unique);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get unique name: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen match = strjoin("type='signal',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "sender='org.freedesktop.DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "path='/org/freedesktop/DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "interface='org.freedesktop.DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "member='NameOwnerChanged',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "arg1='",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unique,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "'",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!match) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_add_match(a, NULL, match, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to add match for NameLost: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(match);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen match = strjoin("type='signal',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "sender='org.freedesktop.DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "path='/org/freedesktop/DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "interface='org.freedesktop.DBus',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "member='NameOwnerChanged',"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "arg2='",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unique,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "'",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!match) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_add_match(a, NULL, match, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to add match for NameAcquired: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (;;) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int events_a, events_b, fd;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uint64_t timeout_a, timeout_b, t;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct timespec _ts, *ts;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct pollfd *pollfd;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (got_hello) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Read messages from bus, to pass them on to our client */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_process(a, &m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* treat 'connection reset by peer' as clean exit condition */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -ECONNRESET)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process bus a: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool processed = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We officially got EOF, let's quit */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = synthesize_name_acquired(a, b, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to synthesize message: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen patch_sender(a, m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = process_policy(a, b, m, policy, &ucred, owned_names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process policy: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (k > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen processed = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!processed) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = sd_bus_send(b, m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k == -ECONNRESET)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to send message to client: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Read messages from our client, to pass them on to the bus */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_process(b, &m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* treat 'connection reset by peer' as clean exit condition */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -ECONNRESET)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process bus b: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (m) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool processed = false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We officially got EOF, let's quit */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = process_hello(a, b, m, &got_hello);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process HELLO: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (k > 0) {
2fe29a46a3e16a787098f9fb410e1b756506fd52Tom Gundersen processed = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 1;
2fe29a46a3e16a787098f9fb410e1b756506fd52Tom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!processed) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = process_driver(a, b, m, policy, &ucred, owned_names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process driver calls: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (k > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen processed = true;
2fe29a46a3e16a787098f9fb410e1b756506fd52Tom Gundersen r = 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!processed) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (;;) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (policy) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = process_policy(b, a, m, policy, &ucred, owned_names);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to process policy: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (k > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen processed = true;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen k = sd_bus_send(a, m, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (k == -EREMCHG)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* The name database changed since the policy check, hence let's check again */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (k == -ECONNRESET)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = k;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to send message to bus: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen continue;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fd = sd_bus_get_fd(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (fd < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get fd: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen events_a = sd_bus_get_events(a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (events_a < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get events mask: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_timeout(a, &timeout_a);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get timeout: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen events_b = sd_bus_get_events(b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (events_b < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get events mask: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_bus_get_timeout(b, &timeout_b);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error_errno(r, "Failed to get timeout: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t = timeout_a;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t = timeout_b;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (t == (uint64_t) -1)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ts = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen usec_t nw;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen nw = now(CLOCK_MONOTONIC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (t > nw)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t -= nw;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen t = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ts = timespec_store(&_ts, t);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen pollfd = (struct pollfd[3]) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen {.fd = fd, .events = events_a, },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen {.fd = in_fd, .events = events_b & POLLIN, },
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen {.fd = out_fd, .events = events_b & POLLOUT, }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = ppoll(pollfd, 3, ts, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("ppoll() failed: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto finish;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenfinish:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_notify(false,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "STOPPING=1\n"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "STATUS=Shutting down.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen policy_free(&policy_buffer);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen strv_free(arg_configuration);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(arg_address);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen