bus-util.c revision cab2aca3e7dc9966eb9f45416f34729719f01dd4
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2013 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_close(sd_bus_message_get_bus(m));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *match = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We unregister the name here and then wait for the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * NameOwnerChanged signal for this event to arrive before we
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * quit. We do this in order to make sure that any queued
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * requests are still processed before we really exit. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_get_unique_name(bus, &unique);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "sender='org.freedesktop.DBus',"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "interface='org.freedesktop.DBus',"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "member='NameOwnerChanged',"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "path='/org/freedesktop/DBus',"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_release_name(bus, name);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r == 0 && !exiting && idle) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Fallback for dbus1 connections: we
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * unregister the name and wait for the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * response to come through for it */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Inform the service manager that we
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * are going down, so that it will
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * queue all further start requests,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * instead of assuming we are already
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_notify(false, "STOPPING=1");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = bus_async_unregister_and_exit(e, bus, name);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_get_exit_code(e, &code);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_message_unrefp) sd_bus_message *rep = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.DBus",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.DBus",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(rep, 'b', &has_owner);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_error_set_errno(error, r);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int check_good_user(sd_bus_message *m, uid_t good_user) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (good_user == UID_INVALID)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Don't trust augmented credentials for authorization */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_creds_get_euid(creds, &sender_uid);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sender_uid == good_user;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Tests non-interactively! */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = check_good_user(call, good_user);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_query_sender_privilege(call, capability);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int authorized = false, challenge = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *sender, **k, **v;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sender = sd_bus_message_get_sender(call);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_new_method_call(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.PolicyKit1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/PolicyKit1/Authority",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.PolicyKit1.Authority",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "CheckAuthorization");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "system-bus-name", 1, "name", "s", sender,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_open_container(request, 'a', "{ss}");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen STRV_FOREACH_PAIR(k, v, details) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_append(request, "{ss}", *k, *v);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_close_container(request);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_append(request, "us", 0, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call(call->bus, request, 0, e, &reply);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Treat no PK available as access denied */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersentypedef struct AsyncPolkitQuery {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_message *request, *reply;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_message_handler_t callback;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void async_polkit_query_free(AsyncPolkitQuery *q) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (q->registry && q->request)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen hashmap_remove(q->registry, q->request);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_message_unref(q->request);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_message_unref(q->reply);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen AsyncPolkitQuery *q = userdata;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q->slot = sd_bus_slot_unref(q->slot);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q->reply = sd_bus_message_ref(reply);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_rewind(q->request, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_reply_method_errno(q->request, r, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = q->callback(q->request, q->userdata, &error_buffer);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = bus_maybe_reply_error(q->request, r, &error_buffer);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *sender, **k, **v;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sd_bus_message_handler_t callback;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = check_good_user(call, good_user);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = hashmap_get(*registry, call);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* This is the second invocation of this function, and
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * there's already a response from polkit, let's
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (sd_bus_message_is_method_error(q->reply, NULL)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Copy error from polkit reply */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = sd_bus_message_get_error(q->reply);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Treat no PK available as access denied */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -sd_bus_error_get_errno(e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_query_sender_privilege(call, capability);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (sd_bus_get_current_message(call->bus) != call)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen callback = sd_bus_get_current_handler(call->bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen userdata = sd_bus_get_current_userdata(call->bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen sender = sd_bus_message_get_sender(call);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen c = sd_bus_message_get_allow_interactive_authorization(call);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = hashmap_ensure_allocated(registry, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_new_method_call(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.PolicyKit1",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "/org/freedesktop/PolicyKit1/Authority",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "org.freedesktop.PolicyKit1.Authority",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "CheckAuthorization");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "system-bus-name", 1, "name", "s", sender,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_open_container(pk, 'a', "{ss}");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen STRV_FOREACH_PAIR(k, v, details) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_append(pk, "{ss}", *k, *v);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_close_container(pk);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_append(pk, "us", !!interactive, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q = new0(AsyncPolkitQuery, 1);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen q->request = sd_bus_message_ref(call);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = hashmap_put(*registry, call, q);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenvoid bus_verify_polkit_async_registry_free(Hashmap *registry) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while ((q = hashmap_steal_first(registry)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_check_peercred(sd_bus *c) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen l = sizeof(struct ucred);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (l != sizeof(struct ucred))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (ucred.uid != 0 && ucred.uid != geteuid())
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_connect_system_systemd(sd_bus **_bus) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_default_system(_bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* If we are root and kdbus is not available, then let's talk
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * directly to the system instance, instead of going via the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_default_system(_bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_connect_user_systemd(sd_bus **_bus) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *ee = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Try via kdbus first, and then directly */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = secure_getenv("XDG_RUNTIME_DIR");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_default_user(_bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return sd_bus_default_user(_bus);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenint bus_print_property(const char *name, sd_bus_message *property, bool all) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_peek_type(property, &type, &contents);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &s);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *escaped = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%s\n", name, escaped);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &b);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%s\n", name, yes_no(b));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Yes, heuristics! But we can change this check
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * should it turn out to not be sufficient */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (endswith(name, "Timestamp")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char timestamp[FORMAT_TIMESTAMP_MAX], *t;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t = format_timestamp(timestamp, sizeof(timestamp), u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%s\n", name, strempty(t));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (strstr(name, "USec")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char timespan[FORMAT_TIMESPAN_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%llu\n", name, (unsigned long long) u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%lld\n", name, (long long) i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (strstr(name, "UMask") || strstr(name, "Mode"))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%04o\n", name, u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%u\n", name, (unsigned) u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s=%i\n", name, (int) i);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_basic(property, type, &d);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *escaped = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen escaped = xescape(str, "\n ");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen printf("%s%s", first ? "" : " ", escaped);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_exit_container(property);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(contents, "y")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < n; i++)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(contents, "u")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen for (i = 0; i < n; i++)
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
dest,
path,
&error,
&reply,
const char *name;
const char *contents;
if (all)
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
size_t n;
*p = SD_ID128_NULL;
return -EINVAL;
static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
char type;
switch (type) {
case SD_BUS_TYPE_STRING: {
char **p = userdata;
if (isempty(s))
r = free_and_strdup(p, s);
case SD_BUS_TYPE_ARRAY: {
char ***p = userdata;
r = bus_message_read_strv_extend(m, &l);
strv_free(*p);
l = NULL;
case SD_BUS_TYPE_BOOLEAN: {
bool *p = userdata;
case SD_BUS_TYPE_UINT32: {
uint64_t u;
case SD_BUS_TYPE_UINT64: {
uint64_t t;
sd_bus_message *m,
void *userdata) {
assert(m);
const char *member;
const char *contents;
if (prop) {
r = sd_bus_message_exit_container(m);
r = sd_bus_message_exit_container(m);
return sd_bus_message_exit_container(m);
sd_bus_message *m,
void *userdata) {
const char *member;
int r, invalidated, i;
assert(m);
invalidated = 0;
++invalidated;
r = sd_bus_message_exit_container(m);
return invalidated;
const char *destination,
const char *path,
void *userdata) {
r = sd_bus_call_method(
bus,
path,
&error,
switch (transport) {
case BUS_TRANSPORT_LOCAL:
if (user)
case BUS_TRANSPORT_REMOTE:
case BUS_TRANSPORT_MACHINE:
int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
switch (transport) {
case BUS_TRANSPORT_LOCAL:
if (user)
case BUS_TRANSPORT_REMOTE:
case BUS_TRANSPORT_MACHINE:
const char *path,
const char *interface,
const char *property,
void *userdata,
int b = *(bool*) userdata;
const char *path,
const char *interface,
const char *property,
void *userdata,
const char *path,
const char *interface,
const char *property,
void *userdata,
const char *path,
const char *interface,
const char *property,
void *userdata,
int bus_log_parse_error(int r) {
int bus_log_create_error(int r) {
assert(u);
return sd_bus_message_read(
&u->id,
&u->description,
&u->load_state,
&u->active_state,
&u->sub_state,
&u->following,
&u->unit_path,
&u->job_id,
&u->job_type,
&u->job_path);
int r, rl;
assert(m);
if (!eq) {
return -EINVAL;
return bus_log_create_error(r);
eq ++;
double percent;
return -EINVAL;
r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
return -EINVAL;
goto finish;
goto finish;
usec_t t;
size_t l;
return log_oom();
goto finish;
return bus_log_create_error(r);
if (rl >= 0) {
const char *sn;
struct rlimit l;
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
uint64_t n;
return -EINVAL;
uint64_t u;
return -EINVAL;
uint64_t u;
return -EINVAL;
int level;
if (level < 0) {
return -EINVAL;
int facility;
if (facility < 0) {
return -EINVAL;
return -EINVAL;
return -EINVAL;
return -EINVAL;
return -EINVAL;
uint64_t u;
return -EINVAL;
return -EINVAL;
return -EINVAL;
int32_t i;
return -EINVAL;
return bus_log_create_error(r);
return bus_log_create_error(r);
p = eq;
return -EINVAL;
return -EINVAL;
return -EINVAL;
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
int sig;
if (sig < 0) {
return -EINVAL;
nsec_t n;
return -EINVAL;
int oa;
return -EINVAL;
return -EINVAL;
} else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
return bus_log_create_error(r);
return bus_log_create_error(r);
p = eq;
int offset;
return -EINVAL;
return -EINVAL;
return -EINVAL;
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
return bus_log_create_error(r);
p = eq;
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return -EINVAL;
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
typedef struct BusWaitForJobs {
char *name;
char *result;
assert(m);
char *found;
assert(m);
assert(d);
if (!found)
free(d);
return -ENOMEM;
r = sd_bus_add_match(
bus,
&d->slot_job_removed,
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'" :
"interface='org.freedesktop.systemd1.Manager',"
"path='/org/freedesktop/systemd1'",
match_job_removed, d);
r = sd_bus_add_match(
bus,
&d->slot_disconnected,
match_disconnected, d);
*ret = d;
d = NULL;
assert(d);
if (!dbus_path)
return -ENOMEM;
"org.freedesktop.systemd1",
"org.freedesktop.systemd1.Service",
NULL,
result);
} explanations [] = {
static void log_job_error_with_service_result(const char* service, const char *result, const char *extra_args) {
if (!systemctl_extra_args) {
log_oom();
log_error("Job for %s failed because %s. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
goto finish;
if (!quiet) {
if (d->name) {
r = -ECANCELED;
r = -ETIME;
r = -EIO;
r = -ENOEXEC;
r = -EPROTO;
r = -EOPNOTSUPP;
r = -EIO;
assert(d);
if (d->result) {
assert(d);
return log_oom();
int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
return bus_log_parse_error(r);
if (!quiet) {
r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
return bus_log_parse_error(r);
r = sd_bus_message_exit_container(m);
return bus_log_parse_error(r);
* template '/prefix/sender_id/external_id' and returns the new path in
int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
if (!sender_id) {
if (!external_id) {
if (!sender_label)
return -ENOMEM;
if (!external_label)
return -ENOMEM;
return -ENOMEM;
*ret_path = p;
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
return -ENOMEM;
bool is_kdbus_wanted(void) {
#ifdef ENABLE_KDBUS
const bool configured = true;
const bool configured = false;
return configured;
bool is_kdbus_available(void) {
if (!is_kdbus_wanted())
if (fd < 0)
const char *path,
const char *interface,
const char *property,
void *userdata,
uint64_t u;
rlim_t x;
const char *is_soft;
if (rl)
assert(z >= 0);