dbus.c revision 969987ea93a7fdcd2c87b551eb0adf0bd9338b32
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt/***
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt This file is part of systemd.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Copyright 2010 Lennart Poettering
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is free software; you can redistribute it and/or modify it
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt under the terms of the GNU Lesser General Public License as published by
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt the Free Software Foundation; either version 2.1 of the License, or
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (at your option) any later version.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is distributed in the hope that it will be useful, but
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt WITHOUT ANY WARRANTY; without even the implied warranty of
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Lesser General Public License for more details.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt You should have received a copy of the GNU Lesser General Public License
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt along with systemd; If not, see <http://www.gnu.org/licenses/>.
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering***/
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <sys/epoll.h>
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include <sys/timerfd.h>
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include <errno.h>
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include <unistd.h>
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "sd-bus.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "log.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "strv.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "mkdir.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "missing.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-unit.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-job.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-manager.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-execute.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-kill.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-cgroup.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "special.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "bus-util.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "bus-error.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "bus-errors.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "strxcpyx.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "dbus-client-track.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "bus-internal.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#include "selinux-access.h"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt#define CONNECTIONS_MAX 512
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic void destroy_bus(Manager *m, sd_bus **bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtint bus_send_queued_message(Manager *m) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!m->queued_message)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m->queued_message_bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt /* If we cannot get rid of this message we won't dispatch any
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * D-Bus messages, so that we won't end up wanting to queue
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * another message. */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Failed to send queued message: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt m->queued_message = sd_bus_message_unref(m->queued_message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *cgroup;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_message_read(message, "s", &cgroup);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus_log_parse_error(r);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt manager_notify_cgroup_empty(m, cgroup);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (m->running_as == SYSTEMD_SYSTEM && m->system_bus) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt /* If we are running as system manager, forward the
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * message to the system bus */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_send(m->system_bus, message, NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Failed to forward Released message: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (bus == m->api_bus)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt destroy_bus(m, &m->api_bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (bus == m->system_bus)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt destroy_bus(m, &m->system_bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (set_remove(m->private_buses, bus)) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_debug("Got disconnect on private connection.");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt destroy_bus(m, &bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *name, *old_owner, *new_owner;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus_log_parse_error(r);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt manager_dispatch_bus_name_owner_changed(
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt m, name,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt isempty(old_owner) ? NULL : old_owner,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt isempty(new_owner) ? NULL : new_owner);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *name;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Unit *u;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_message_read(message, "s", &name);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus_log_parse_error(r);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt goto failed;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = manager_load_unit(m, name, NULL, &error, &u);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt goto failed;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (u->refuse_manual_start) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %u may be requested by dependency only.", u->id);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt goto failed;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt goto failed;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt /* Successfully queued, that's it for us */
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtfailed:
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!sd_bus_error_is_set(&error))
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt sd_bus_error_set_errno(&error, r);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus_log_create_error(r);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
e80afdb3e4a1239ce0bffa4215d6a227caf3d833Michal Schmidt r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
e80afdb3e4a1239ce0bffa4215d6a227caf3d833Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus_log_create_error(r);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_error("Failed to respond with to bus activation request: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *verb, *path;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Unit *u = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Job *j;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt /* Our own method calls are all protected individually with
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * selinux checks, but the built-in interfaces need to be
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * protected too. */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt verb = "reload";
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt verb = "status";
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt else
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt path = sd_bus_message_get_path(message);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (object_path_startswith("/org/freedesktop/systemd1", path)) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = selinux_access_check(bus, message, verb, error);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt pid_t pid;
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
61c81750217af7492be86adde81b28e310cd5e82Tom Gundersen if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt u = manager_get_unit_by_pid(m, pid);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt } else {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = manager_get_job_from_dbus_path(m, path, &j);
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt if (r >= 0)
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt u = j->unit;
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt else
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt manager_load_unit_from_dbus_path(m, path, NULL, &u);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!u)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = selinux_unit_access_check(u, bus, message, verb, error);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_job_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Manager *m = userdata;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Job *j;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(interface);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(found);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = manager_get_job_from_dbus_path(m, path, &j);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *found = j;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic Unit *find_unit(Manager *m, sd_bus *bus, const char *path) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt sd_bus_message *message;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt pid_t pid;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt message = sd_bus_get_current(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!message)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt u = manager_get_unit_by_pid(m, pid);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt } else {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = manager_load_unit_from_dbus_path(m, path, NULL, &u);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Manager *m = userdata;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(interface);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(found);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt u = find_unit(m, bus, path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!u)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *found = u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Manager *m = userdata;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(interface);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(found);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt u = find_unit(m, bus, path);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!u)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *found = u;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(interface);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(found);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt u = find_unit(m, bus, path);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!u)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!unit_get_cgroup_context(u))
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *found = u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Manager *m = userdata;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt CGroupContext *c;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(interface);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(found);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt u = find_unit(m, bus, path);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!u)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt c = unit_get_cgroup_context(u);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!c)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt *found = c;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 1;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Manager *m = userdata;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt ExecContext *c;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt Unit *u;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert(bus);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert(path);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert(interface);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert(found);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert(m);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt u = find_unit(m, bus, path);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt if (!u)
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt return 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt return 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt c = unit_get_exec_context(u);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt if (!c)
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt return 0;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt *found = c;
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt return 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt KillContext *c;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Unit *u;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(path);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(interface);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(found);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt u = find_unit(m, bus, path);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!u)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt c = unit_get_kill_context(u);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!c)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *found = c;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_job_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char **l = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt unsigned k = 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Iterator i;
8927b1dad2d4a7330174cb924090b4635a2547fbDavid Herrmann Job *j;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt l = new0(char*, hashmap_size(m->jobs)+1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!l)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt HASHMAP_FOREACH(j, m->jobs, i) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt l[k] = job_dbus_path(j);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!l[k])
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt k++;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(hashmap_size(m->jobs) == k);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *nodes = l;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt l = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return k;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_unit_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt _cleanup_free_ char **l = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt unsigned k = 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Iterator i;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Unit *u;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt l = new0(char*, hashmap_size(m->units)+1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (!l)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -ENOMEM;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt HASHMAP_FOREACH(u, m->units, i) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt l[k] = unit_dbus_path(u);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (!l[k])
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return -ENOMEM;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt k++;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt *nodes = l;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt l = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return k;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt}
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt UnitType t;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_filter(bus, selinux_filter, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to add SELinux access filter: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register Manager vtable: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register Job vtable: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to add job enumerator: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register Unit vtable: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to add job enumerator: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt for (t = 0; t < _UNIT_TYPE_MAX; t++) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (unit_vtable[t]->cgroup_context_offset > 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (unit_vtable[t]->exec_context_offset > 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (unit_vtable[t]->kill_context_offset > 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_match(
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "type='signal',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "path='/org/freedesktop/DBus/Local',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "interface='org.freedesktop.DBus.Local',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "member='Disconnected'",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt signal_disconnected, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register match for Disconnected message: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_bus_unref_ sd_bus *bus = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_close_ int nfd = -1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Manager *m = userdata;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt sd_id128_t id;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(s);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (nfd < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to accept private connection, ignoring: %m");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Too many concurrent connections, refusing");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_oom();
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_new(&bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_set_fd(bus, nfd, nfd);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt nfd = -1;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = bus_check_peercred(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(sd_id128_randomize(&id) >= 0);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_set_server(bus, 1, id);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_start(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to start new connection bus: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
b669934fae49c9158c35e612e54e1765edca8584Thomas Hindoe Paaboel Andersen }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (m->running_as == SYSTEMD_SYSTEM) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt /* When we run as system instance we get the Released
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt * signal via a direct connection */
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_add_match(
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus,
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "type='signal',"
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen "interface='org.freedesktop.systemd1.Agent',"
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen "member='Released',"
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "path='/org/freedesktop/systemd1/agent'",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt signal_agent_released, m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = bus_setup_disconnected_match(m, bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = bus_setup_api_vtables(m, bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
11de3decc9357714498f96e13f1c1c2da1046811Michal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = set_put(m->private_buses, bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_debug("Accepted new private connection.");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
ce79279bff6e7a1a17070509a039ab635796f129Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_list_names(Manager *m, sd_bus *bus) {
ce79279bff6e7a1a17070509a039ab635796f129Michal Schmidt _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *name;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt int r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(m);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert(bus);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_call_method(
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt bus,
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "org.freedesktop.DBus",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "/org/freedesktop/DBus",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "org.freedesktop.DBus",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt "ListNames",
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt &error, &reply,
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return r;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_message_enter_container(reply, 'a', "s");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return bus_log_parse_error(r);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt /* This is a bit hacky, we say the owner of the name is the
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt * name itself, because we don't want the extra traffic to
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt * figure out the real owner. */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return bus_log_parse_error(r);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_message_exit_container(reply);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return bus_log_parse_error(r);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_setup_api(Manager *m, sd_bus *bus) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert(bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = bus_setup_api_vtables(m, bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_match(
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "type='signal',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "sender='org.freedesktop.DBus',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "path='/org/freedesktop/DBus',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "interface='org.freedesktop.DBus',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "member='NameOwnerChanged'",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt signal_name_owner_changed, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_add_match(
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus,
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "type='signal',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "sender='org.freedesktop.DBus',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "path='/org/freedesktop/DBus',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "interface='org.freedesktop.systemd1.Activator',"
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt "member='ActivationRequest'",
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt signal_activation_request, m);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt /* Allow replacing of our name, to ease implementation of
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * reexecution, where we keep the old connection open until
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * after the new connection is set up and the name installed
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * to allow clients to synchronously wait for reexecution to
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt * finish */
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to register name: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r != SD_BUS_NAME_PRIMARY_OWNER) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to acquire name.");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return -EEXIST;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus_list_names(m, bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_debug("Successfully connected to API bus.");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidtstatic int bus_init_api(Manager *m) {
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt _cleanup_bus_unref_ sd_bus *bus = NULL;
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt int r;
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt if (m->api_bus)
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt return 0;
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt /* The API and system bus is the same if we are running in system mode */
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt bus = sd_bus_ref(m->system_bus);
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt else {
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt if (m->running_as == SYSTEMD_SYSTEM)
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt r = sd_bus_open_system(&bus);
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt else
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt r = sd_bus_open_user(&bus);
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_debug("Failed to connect to API bus, retrying later...");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to attach API bus to event loop: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = bus_setup_disconnected_match(m, bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0)
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt r = bus_setup_api(m, bus);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt if (r < 0) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt log_error("Failed to set up API bus: %s", strerror(-r));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt }
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt m->api_bus = bus;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bus = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt return 0;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt}
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic int bus_setup_system(Manager *m, sd_bus *bus) {
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt int r;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt
assert(m);
assert(bus);
if (m->running_as == SYSTEMD_SYSTEM)
return 0;
/* If we are a user instance we get the Released message via
* the system bus */
r = sd_bus_add_match(
bus,
"type='signal',"
"interface='org.freedesktop.systemd1.Agent',"
"member='Released',"
"path='/org/freedesktop/systemd1/agent'",
signal_agent_released, m);
if (r < 0)
log_warning("Failed to register Released match on system bus: %s", strerror(-r));
log_debug("Successfully connected to system bus.");
return 0;
}
static int bus_init_system(Manager *m) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
if (m->system_bus)
return 0;
/* The API and system bus is the same if we are running in system mode */
if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
m->system_bus = sd_bus_ref(m->api_bus);
return 0;
}
r = sd_bus_open_system(&bus);
if (r < 0) {
log_debug("Failed to connect to system bus, retrying later...");
return 0;
}
r = bus_setup_disconnected_match(m, bus);
if (r < 0)
return 0;
r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0) {
log_error("Failed to attach system bus to event loop: %s", strerror(-r));
return 0;
}
r = bus_setup_system(m, bus);
if (r < 0) {
log_error("Fauiled to set up system bus: %s", strerror(-r));
return 0;
}
m->system_bus = bus;
bus = NULL;
return 0;
}
static int bus_init_private(Manager *m) {
_cleanup_close_ int fd = -1;
union sockaddr_union sa = {
.un.sun_family = AF_UNIX
};
sd_event_source *s;
socklen_t salen;
int r;
assert(m);
if (m->private_listen_fd >= 0)
return 0;
if (m->running_as == SYSTEMD_SYSTEM) {
/* We want the private bus only when running as init */
if (getpid() != 1)
return 0;
strcpy(sa.un.sun_path, "/run/systemd/private");
salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
} else {
size_t left = sizeof(sa.un.sun_path);
char *p = sa.un.sun_path;
const char *e;
e = secure_getenv("XDG_RUNTIME_DIR");
if (!e) {
log_error("Failed to determine XDG_RUNTIME_DIR");
return -EHOSTDOWN;
}
left = strpcpy(&p, left, e);
left = strpcpy(&p, left, "/systemd/private");
salen = sizeof(sa.un) - left;
mkdir_parents_label(sa.un.sun_path, 0755);
}
unlink(sa.un.sun_path);
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0) {
log_error("Failed to allocate private socket: %m");
return -errno;
}
r = bind(fd, &sa.sa, salen);
if (r < 0) {
log_error("Failed to bind private socket: %m");
return -errno;
}
r = listen(fd, SOMAXCONN);
if (r < 0) {
log_error("Failed to make private socket listening: %m");
return -errno;
}
r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
if (r < 0) {
log_error("Failed to allocate event source: %s", strerror(-r));
return r;
}
m->private_listen_fd = fd;
m->private_listen_event_source = s;
fd = -1;
log_debug("Successfully created private D-Bus server.");
return 0;
}
int bus_init(Manager *m, bool try_bus_connect) {
int r;
if (try_bus_connect) {
r = bus_init_system(m);
if (r < 0)
return r;
r = bus_init_api(m);
if (r < 0)
return r;
}
r = bus_init_private(m);
if (r < 0)
return r;
return 0;
}
static void destroy_bus(Manager *m, sd_bus **bus) {
Iterator i;
Job *j;
assert(m);
assert(bus);
if (!*bus)
return;
/* Get rid of tracked clients on this bus */
bus_client_untrack_bus(m->subscribed, *bus);
HASHMAP_FOREACH(j, m->jobs, i)
bus_client_untrack_bus(j->subscribed, *bus);
/* Get rid of queued message on this bus */
if (m->queued_message_bus == *bus) {
m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
if (m->queued_message)
m->queued_message = sd_bus_message_unref(m->queued_message);
}
/* Possibly flush unwritten data, but only if we are
* unprivileged, since we don't want to sync here */
if (m->running_as != SYSTEMD_SYSTEM)
sd_bus_flush(*bus);
/* And destroy the object */
sd_bus_close(*bus);
*bus = sd_bus_unref(*bus);
}
void bus_done(Manager *m) {
sd_bus *b;
assert(m);
if (m->api_bus)
destroy_bus(m, &m->api_bus);
if (m->system_bus)
destroy_bus(m, &m->system_bus);
while ((b = set_steal_first(m->private_buses)))
destroy_bus(m, &b);
set_free(m->private_buses);
set_free(m->subscribed);
if (m->private_listen_event_source)
m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
if (m->private_listen_fd >= 0) {
close_nointr_nofail(m->private_listen_fd);
m->private_listen_fd = -1;
}
}
int bus_fdset_add_all(Manager *m, FDSet *fds) {
Iterator i;
sd_bus *b;
int fd;
assert(m);
assert(fds);
/* When we are about to reexecute we add all D-Bus fds to the
* set to pass over to the newly executed systemd. They won't
* be used there however, except thatt they are closed at the
* very end of deserialization, those making it possible for
* clients to synchronously wait for systemd to reexec by
* simply waiting for disconnection */
if (m->api_bus) {
fd = sd_bus_get_fd(m->api_bus);
if (fd >= 0) {
fd = fdset_put_dup(fds, fd);
if (fd < 0)
return fd;
}
}
SET_FOREACH(b, m->private_buses, i) {
fd = sd_bus_get_fd(b);
if (fd >= 0) {
fd = fdset_put_dup(fds, fd);
if (fd < 0)
return fd;
}
}
/* We don't offer any APIs on the system bus (well, unless it
* is the same as the API bus) hence we don't bother with it
* here */
return 0;
}
void bus_serialize(Manager *m, FILE *f) {
assert(m);
assert(f);
bus_client_track_serialize(m, f, m->subscribed);
}
int bus_deserialize_item(Manager *m, const char *line) {
assert(m);
assert(line);
return bus_client_track_deserialize_item(m, &m->subscribed, line);
}