1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 // #include <sys/socket.h>
24 // #include "sd-daemon.h"
25 // #include "sd-event.h"
30 // #include "path-util.h"
31 // #include "missing.h"
33 // #include "signal-util.h"
34 #include "unit-name.h"
36 // #include "sd-bus.h"
37 // #include "bus-error.h"
38 // #include "bus-label.h"
39 #include "bus-message.h"
41 #include "bus-internal.h"
43 /// UNNEEDED by elogind
45 static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
46 sd_event *e = userdata;
51 sd_bus_close(sd_bus_message_get_bus(m));
57 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
58 _cleanup_free_ char *match = NULL;
66 /* We unregister the name here and then wait for the
67 * NameOwnerChanged signal for this event to arrive before we
68 * quit. We do this in order to make sure that any queued
69 * requests are still processed before we really exit. */
71 r = sd_bus_get_unique_name(bus, &unique);
76 "sender='org.freedesktop.DBus',"
78 "interface='org.freedesktop.DBus',"
79 "member='NameOwnerChanged',"
80 "path='/org/freedesktop/DBus',"
83 "arg2=''", name, unique);
87 r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
91 r = sd_bus_release_name(bus, name);
98 int bus_event_loop_with_idle(
103 check_idle_t check_idle,
105 bool exiting = false;
115 r = sd_event_get_state(e);
118 if (r == SD_EVENT_FINISHED)
122 idle = check_idle(userdata);
126 r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
130 if (r == 0 && !exiting && idle) {
132 r = sd_bus_try_close(bus);
136 /* Fallback for dbus1 connections: we
137 * unregister the name and wait for the
138 * response to come through for it */
139 if (r == -EOPNOTSUPP) {
141 /* Inform the service manager that we
142 * are going down, so that it will
143 * queue all further start requests,
144 * instead of assuming we are already
146 sd_notify(false, "STOPPING=1");
148 r = bus_async_unregister_and_exit(e, bus, name);
164 r = sd_event_get_exit_code(e, &code);
172 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
173 _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
174 int r, has_owner = 0;
179 r = sd_bus_call_method(c,
180 "org.freedesktop.DBus",
181 "/org/freedesktop/dbus",
182 "org.freedesktop.DBus",
191 r = sd_bus_message_read_basic(rep, 'b', &has_owner);
193 return sd_bus_error_set_errno(error, r);
198 static int check_good_user(sd_bus_message *m, uid_t good_user) {
199 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
205 if (good_user == UID_INVALID)
208 r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
212 /* Don't trust augmented credentials for authorization */
213 assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
215 r = sd_bus_creds_get_euid(creds, &sender_uid);
219 return sender_uid == good_user;
223 sd_bus_message *call,
226 const char **details,
236 /* Tests non-interactively! */
238 r = check_good_user(call, good_user);
242 r = sd_bus_query_sender_privilege(call, capability);
249 _cleanup_bus_message_unref_ sd_bus_message *request = NULL;
250 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
251 int authorized = false, challenge = false;
252 const char *sender, **k, **v;
254 sender = sd_bus_message_get_sender(call);
258 r = sd_bus_message_new_method_call(
261 "org.freedesktop.PolicyKit1",
262 "/org/freedesktop/PolicyKit1/Authority",
263 "org.freedesktop.PolicyKit1.Authority",
264 "CheckAuthorization");
268 r = sd_bus_message_append(
271 "system-bus-name", 1, "name", "s", sender,
276 r = sd_bus_message_open_container(request, 'a', "{ss}");
280 STRV_FOREACH_PAIR(k, v, details) {
281 r = sd_bus_message_append(request, "{ss}", *k, *v);
286 r = sd_bus_message_close_container(request);
290 r = sd_bus_message_append(request, "us", 0, NULL);
294 r = sd_bus_call(call->bus, request, 0, e, &reply);
296 /* Treat no PK available as access denied */
297 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
298 sd_bus_error_free(e);
305 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
309 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
317 *_challenge = challenge;
328 typedef struct AsyncPolkitQuery {
329 sd_bus_message *request, *reply;
330 sd_bus_message_handler_t callback;
336 static void async_polkit_query_free(AsyncPolkitQuery *q) {
341 sd_bus_slot_unref(q->slot);
343 if (q->registry && q->request)
344 hashmap_remove(q->registry, q->request);
346 sd_bus_message_unref(q->request);
347 sd_bus_message_unref(q->reply);
352 static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
353 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
354 AsyncPolkitQuery *q = userdata;
360 q->slot = sd_bus_slot_unref(q->slot);
361 q->reply = sd_bus_message_ref(reply);
363 r = sd_bus_message_rewind(q->request, true);
365 r = sd_bus_reply_method_errno(q->request, r, NULL);
369 r = q->callback(q->request, q->userdata, &error_buffer);
370 r = bus_maybe_reply_error(q->request, r, &error_buffer);
373 async_polkit_query_free(q);
380 int bus_verify_polkit_async(
381 sd_bus_message *call,
384 const char **details,
388 sd_bus_error *error) {
391 _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
393 const char *sender, **k, **v;
394 sd_bus_message_handler_t callback;
404 r = check_good_user(call, good_user);
409 q = hashmap_get(*registry, call);
411 int authorized, challenge;
413 /* This is the second invocation of this function, and
414 * there's already a response from polkit, let's
418 if (sd_bus_message_is_method_error(q->reply, NULL)) {
419 const sd_bus_error *e;
421 /* Copy error from polkit reply */
422 e = sd_bus_message_get_error(q->reply);
423 sd_bus_error_copy(error, e);
425 /* Treat no PK available as access denied */
426 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
429 return -sd_bus_error_get_errno(e);
432 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
434 r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
443 return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
449 r = sd_bus_query_sender_privilege(call, capability);
456 if (sd_bus_get_current_message(call->bus) != call)
459 callback = sd_bus_get_current_handler(call->bus);
463 userdata = sd_bus_get_current_userdata(call->bus);
465 sender = sd_bus_message_get_sender(call);
469 c = sd_bus_message_get_allow_interactive_authorization(call);
475 r = hashmap_ensure_allocated(registry, NULL);
479 r = sd_bus_message_new_method_call(
482 "org.freedesktop.PolicyKit1",
483 "/org/freedesktop/PolicyKit1/Authority",
484 "org.freedesktop.PolicyKit1.Authority",
485 "CheckAuthorization");
489 r = sd_bus_message_append(
492 "system-bus-name", 1, "name", "s", sender,
497 r = sd_bus_message_open_container(pk, 'a', "{ss}");
501 STRV_FOREACH_PAIR(k, v, details) {
502 r = sd_bus_message_append(pk, "{ss}", *k, *v);
507 r = sd_bus_message_close_container(pk);
511 r = sd_bus_message_append(pk, "us", !!interactive, NULL);
515 q = new0(AsyncPolkitQuery, 1);
519 q->request = sd_bus_message_ref(call);
520 q->callback = callback;
521 q->userdata = userdata;
523 r = hashmap_put(*registry, call, q);
525 async_polkit_query_free(q);
529 q->registry = *registry;
531 r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
533 async_polkit_query_free(q);
543 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
547 while ((q = hashmap_steal_first(registry)))
548 async_polkit_query_free(q);
550 hashmap_free(registry);
554 /// UNNEEDED by elogind
556 int bus_check_peercred(sd_bus *c) {
563 fd = sd_bus_get_fd(c);
567 l = sizeof(struct ucred);
568 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
571 if (l != sizeof(struct ucred))
574 if (ucred.uid != 0 && ucred.uid != geteuid())
580 int bus_connect_system_systemd(sd_bus **_bus) {
581 _cleanup_bus_unref_ sd_bus *bus = NULL;
587 return sd_bus_default_system(_bus);
589 /* If we are root and kdbus is not available, then let's talk
590 * directly to the system instance, instead of going via the
593 r = sd_bus_new(&bus);
597 r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
601 bus->bus_client = true;
603 r = sd_bus_start(bus);
610 bus = sd_bus_unref(bus);
612 r = sd_bus_new(&bus);
616 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
620 r = sd_bus_start(bus);
622 return sd_bus_default_system(_bus);
624 r = bus_check_peercred(bus);
634 int bus_connect_user_systemd(sd_bus **_bus) {
635 _cleanup_bus_unref_ sd_bus *bus = NULL;
636 _cleanup_free_ char *ee = NULL;
640 /* Try via kdbus first, and then directly */
644 r = sd_bus_new(&bus);
648 if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
651 bus->bus_client = true;
653 r = sd_bus_start(bus);
660 bus = sd_bus_unref(bus);
662 e = secure_getenv("XDG_RUNTIME_DIR");
664 return sd_bus_default_user(_bus);
666 ee = bus_address_escape(e);
670 r = sd_bus_new(&bus);
674 bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
678 r = sd_bus_start(bus);
680 return sd_bus_default_user(_bus);
682 r = bus_check_peercred(bus);
693 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
695 const char *contents;
701 r = sd_bus_message_peek_type(property, &type, &contents);
707 case SD_BUS_TYPE_STRING: {
710 r = sd_bus_message_read_basic(property, type, &s);
714 if (all || !isempty(s)) {
715 _cleanup_free_ char *escaped = NULL;
717 escaped = xescape(s, "\n");
721 printf("%s=%s\n", name, escaped);
727 case SD_BUS_TYPE_BOOLEAN: {
730 r = sd_bus_message_read_basic(property, type, &b);
734 printf("%s=%s\n", name, yes_no(b));
739 case SD_BUS_TYPE_UINT64: {
742 r = sd_bus_message_read_basic(property, type, &u);
746 /* Yes, heuristics! But we can change this check
747 * should it turn out to not be sufficient */
749 if (endswith(name, "Timestamp")) {
750 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
752 t = format_timestamp(timestamp, sizeof(timestamp), u);
754 printf("%s=%s\n", name, strempty(t));
756 } else if (strstr(name, "USec")) {
757 char timespan[FORMAT_TIMESPAN_MAX];
759 printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
761 printf("%s=%llu\n", name, (unsigned long long) u);
766 case SD_BUS_TYPE_INT64: {
769 r = sd_bus_message_read_basic(property, type, &i);
773 printf("%s=%lld\n", name, (long long) i);
778 case SD_BUS_TYPE_UINT32: {
781 r = sd_bus_message_read_basic(property, type, &u);
785 if (strstr(name, "UMask") || strstr(name, "Mode"))
786 printf("%s=%04o\n", name, u);
788 printf("%s=%u\n", name, (unsigned) u);
793 case SD_BUS_TYPE_INT32: {
796 r = sd_bus_message_read_basic(property, type, &i);
800 printf("%s=%i\n", name, (int) i);
804 case SD_BUS_TYPE_DOUBLE: {
807 r = sd_bus_message_read_basic(property, type, &d);
811 printf("%s=%g\n", name, d);
815 case SD_BUS_TYPE_ARRAY:
816 if (streq(contents, "s")) {
820 r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
824 while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
825 _cleanup_free_ char *escaped = NULL;
830 escaped = xescape(str, "\n ");
834 printf("%s%s", first ? "" : " ", escaped);
846 r = sd_bus_message_exit_container(property);
852 } else if (streq(contents, "y")) {
856 r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
865 for (i = 0; i < n; i++)
866 printf("%02x", u[i]);
873 } else if (streq(contents, "u")) {
877 r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
886 for (i = 0; i < n; i++)
887 printf("%08x", u[i]);
901 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
902 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
903 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
909 r = sd_bus_call_method(bus,
912 "org.freedesktop.DBus.Properties",
920 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
924 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
926 const char *contents;
928 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
932 if (!filter || strv_find(filter, name)) {
933 r = sd_bus_message_peek_type(reply, NULL, &contents);
937 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
941 r = bus_print_property(name, reply, all);
946 printf("%s=[unprintable]\n", name);
947 /* skip what we didn't read */
948 r = sd_bus_message_skip(reply, contents);
953 r = sd_bus_message_exit_container(reply);
957 r = sd_bus_message_skip(reply, "v");
962 r = sd_bus_message_exit_container(reply);
969 r = sd_bus_message_exit_container(reply);
976 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
977 sd_id128_t *p = userdata;
982 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
989 memcpy((*p).bytes, v, n);
996 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1000 r = sd_bus_message_peek_type(m, &type, NULL);
1005 case SD_BUS_TYPE_STRING: {
1007 char **p = userdata;
1009 r = sd_bus_message_read_basic(m, type, &s);
1016 r = free_and_strdup(p, s);
1020 case SD_BUS_TYPE_ARRAY: {
1021 _cleanup_strv_free_ char **l = NULL;
1022 char ***p = userdata;
1024 r = bus_message_read_strv_extend(m, &l);
1035 case SD_BUS_TYPE_BOOLEAN: {
1039 r = sd_bus_message_read_basic(m, type, &b);
1048 case SD_BUS_TYPE_UINT32: {
1050 uint32_t *p = userdata;
1052 r = sd_bus_message_read_basic(m, type, &u);
1061 case SD_BUS_TYPE_UINT64: {
1063 uint64_t *p = userdata;
1065 r = sd_bus_message_read_basic(m, type, &t);
1081 int bus_message_map_all_properties(
1083 const struct bus_properties_map *map,
1086 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1092 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1096 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1097 const struct bus_properties_map *prop;
1099 const char *contents;
1103 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1107 for (i = 0, prop = NULL; map[i].member; i++)
1108 if (streq(map[i].member, member)) {
1114 r = sd_bus_message_peek_type(m, NULL, &contents);
1118 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1122 v = (uint8_t *)userdata + prop->offset;
1124 r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
1126 r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
1130 r = sd_bus_message_exit_container(m);
1134 r = sd_bus_message_skip(m, "v");
1139 r = sd_bus_message_exit_container(m);
1146 return sd_bus_message_exit_container(m);
1149 /// UNNEEDED by elogind
1151 int bus_message_map_properties_changed(
1153 const struct bus_properties_map *map,
1157 int r, invalidated, i;
1162 r = bus_message_map_all_properties(m, map, userdata);
1166 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1171 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1172 for (i = 0; map[i].member; i++)
1173 if (streq(map[i].member, member)) {
1180 r = sd_bus_message_exit_container(m);
1188 int bus_map_all_properties(
1190 const char *destination,
1192 const struct bus_properties_map *map,
1195 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1196 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1200 assert(destination);
1204 r = sd_bus_call_method(
1208 "org.freedesktop.DBus.Properties",
1216 return bus_message_map_all_properties(m, map, userdata);
1219 int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1222 assert(transport >= 0);
1223 assert(transport < _BUS_TRANSPORT_MAX);
1226 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1227 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1229 switch (transport) {
1231 case BUS_TRANSPORT_LOCAL:
1232 /// elogind does not support a user bus
1235 r = sd_bus_default_user(bus);
1238 r = sd_bus_default_system(bus);
1242 case BUS_TRANSPORT_REMOTE:
1243 r = sd_bus_open_system_remote(bus, host);
1246 case BUS_TRANSPORT_MACHINE:
1247 r = sd_bus_open_system_machine(bus, host);
1251 assert_not_reached("Hmm, unknown transport type.");
1257 /// UNNEEDED by elogind
1259 int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1262 assert(transport >= 0);
1263 assert(transport < _BUS_TRANSPORT_MAX);
1266 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1267 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1269 switch (transport) {
1271 case BUS_TRANSPORT_LOCAL:
1273 r = bus_connect_user_systemd(bus);
1275 r = bus_connect_system_systemd(bus);
1279 case BUS_TRANSPORT_REMOTE:
1280 r = sd_bus_open_system_remote(bus, host);
1283 case BUS_TRANSPORT_MACHINE:
1284 r = sd_bus_open_system_machine(bus, host);
1288 assert_not_reached("Hmm, unknown transport type.");
1295 int bus_property_get_bool(
1298 const char *interface,
1299 const char *property,
1300 sd_bus_message *reply,
1302 sd_bus_error *error) {
1304 int b = *(bool*) userdata;
1306 return sd_bus_message_append_basic(reply, 'b', &b);
1309 #if __SIZEOF_SIZE_T__ != 8
1310 int bus_property_get_size(
1313 const char *interface,
1314 const char *property,
1315 sd_bus_message *reply,
1317 sd_bus_error *error) {
1319 uint64_t sz = *(size_t*) userdata;
1321 return sd_bus_message_append_basic(reply, 't', &sz);
1325 #if __SIZEOF_LONG__ != 8
1326 int bus_property_get_long(
1329 const char *interface,
1330 const char *property,
1331 sd_bus_message *reply,
1333 sd_bus_error *error) {
1335 int64_t l = *(long*) userdata;
1337 return sd_bus_message_append_basic(reply, 'x', &l);
1340 int bus_property_get_ulong(
1343 const char *interface,
1344 const char *property,
1345 sd_bus_message *reply,
1347 sd_bus_error *error) {
1349 uint64_t ul = *(unsigned long*) userdata;
1351 return sd_bus_message_append_basic(reply, 't', &ul);
1355 int bus_log_parse_error(int r) {
1356 return log_error_errno(r, "Failed to parse bus message: %m");
1359 /// UNNEEDED by elogind
1361 int bus_log_create_error(int r) {
1362 return log_error_errno(r, "Failed to create bus message: %m");
1365 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1371 return sd_bus_message_read(
1386 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1387 const char *eq, *field;
1393 eq = strchr(assignment, '=');
1395 log_error("Not an assignment: %s", assignment);
1399 field = strndupa(assignment, eq - assignment);
1402 if (streq(field, "CPUQuota")) {
1406 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1408 return bus_log_create_error(r);
1410 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1412 } else if (endswith(eq, "%")) {
1415 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1416 log_error("CPU quota '%s' invalid.", eq);
1420 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1422 return bus_log_create_error(r);
1424 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1426 log_error("CPU quota needs to be in percent.");
1431 return bus_log_create_error(r);
1436 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1438 return bus_log_create_error(r);
1440 if (STR_IN_SET(field,
1441 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
1442 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
1443 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
1444 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges")) {
1446 r = parse_boolean(eq);
1448 log_error("Failed to parse boolean assignment %s.", assignment);
1452 r = sd_bus_message_append(m, "v", "b", r);
1454 } else if (streq(field, "MemoryLimit")) {
1457 if (isempty(eq) || streq(eq, "infinity"))
1458 bytes = (uint64_t) -1;
1460 r = parse_size(eq, 1024, &bytes);
1462 log_error("Failed to parse bytes specification %s", assignment);
1467 r = sd_bus_message_append(m, "v", "t", bytes);
1469 } else if (streq(field, "TasksMax")) {
1472 if (isempty(eq) || streq(eq, "infinity"))
1475 r = safe_atou64(eq, &n);
1477 log_error("Failed to parse maximum tasks specification %s", assignment);
1482 r = sd_bus_message_append(m, "v", "t", n);
1484 } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
1487 r = cg_cpu_shares_parse(eq, &u);
1489 log_error("Failed to parse %s value %s.", field, eq);
1493 r = sd_bus_message_append(m, "v", "t", u);
1495 } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
1498 r = cg_cpu_shares_parse(eq, &u);
1500 log_error("Failed to parse %s value %s.", field, eq);
1504 r = sd_bus_message_append(m, "v", "t", u);
1506 } else if (STR_IN_SET(field,
1507 "User", "Group", "DevicePolicy", "KillMode",
1508 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1509 "StandardInput", "StandardOutput", "StandardError",
1510 "Description", "Slice", "Type", "WorkingDirectory",
1512 r = sd_bus_message_append(m, "v", "s", eq);
1514 else if (streq(field, "DeviceAllow")) {
1517 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1519 const char *path, *rwm, *e;
1521 e = strchr(eq, ' ');
1523 path = strndupa(eq, e - eq);
1530 if (!path_startswith(path, "/dev")) {
1531 log_error("%s is not a device file in /dev.", path);
1535 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1538 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1541 r = sd_bus_message_append(m, "v", "a(st)", 0);
1543 const char *path, *bandwidth, *e;
1546 e = strchr(eq, ' ');
1548 path = strndupa(eq, e - eq);
1551 log_error("Failed to parse %s value %s.", field, eq);
1555 if (!path_startswith(path, "/dev")) {
1556 log_error("%s is not a device file in /dev.", path);
1560 r = parse_size(bandwidth, 1000, &bytes);
1562 log_error("Failed to parse byte value %s.", bandwidth);
1566 r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
1569 } else if (streq(field, "BlockIODeviceWeight")) {
1572 r = sd_bus_message_append(m, "v", "a(st)", 0);
1574 const char *path, *weight, *e;
1577 e = strchr(eq, ' ');
1579 path = strndupa(eq, e - eq);
1582 log_error("Failed to parse %s value %s.", field, eq);
1586 if (!path_startswith(path, "/dev")) {
1587 log_error("%s is not a device file in /dev.", path);
1591 r = safe_atou64(weight, &u);
1593 log_error("Failed to parse %s value %s.", field, weight);
1596 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1599 } else if (rlimit_from_string(field) >= 0) {
1602 if (streq(eq, "infinity"))
1605 r = safe_atou64(eq, &rl);
1607 log_error("Invalid resource limit: %s", eq);
1612 r = sd_bus_message_append(m, "v", "t", rl);
1614 } else if (streq(field, "Nice")) {
1617 r = safe_atoi32(eq, &i);
1619 log_error("Failed to parse %s value %s.", field, eq);
1623 r = sd_bus_message_append(m, "v", "i", i);
1625 } else if (streq(field, "Environment")) {
1627 r = sd_bus_message_append(m, "v", "as", 1, eq);
1629 } else if (streq(field, "KillSignal")) {
1632 sig = signal_from_string_try_harder(eq);
1634 log_error("Failed to parse %s value %s.", field, eq);
1638 r = sd_bus_message_append(m, "v", "i", sig);
1640 } else if (streq(field, "AccuracySec")) {
1643 r = parse_sec(eq, &u);
1645 log_error("Failed to parse %s value %s", field, eq);
1649 r = sd_bus_message_append(m, "v", "t", u);
1652 log_error("Unknown assignment %s.", assignment);
1657 return bus_log_create_error(r);
1663 typedef struct BusWaitForJobs {
1670 sd_bus_slot *slot_job_removed;
1671 sd_bus_slot *slot_disconnected;
1674 /// UNNEEDED by elogind
1676 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1679 log_error("Warning! D-Bus connection terminated.");
1680 sd_bus_close(sd_bus_message_get_bus(m));
1685 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1686 const char *path, *unit, *result;
1687 BusWaitForJobs *d = userdata;
1695 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1697 bus_log_parse_error(r);
1701 found = set_remove(d->jobs, (char*) path);
1707 if (!isempty(result))
1708 d->result = strdup(result);
1711 d->name = strdup(unit);
1716 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1720 set_free_free(d->jobs);
1722 sd_bus_slot_unref(d->slot_disconnected);
1723 sd_bus_slot_unref(d->slot_job_removed);
1725 sd_bus_unref(d->bus);
1733 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1734 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1740 d = new0(BusWaitForJobs, 1);
1744 d->bus = sd_bus_ref(bus);
1746 /* When we are a bus client we match by sender. Direct
1747 * connections OTOH have no initialized sender field, and
1748 * hence we ignore the sender then */
1749 r = sd_bus_add_match(
1751 &d->slot_job_removed,
1754 "sender='org.freedesktop.systemd1',"
1755 "interface='org.freedesktop.systemd1.Manager',"
1756 "member='JobRemoved',"
1757 "path='/org/freedesktop/systemd1'" :
1759 "interface='org.freedesktop.systemd1.Manager',"
1760 "member='JobRemoved',"
1761 "path='/org/freedesktop/systemd1'",
1762 match_job_removed, d);
1766 r = sd_bus_add_match(
1768 &d->slot_disconnected,
1770 "sender='org.freedesktop.DBus.Local',"
1771 "interface='org.freedesktop.DBus.Local',"
1772 "member='Disconnected'",
1773 match_disconnected, d);
1783 static int bus_process_wait(sd_bus *bus) {
1787 r = sd_bus_process(bus, NULL);
1793 r = sd_bus_wait(bus, (uint64_t) -1);
1799 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1800 _cleanup_free_ char *dbus_path = NULL;
1806 dbus_path = unit_dbus_path_from_name(d->name);
1810 return sd_bus_get_property_string(d->bus,
1811 "org.freedesktop.systemd1",
1813 "org.freedesktop.systemd1.Service",
1819 static const struct {
1820 const char *result, *explanation;
1821 } explanations [] = {
1822 { "resources", "a configured resource limit was exceeded" },
1823 { "timeout", "a timeout was exceeded" },
1824 { "exit-code", "the control process exited with error code" },
1825 { "signal", "a fatal signal was delivered to the control process" },
1826 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1827 { "watchdog", "the service failed to send watchdog ping" },
1828 { "start-limit", "start of the service was attempted too often" }
1831 static void log_job_error_with_service_result(const char* service, const char *result) {
1832 _cleanup_free_ char *service_shell_quoted = NULL;
1836 service_shell_quoted = shell_maybe_quote(service);
1838 if (!isempty(result)) {
1841 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1842 if (streq(result, explanations[i].result))
1845 if (i < ELEMENTSOF(explanations)) {
1846 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1848 explanations[i].explanation,
1849 strna(service_shell_quoted));
1855 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1857 strna(service_shell_quoted));
1860 /* For some results maybe additional explanation is required */
1861 if (streq_ptr(result, "start-limit"))
1862 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1863 strna(service_shell_quoted));
1866 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1872 if (streq(d->result, "canceled"))
1873 log_error("Job for %s canceled.", strna(d->name));
1874 else if (streq(d->result, "timeout"))
1875 log_error("Job for %s timed out.", strna(d->name));
1876 else if (streq(d->result, "dependency"))
1877 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1878 else if (streq(d->result, "invalid"))
1879 log_error("Job for %s invalid.", strna(d->name));
1880 else if (streq(d->result, "assert"))
1881 log_error("Assertion failed on job for %s.", strna(d->name));
1882 else if (streq(d->result, "unsupported"))
1883 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1884 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1887 _cleanup_free_ char *result = NULL;
1889 q = bus_job_get_service_result(d, &result);
1891 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1893 log_job_error_with_service_result(d->name, result);
1895 log_error("Job failed. See \"journalctl -xe\" for details.");
1899 if (streq(d->result, "canceled"))
1901 else if (streq(d->result, "timeout"))
1903 else if (streq(d->result, "dependency"))
1905 else if (streq(d->result, "invalid"))
1907 else if (streq(d->result, "assert"))
1909 else if (streq(d->result, "unsupported"))
1911 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1917 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1922 while (!set_isempty(d->jobs)) {
1925 q = bus_process_wait(d->bus);
1927 return log_error_errno(q, "Failed to wait for response: %m");
1930 q = check_wait_response(d, quiet);
1931 /* Return the first error as it is most likely to be
1933 if (q < 0 && r == 0)
1936 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1939 d->name = mfree(d->name);
1940 d->result = mfree(d->result);
1946 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1951 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1955 return set_put_strdup(d->jobs, path);
1958 int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
1961 r = bus_wait_for_jobs_add(d, path);
1965 return bus_wait_for_jobs(d, quiet);
1968 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1969 const char *type, *path, *source;
1972 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1974 return bus_log_parse_error(r);
1976 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1978 if (streq(type, "symlink"))
1979 log_info("Created symlink from %s to %s.", path, source);
1981 log_info("Removed symlink %s.", path);
1984 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1989 return bus_log_parse_error(r);
1991 r = sd_bus_message_exit_container(m);
1993 return bus_log_parse_error(r);
1999 * bus_path_encode_unique() - encode unique object path
2000 * @b: bus connection or NULL
2001 * @prefix: object path prefix
2002 * @sender_id: unique-name of client, or NULL
2003 * @external_id: external ID to be chosen by client, or NULL
2004 * @ret_path: storage for encoded object path pointer
2006 * Whenever we provide a bus API that allows clients to create and manage
2007 * server-side objects, we need to provide a unique name for these objects. If
2008 * we let the server choose the name, we suffer from a race condition: If a
2009 * client creates an object asynchronously, it cannot destroy that object until
2010 * it received the method reply. It cannot know the name of the new object,
2011 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
2013 * Therefore, many APIs allow the client to choose the unique name for newly
2014 * created objects. There're two problems to solve, though:
2015 * 1) Object names are usually defined via dbus object paths, which are
2016 * usually globally namespaced. Therefore, multiple clients must be able
2017 * to choose unique object names without interference.
2018 * 2) If multiple libraries share the same bus connection, they must be
2019 * able to choose unique object names without interference.
2020 * The first problem is solved easily by prefixing a name with the
2021 * unique-bus-name of a connection. The server side must enforce this and
2022 * reject any other name. The second problem is solved by providing unique
2023 * suffixes from within sd-bus.
2025 * This helper allows clients to create unique object-paths. It uses the
2026 * template '/prefix/sender_id/external_id' and returns the new path in
2027 * @ret_path (must be freed by the caller).
2028 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
2029 * NULL, this function allocates a unique suffix via @b (by requesting a new
2030 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2033 * Returns: 0 on success, negative error code on failure.
2035 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
2036 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
2037 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
2040 assert_return(b || (sender_id && external_id), -EINVAL);
2041 assert_return(object_path_is_valid(prefix), -EINVAL);
2042 assert_return(ret_path, -EINVAL);
2045 r = sd_bus_get_unique_name(b, &sender_id);
2051 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
2052 external_id = external_buf;
2055 sender_label = bus_label_escape(sender_id);
2059 external_label = bus_label_escape(external_id);
2060 if (!external_label)
2063 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
2072 * bus_path_decode_unique() - decode unique object path
2073 * @path: object path to decode
2074 * @prefix: object path prefix
2075 * @ret_sender: output parameter for sender-id label
2076 * @ret_external: output parameter for external-id label
2078 * This does the reverse of bus_path_encode_unique() (see its description for
2079 * details). Both trailing labels, sender-id and external-id, are unescaped and
2080 * returned in the given output parameters (the caller must free them).
2082 * Note that this function returns 0 if the path does not match the template
2083 * (see bus_path_encode_unique()), 1 if it matched.
2085 * Returns: Negative error code on failure, 0 if the given object path does not
2086 * match the template (return parameters are set to NULL), 1 if it was
2087 * parsed successfully (return parameters contain allocated labels).
2089 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2091 char *sender, *external;
2093 assert(object_path_is_valid(path));
2094 assert(object_path_is_valid(prefix));
2096 assert(ret_external);
2098 p = object_path_startswith(path, prefix);
2101 *ret_external = NULL;
2108 *ret_external = NULL;
2112 sender = bus_label_unescape_n(p, q - p);
2113 external = bus_label_unescape(q + 1);
2114 if (!sender || !external) {
2120 *ret_sender = sender;
2121 *ret_external = external;
2126 bool is_kdbus_wanted(void) {
2127 _cleanup_free_ char *value = NULL;
2129 const bool configured = true;
2131 const bool configured = false;
2136 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2139 r = get_proc_cmdline_key("kdbus=", &value);
2143 return parse_boolean(value) == 1;
2146 bool is_kdbus_available(void) {
2147 _cleanup_close_ int fd = -1;
2148 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2150 if (!is_kdbus_wanted())
2153 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2157 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;