dbus.c revision 230314d718cb68b328961c9723976e54c17d06f7
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2010 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3c0cf502796be355431d4a64d738e75f543aa51dLennart Poetteringstatic void destroy_bus(Manager *m, sd_bus **bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* If we cannot get rid of this message we won't dispatch any
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * D-Bus messages, so that we won't end up wanting to queue
static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *cgroup;
assert(m);
static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
m, name,
static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
const char *name;
Unit *u;
assert(m);
r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
goto failed;
goto failed;
if (u->refuse_manual_start) {
r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only.", u->id);
goto failed;
goto failed;
r = sd_bus_message_new_signal(bus, &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
#ifdef HAVE_SELINUX
static int mac_selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Job *j;
u = j->unit;
static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Job *j;
assert(m);
*found = j;
Unit *u;
assert(m);
if (!message)
*unit = u;
static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
assert(m);
static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Unit *u;
assert(m);
*found = u;
static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Unit *u;
assert(m);
if (!unit_get_cgroup_context(u))
*found = u;
static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
CGroupContext *c;
Unit *u;
assert(m);
c = unit_get_cgroup_context(u);
*found = c;
static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
ExecContext *c;
Unit *u;
assert(m);
c = unit_get_exec_context(u);
*found = c;
static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
KillContext *c;
Unit *u;
assert(m);
c = unit_get_kill_context(u);
*found = c;
static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
Iterator i;
Job *j;
return -ENOMEM;
l[k] = job_dbus_path(j);
return -ENOMEM;
*nodes = l;
l = NULL;
static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
Iterator i;
Unit *u;
return -ENOMEM;
l[k] = unit_dbus_path(u);
return -ENOMEM;
*nodes = l;
l = NULL;
UnitType t;
assert(m);
#ifdef HAVE_SELINUX
r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
for (t = 0; t < _UNIT_TYPE_MAX; t++) {
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
return log_error_errno(r, "Failed to register type specific vtable for %s: %m", unit_vtable[t]->bus_interface);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", unit_vtable[t]->bus_interface);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
return log_error_errno(r, "Failed to register control group vtable for %s: %m", unit_vtable[t]->bus_interface);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
return log_error_errno(r, "Failed to register execute vtable for %s: %m", unit_vtable[t]->bus_interface);
r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
return log_error_errno(r, "Failed to register kill vtable for %s: %m", unit_vtable[t]->bus_interface);
assert(m);
r = sd_bus_add_match(
bus,
NULL,
"path='/org/freedesktop/DBus/Local',"
signal_disconnected, m);
assert(s);
assert(m);
if (nfd < 0) {
log_oom();
r = sd_bus_add_match(
bus,
NULL,
"interface='org.freedesktop.systemd1.Agent',"
"path='/org/freedesktop/systemd1/agent'",
assert(m);
assert(m);
/* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
r = sd_bus_add_match(
bus,
NULL,
"path='/org/freedesktop/DBus',"
r = sd_bus_add_match(
bus,
NULL,
"path='/org/freedesktop/DBus',"
"interface='org.freedesktop.systemd1.Activator',"
r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
if (m->api_bus)
assert(m);
r = sd_bus_add_match(
bus,
NULL,
"interface='org.freedesktop.systemd1.Agent',"
"path='/org/freedesktop/systemd1/agent'",
if (m->system_bus)
sd_event_source *s;
assert(m);
if (m->private_listen_fd >= 0)
if (m->kdbus_fd >= 0)
return -EHOSTDOWN;
if (fd < 0)
m->private_listen_event_source = s;
if (try_bus_connect) {
r = bus_init_system(m);
r = bus_init_api(m);
r = bus_init_private(m);
Iterator i;
Job *j;
assert(m);
if (!*bus)
if (m->queued_message)
sd_bus *b;
assert(m);
if (m->api_bus)
if (m->system_bus)
destroy_bus(m, &b);
if (m->private_listen_event_source)
Iterator i;
sd_bus *b;
int fd;
assert(m);
if (m->api_bus) {
if (fd >= 0) {
if (fd < 0)
return fd;
if (fd >= 0) {
if (fd < 0)
return fd;
int bus_foreach_bus(
Manager *m,
void *userdata) {
Iterator i;
sd_bus *b;
int r, ret = 0;
ret = r;
ret = r;
return ret;
assert(f);
assert(l);
r = strv_extend(l, e);
assert(m);
assert(t);
assert(l);
STRV_FOREACH(i, *l) {
k = sd_bus_track_add_name(*t, *i);
strv_free(*l);
*l = NULL;
return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, &m->polkit_registry, error);
return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, &m->polkit_registry, error);