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"
30 #include "path-util.h"
33 #include "signal-util.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-label.h"
39 #include "bus-message.h"
41 #include "bus-internal.h"
43 static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
44 sd_event *e = userdata;
49 sd_bus_close(sd_bus_message_get_bus(m));
55 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
56 _cleanup_free_ char *match = NULL;
64 /* We unregister the name here and then wait for the
65 * NameOwnerChanged signal for this event to arrive before we
66 * quit. We do this in order to make sure that any queued
67 * requests are still processed before we really exit. */
69 r = sd_bus_get_unique_name(bus, &unique);
74 "sender='org.freedesktop.DBus',"
76 "interface='org.freedesktop.DBus',"
77 "member='NameOwnerChanged',"
78 "path='/org/freedesktop/DBus',"
81 "arg2=''", name, unique);
85 r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
89 r = sd_bus_release_name(bus, name);
96 /// UNNEEDED by elogind
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,
235 /* Tests non-interactively! */
237 r = check_good_user(call, good_user);
241 r = sd_bus_query_sender_privilege(call, capability);
248 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
249 int authorized = false, challenge = false;
252 sender = sd_bus_message_get_sender(call);
256 r = sd_bus_call_method(
258 "org.freedesktop.PolicyKit1",
259 "/org/freedesktop/PolicyKit1/Authority",
260 "org.freedesktop.PolicyKit1.Authority",
261 "CheckAuthorization",
265 "system-bus-name", 1, "name", "s", sender,
272 /* Treat no PK available as access denied */
273 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
274 sd_bus_error_free(e);
281 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
285 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
293 *_challenge = challenge;
304 typedef struct AsyncPolkitQuery {
305 sd_bus_message *request, *reply;
306 sd_bus_message_handler_t callback;
312 static void async_polkit_query_free(AsyncPolkitQuery *q) {
317 sd_bus_slot_unref(q->slot);
319 if (q->registry && q->request)
320 hashmap_remove(q->registry, q->request);
322 sd_bus_message_unref(q->request);
323 sd_bus_message_unref(q->reply);
328 static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
329 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
330 AsyncPolkitQuery *q = userdata;
336 q->slot = sd_bus_slot_unref(q->slot);
337 q->reply = sd_bus_message_ref(reply);
339 r = sd_bus_message_rewind(q->request, true);
341 r = sd_bus_reply_method_errno(q->request, r, NULL);
345 r = q->callback(q->request, q->userdata, &error_buffer);
346 r = bus_maybe_reply_error(q->request, r, &error_buffer);
349 async_polkit_query_free(q);
356 int bus_verify_polkit_async(
357 sd_bus_message *call,
363 sd_bus_error *error) {
366 _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
369 sd_bus_message_handler_t callback;
379 r = check_good_user(call, good_user);
384 q = hashmap_get(*registry, call);
386 int authorized, challenge;
388 /* This is the second invocation of this function, and
389 * there's already a response from polkit, let's
393 if (sd_bus_message_is_method_error(q->reply, NULL)) {
394 const sd_bus_error *e;
396 /* Copy error from polkit reply */
397 e = sd_bus_message_get_error(q->reply);
398 sd_bus_error_copy(error, e);
400 /* Treat no PK available as access denied */
401 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
404 return -sd_bus_error_get_errno(e);
407 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
409 r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
418 return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
424 r = sd_bus_query_sender_privilege(call, capability);
431 if (sd_bus_get_current_message(call->bus) != call)
434 callback = sd_bus_get_current_handler(call->bus);
438 userdata = sd_bus_get_current_userdata(call->bus);
440 sender = sd_bus_message_get_sender(call);
444 c = sd_bus_message_get_allow_interactive_authorization(call);
450 r = hashmap_ensure_allocated(registry, NULL);
454 r = sd_bus_message_new_method_call(
457 "org.freedesktop.PolicyKit1",
458 "/org/freedesktop/PolicyKit1/Authority",
459 "org.freedesktop.PolicyKit1.Authority",
460 "CheckAuthorization");
464 r = sd_bus_message_append(
467 "system-bus-name", 1, "name", "s", sender,
475 q = new0(AsyncPolkitQuery, 1);
479 q->request = sd_bus_message_ref(call);
480 q->callback = callback;
481 q->userdata = userdata;
483 r = hashmap_put(*registry, call, q);
485 async_polkit_query_free(q);
489 q->registry = *registry;
491 r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
493 async_polkit_query_free(q);
503 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
507 while ((q = hashmap_steal_first(registry)))
508 async_polkit_query_free(q);
510 hashmap_free(registry);
514 int bus_check_peercred(sd_bus *c) {
521 fd = sd_bus_get_fd(c);
525 l = sizeof(struct ucred);
526 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
529 if (l != sizeof(struct ucred))
532 if (ucred.uid != 0 && ucred.uid != geteuid())
538 int bus_open_system_systemd(sd_bus **_bus) {
539 _cleanup_bus_unref_ sd_bus *bus = NULL;
545 return sd_bus_open_system(_bus);
547 /* If we are root and kdbus is not available, then let's talk
548 * directly to the system instance, instead of going via the
551 r = sd_bus_new(&bus);
555 r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
559 bus->bus_client = true;
561 r = sd_bus_start(bus);
568 bus = sd_bus_unref(bus);
570 r = sd_bus_new(&bus);
574 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
578 r = sd_bus_start(bus);
580 return sd_bus_open_system(_bus);
582 r = bus_check_peercred(bus);
592 int bus_open_user_systemd(sd_bus **_bus) {
593 _cleanup_bus_unref_ sd_bus *bus = NULL;
594 _cleanup_free_ char *ee = NULL;
598 /* Try via kdbus first, and then directly */
602 r = sd_bus_new(&bus);
606 if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
609 bus->bus_client = true;
611 r = sd_bus_start(bus);
618 bus = sd_bus_unref(bus);
620 e = secure_getenv("XDG_RUNTIME_DIR");
622 return sd_bus_open_user(_bus);
624 ee = bus_address_escape(e);
628 r = sd_bus_new(&bus);
632 bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
636 r = sd_bus_start(bus);
638 return sd_bus_open_user(_bus);
640 r = bus_check_peercred(bus);
650 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
652 const char *contents;
658 r = sd_bus_message_peek_type(property, &type, &contents);
664 case SD_BUS_TYPE_STRING: {
667 r = sd_bus_message_read_basic(property, type, &s);
671 if (all || !isempty(s)) {
672 _cleanup_free_ char *escaped = NULL;
674 escaped = xescape(s, "\n");
678 printf("%s=%s\n", name, escaped);
684 case SD_BUS_TYPE_BOOLEAN: {
687 r = sd_bus_message_read_basic(property, type, &b);
691 printf("%s=%s\n", name, yes_no(b));
696 case SD_BUS_TYPE_UINT64: {
699 r = sd_bus_message_read_basic(property, type, &u);
703 /* Yes, heuristics! But we can change this check
704 * should it turn out to not be sufficient */
706 if (endswith(name, "Timestamp")) {
707 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
709 t = format_timestamp(timestamp, sizeof(timestamp), u);
711 printf("%s=%s\n", name, strempty(t));
713 } else if (strstr(name, "USec")) {
714 char timespan[FORMAT_TIMESPAN_MAX];
716 printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
718 printf("%s=%llu\n", name, (unsigned long long) u);
723 case SD_BUS_TYPE_INT64: {
726 r = sd_bus_message_read_basic(property, type, &i);
730 printf("%s=%lld\n", name, (long long) i);
735 case SD_BUS_TYPE_UINT32: {
738 r = sd_bus_message_read_basic(property, type, &u);
742 if (strstr(name, "UMask") || strstr(name, "Mode"))
743 printf("%s=%04o\n", name, u);
745 printf("%s=%u\n", name, (unsigned) u);
750 case SD_BUS_TYPE_INT32: {
753 r = sd_bus_message_read_basic(property, type, &i);
757 printf("%s=%i\n", name, (int) i);
761 case SD_BUS_TYPE_DOUBLE: {
764 r = sd_bus_message_read_basic(property, type, &d);
768 printf("%s=%g\n", name, d);
772 case SD_BUS_TYPE_ARRAY:
773 if (streq(contents, "s")) {
777 r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
781 while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
782 _cleanup_free_ char *escaped = NULL;
787 escaped = xescape(str, "\n ");
791 printf("%s%s", first ? "" : " ", escaped);
803 r = sd_bus_message_exit_container(property);
809 } else if (streq(contents, "y")) {
813 r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
822 for (i = 0; i < n; i++)
823 printf("%02x", u[i]);
830 } else if (streq(contents, "u")) {
834 r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
843 for (i = 0; i < n; i++)
844 printf("%08x", u[i]);
858 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
859 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
860 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
866 r = sd_bus_call_method(bus,
869 "org.freedesktop.DBus.Properties",
877 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
881 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
883 const char *contents;
885 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
889 if (!filter || strv_find(filter, name)) {
890 r = sd_bus_message_peek_type(reply, NULL, &contents);
894 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
898 r = bus_print_property(name, reply, all);
903 printf("%s=[unprintable]\n", name);
904 /* skip what we didn't read */
905 r = sd_bus_message_skip(reply, contents);
910 r = sd_bus_message_exit_container(reply);
914 r = sd_bus_message_skip(reply, "v");
919 r = sd_bus_message_exit_container(reply);
926 r = sd_bus_message_exit_container(reply);
933 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
934 sd_id128_t *p = userdata;
939 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
946 memcpy((*p).bytes, v, n);
953 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
957 r = sd_bus_message_peek_type(m, &type, NULL);
962 case SD_BUS_TYPE_STRING: {
966 r = sd_bus_message_read_basic(m, type, &s);
973 r = free_and_strdup(p, s);
977 case SD_BUS_TYPE_ARRAY: {
978 _cleanup_strv_free_ char **l = NULL;
979 char ***p = userdata;
981 r = bus_message_read_strv_extend(m, &l);
992 case SD_BUS_TYPE_BOOLEAN: {
996 r = sd_bus_message_read_basic(m, type, &b);
1005 case SD_BUS_TYPE_UINT32: {
1007 uint32_t *p = userdata;
1009 r = sd_bus_message_read_basic(m, type, &u);
1018 case SD_BUS_TYPE_UINT64: {
1020 uint64_t *p = userdata;
1022 r = sd_bus_message_read_basic(m, type, &t);
1038 int bus_message_map_all_properties(
1040 const struct bus_properties_map *map,
1043 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1049 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1053 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1054 const struct bus_properties_map *prop;
1056 const char *contents;
1060 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1064 for (i = 0, prop = NULL; map[i].member; i++)
1065 if (streq(map[i].member, member)) {
1071 r = sd_bus_message_peek_type(m, NULL, &contents);
1075 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1079 v = (uint8_t *)userdata + prop->offset;
1081 r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
1083 r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
1087 r = sd_bus_message_exit_container(m);
1091 r = sd_bus_message_skip(m, "v");
1096 r = sd_bus_message_exit_container(m);
1103 return sd_bus_message_exit_container(m);
1106 /// UNNEEDED by elogind
1108 int bus_message_map_properties_changed(
1110 const struct bus_properties_map *map,
1114 int r, invalidated, i;
1119 r = bus_message_map_all_properties(m, map, userdata);
1123 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1128 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1129 for (i = 0; map[i].member; i++)
1130 if (streq(map[i].member, member)) {
1137 r = sd_bus_message_exit_container(m);
1145 int bus_map_all_properties(
1147 const char *destination,
1149 const struct bus_properties_map *map,
1152 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1153 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1157 assert(destination);
1161 r = sd_bus_call_method(
1165 "org.freedesktop.DBus.Properties",
1173 return bus_message_map_all_properties(m, map, userdata);
1176 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1179 assert(transport >= 0);
1180 assert(transport < _BUS_TRANSPORT_MAX);
1183 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1184 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1186 switch (transport) {
1188 case BUS_TRANSPORT_LOCAL:
1190 r = sd_bus_default_user(bus);
1192 r = sd_bus_default_system(bus);
1196 case BUS_TRANSPORT_REMOTE:
1197 r = sd_bus_open_system_remote(bus, host);
1200 case BUS_TRANSPORT_MACHINE:
1201 r = sd_bus_open_system_machine(bus, host);
1205 assert_not_reached("Hmm, unknown transport type.");
1211 /// UNNEEDED by elogind
1213 int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1216 assert(transport >= 0);
1217 assert(transport < _BUS_TRANSPORT_MAX);
1220 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1221 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1223 switch (transport) {
1225 case BUS_TRANSPORT_LOCAL:
1227 r = bus_open_user_systemd(bus);
1229 r = bus_open_system_systemd(bus);
1233 case BUS_TRANSPORT_REMOTE:
1234 r = sd_bus_open_system_remote(bus, host);
1237 case BUS_TRANSPORT_MACHINE:
1238 r = sd_bus_open_system_machine(bus, host);
1242 assert_not_reached("Hmm, unknown transport type.");
1249 int bus_property_get_bool(
1252 const char *interface,
1253 const char *property,
1254 sd_bus_message *reply,
1256 sd_bus_error *error) {
1258 int b = *(bool*) userdata;
1260 return sd_bus_message_append_basic(reply, 'b', &b);
1263 #if __SIZEOF_SIZE_T__ != 8
1264 int bus_property_get_size(
1267 const char *interface,
1268 const char *property,
1269 sd_bus_message *reply,
1271 sd_bus_error *error) {
1273 uint64_t sz = *(size_t*) userdata;
1275 return sd_bus_message_append_basic(reply, 't', &sz);
1279 #if __SIZEOF_LONG__ != 8
1280 int bus_property_get_long(
1283 const char *interface,
1284 const char *property,
1285 sd_bus_message *reply,
1287 sd_bus_error *error) {
1289 int64_t l = *(long*) userdata;
1291 return sd_bus_message_append_basic(reply, 'x', &l);
1294 int bus_property_get_ulong(
1297 const char *interface,
1298 const char *property,
1299 sd_bus_message *reply,
1301 sd_bus_error *error) {
1303 uint64_t ul = *(unsigned long*) userdata;
1305 return sd_bus_message_append_basic(reply, 't', &ul);
1309 int bus_log_parse_error(int r) {
1310 return log_error_errno(r, "Failed to parse bus message: %m");
1313 int bus_log_create_error(int r) {
1314 return log_error_errno(r, "Failed to create bus message: %m");
1317 /// UNNEEDED by elogind
1319 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1325 return sd_bus_message_read(
1340 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1341 const char *eq, *field;
1347 eq = strchr(assignment, '=');
1349 log_error("Not an assignment: %s", assignment);
1353 field = strndupa(assignment, eq - assignment);
1356 if (streq(field, "CPUQuota")) {
1360 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1362 return bus_log_create_error(r);
1364 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1366 } else if (endswith(eq, "%")) {
1369 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1370 log_error("CPU quota '%s' invalid.", eq);
1374 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1376 return bus_log_create_error(r);
1378 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1380 log_error("CPU quota needs to be in percent.");
1385 return bus_log_create_error(r);
1390 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1392 return bus_log_create_error(r);
1394 if (STR_IN_SET(field,
1395 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1396 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
1398 r = parse_boolean(eq);
1400 log_error("Failed to parse boolean assignment %s.", assignment);
1404 r = sd_bus_message_append(m, "v", "b", r);
1406 } else if (streq(field, "MemoryLimit")) {
1409 r = parse_size(eq, 1024, &bytes);
1411 log_error("Failed to parse bytes specification %s", assignment);
1415 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1417 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1420 r = safe_atou64(eq, &u);
1422 log_error("Failed to parse %s value %s.", field, eq);
1426 r = sd_bus_message_append(m, "v", "t", u);
1428 } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
1429 r = sd_bus_message_append(m, "v", "s", eq);
1431 else if (streq(field, "DeviceAllow")) {
1434 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1436 const char *path, *rwm, *e;
1438 e = strchr(eq, ' ');
1440 path = strndupa(eq, e - eq);
1447 if (!path_startswith(path, "/dev")) {
1448 log_error("%s is not a device file in /dev.", path);
1452 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1455 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1458 r = sd_bus_message_append(m, "v", "a(st)", 0);
1460 const char *path, *bandwidth, *e;
1463 e = strchr(eq, ' ');
1465 path = strndupa(eq, e - eq);
1468 log_error("Failed to parse %s value %s.", field, eq);
1472 if (!path_startswith(path, "/dev")) {
1473 log_error("%s is not a device file in /dev.", path);
1477 r = parse_size(bandwidth, 1000, &bytes);
1479 log_error("Failed to parse byte value %s.", bandwidth);
1483 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1486 } else if (streq(field, "BlockIODeviceWeight")) {
1489 r = sd_bus_message_append(m, "v", "a(st)", 0);
1491 const char *path, *weight, *e;
1494 e = strchr(eq, ' ');
1496 path = strndupa(eq, e - eq);
1499 log_error("Failed to parse %s value %s.", field, eq);
1503 if (!path_startswith(path, "/dev")) {
1504 log_error("%s is not a device file in /dev.", path);
1508 r = safe_atou64(weight, &u);
1510 log_error("Failed to parse %s value %s.", field, weight);
1513 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1516 } else if (rlimit_from_string(field) >= 0) {
1519 if (streq(eq, "infinity"))
1522 r = safe_atou64(eq, &rl);
1524 log_error("Invalid resource limit: %s", eq);
1529 r = sd_bus_message_append(m, "v", "t", rl);
1531 } else if (streq(field, "Nice")) {
1534 r = safe_atoi32(eq, &i);
1536 log_error("Failed to parse %s value %s.", field, eq);
1540 r = sd_bus_message_append(m, "v", "i", i);
1542 } else if (streq(field, "Environment")) {
1544 r = sd_bus_message_append(m, "v", "as", 1, eq);
1546 } else if (streq(field, "KillSignal")) {
1549 sig = signal_from_string_try_harder(eq);
1551 log_error("Failed to parse %s value %s.", field, eq);
1555 r = sd_bus_message_append(m, "v", "i", sig);
1557 } else if (streq(field, "AccuracySec")) {
1560 r = parse_sec(eq, &u);
1562 log_error("Failed to parse %s value %s", field, eq);
1566 r = sd_bus_message_append(m, "v", "t", u);
1569 log_error("Unknown assignment %s.", assignment);
1574 return bus_log_create_error(r);
1580 typedef struct BusWaitForJobs {
1587 sd_bus_slot *slot_job_removed;
1588 sd_bus_slot *slot_disconnected;
1591 /// UNNEEDED by elogind
1593 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1596 log_error("Warning! D-Bus connection terminated.");
1597 sd_bus_close(sd_bus_message_get_bus(m));
1602 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1603 const char *path, *unit, *result;
1604 BusWaitForJobs *d = userdata;
1612 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1614 bus_log_parse_error(r);
1618 found = set_remove(d->jobs, (char*) path);
1624 if (!isempty(result))
1625 d->result = strdup(result);
1628 d->name = strdup(unit);
1634 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1638 set_free_free(d->jobs);
1640 sd_bus_slot_unref(d->slot_disconnected);
1641 sd_bus_slot_unref(d->slot_job_removed);
1643 sd_bus_unref(d->bus);
1651 /// UNNEEDED by elogind
1653 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1654 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1660 d = new0(BusWaitForJobs, 1);
1664 d->bus = sd_bus_ref(bus);
1666 /* When we are a bus client we match by sender. Direct
1667 * connections OTOH have no initialized sender field, and
1668 * hence we ignore the sender then */
1669 r = sd_bus_add_match(
1671 &d->slot_job_removed,
1674 "sender='org.freedesktop.systemd1',"
1675 "interface='org.freedesktop.systemd1.Manager',"
1676 "member='JobRemoved',"
1677 "path='/org/freedesktop/systemd1'" :
1679 "interface='org.freedesktop.systemd1.Manager',"
1680 "member='JobRemoved',"
1681 "path='/org/freedesktop/systemd1'",
1682 match_job_removed, d);
1686 r = sd_bus_add_match(
1688 &d->slot_disconnected,
1690 "sender='org.freedesktop.DBus.Local',"
1691 "interface='org.freedesktop.DBus.Local',"
1692 "member='Disconnected'",
1693 match_disconnected, d);
1704 static int bus_process_wait(sd_bus *bus) {
1708 r = sd_bus_process(bus, NULL);
1714 r = sd_bus_wait(bus, (uint64_t) -1);
1720 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1721 _cleanup_free_ char *dbus_path = NULL;
1727 dbus_path = unit_dbus_path_from_name(d->name);
1731 return sd_bus_get_property_string(d->bus,
1732 "org.freedesktop.systemd1",
1734 "org.freedesktop.systemd1.Service",
1740 static const struct {
1741 const char *result, *explanation;
1742 } explanations [] = {
1743 { "resources", "a configured resource limit was exceeded" },
1744 { "timeout", "a timeout was exceeded" },
1745 { "exit-code", "the control process exited with error code" },
1746 { "signal", "a fatal signal was delivered to the control process" },
1747 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1748 { "watchdog", "the service failed to send watchdog ping" },
1749 { "start-limit", "start of the service was attempted too often" }
1752 static void log_job_error_with_service_result(const char* service, const char *result) {
1753 _cleanup_free_ char *service_shell_quoted = NULL;
1757 service_shell_quoted = shell_maybe_quote(service);
1759 if (!isempty(result)) {
1762 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1763 if (streq(result, explanations[i].result))
1766 if (i < ELEMENTSOF(explanations)) {
1767 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1769 explanations[i].explanation,
1770 strna(service_shell_quoted));
1776 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1778 strna(service_shell_quoted));
1781 /* For some results maybe additional explanation is required */
1782 if (streq_ptr(result, "start-limit"))
1783 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1784 strna(service_shell_quoted));
1787 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1793 if (streq(d->result, "canceled"))
1794 log_error("Job for %s canceled.", strna(d->name));
1795 else if (streq(d->result, "timeout"))
1796 log_error("Job for %s timed out.", strna(d->name));
1797 else if (streq(d->result, "dependency"))
1798 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1799 else if (streq(d->result, "invalid"))
1800 log_error("Job for %s invalid.", strna(d->name));
1801 else if (streq(d->result, "assert"))
1802 log_error("Assertion failed on job for %s.", strna(d->name));
1803 else if (streq(d->result, "unsupported"))
1804 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1805 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1808 _cleanup_free_ char *result = NULL;
1810 q = bus_job_get_service_result(d, &result);
1812 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1814 log_job_error_with_service_result(d->name, result);
1816 log_error("Job failed. See \"journalctl -xe\" for details.");
1820 if (streq(d->result, "canceled"))
1822 else if (streq(d->result, "timeout"))
1824 else if (streq(d->result, "dependency"))
1826 else if (streq(d->result, "invalid"))
1828 else if (streq(d->result, "assert"))
1830 else if (streq(d->result, "unsupported"))
1832 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1838 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1843 while (!set_isempty(d->jobs)) {
1846 q = bus_process_wait(d->bus);
1848 return log_error_errno(q, "Failed to wait for response: %m");
1851 q = check_wait_response(d, quiet);
1852 /* Return the first error as it is most likely to be
1854 if (q < 0 && r == 0)
1857 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1870 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1875 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1879 return set_put_strdup(d->jobs, path);
1882 /// UNNEEDED by elogind
1884 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1885 const char *type, *path, *source;
1888 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1890 return bus_log_parse_error(r);
1892 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1894 if (streq(type, "symlink"))
1895 log_info("Created symlink from %s to %s.", path, source);
1897 log_info("Removed symlink %s.", path);
1900 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1905 return bus_log_parse_error(r);
1907 r = sd_bus_message_exit_container(m);
1909 return bus_log_parse_error(r);
1916 * bus_path_encode_unique() - encode unique object path
1917 * @b: bus connection or NULL
1918 * @prefix: object path prefix
1919 * @sender_id: unique-name of client, or NULL
1920 * @external_id: external ID to be chosen by client, or NULL
1921 * @ret_path: storage for encoded object path pointer
1923 * Whenever we provide a bus API that allows clients to create and manage
1924 * server-side objects, we need to provide a unique name for these objects. If
1925 * we let the server choose the name, we suffer from a race condition: If a
1926 * client creates an object asynchronously, it cannot destroy that object until
1927 * it received the method reply. It cannot know the name of the new object,
1928 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1930 * Therefore, many APIs allow the client to choose the unique name for newly
1931 * created objects. There're two problems to solve, though:
1932 * 1) Object names are usually defined via dbus object paths, which are
1933 * usually globally namespaced. Therefore, multiple clients must be able
1934 * to choose unique object names without interference.
1935 * 2) If multiple libraries share the same bus connection, they must be
1936 * able to choose unique object names without interference.
1937 * The first problem is solved easily by prefixing a name with the
1938 * unique-bus-name of a connection. The server side must enforce this and
1939 * reject any other name. The second problem is solved by providing unique
1940 * suffixes from within sd-bus.
1942 * This helper allows clients to create unique object-paths. It uses the
1943 * template '/prefix/sender_id/external_id' and returns the new path in
1944 * @ret_path (must be freed by the caller).
1945 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1946 * NULL, this function allocates a unique suffix via @b (by requesting a new
1947 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1950 * Returns: 0 on success, negative error code on failure.
1952 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1953 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1954 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1957 assert_return(b || (sender_id && external_id), -EINVAL);
1958 assert_return(object_path_is_valid(prefix), -EINVAL);
1959 assert_return(ret_path, -EINVAL);
1962 r = sd_bus_get_unique_name(b, &sender_id);
1968 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1969 external_id = external_buf;
1972 sender_label = bus_label_escape(sender_id);
1976 external_label = bus_label_escape(external_id);
1977 if (!external_label)
1980 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
1989 * bus_path_decode_unique() - decode unique object path
1990 * @path: object path to decode
1991 * @prefix: object path prefix
1992 * @ret_sender: output parameter for sender-id label
1993 * @ret_external: output parameter for external-id label
1995 * This does the reverse of bus_path_encode_unique() (see its description for
1996 * details). Both trailing labels, sender-id and external-id, are unescaped and
1997 * returned in the given output parameters (the caller must free them).
1999 * Note that this function returns 0 if the path does not match the template
2000 * (see bus_path_encode_unique()), 1 if it matched.
2002 * Returns: Negative error code on failure, 0 if the given object path does not
2003 * match the template (return parameters are set to NULL), 1 if it was
2004 * parsed successfully (return parameters contain allocated labels).
2006 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2008 char *sender, *external;
2010 assert(object_path_is_valid(path));
2011 assert(object_path_is_valid(prefix));
2013 assert(ret_external);
2015 p = object_path_startswith(path, prefix);
2018 *ret_external = NULL;
2025 *ret_external = NULL;
2029 sender = bus_label_unescape_n(p, q - p);
2030 external = bus_label_unescape(q + 1);
2031 if (!sender || !external) {
2037 *ret_sender = sender;
2038 *ret_external = external;
2042 bool is_kdbus_wanted(void) {
2043 _cleanup_free_ char *value = NULL;
2045 const bool configured = true;
2047 const bool configured = false;
2052 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2055 r = get_proc_cmdline_key("kdbus=", &value);
2059 return parse_boolean(value) == 1;
2062 bool is_kdbus_available(void) {
2063 _cleanup_close_ int fd = -1;
2064 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2066 if (!is_kdbus_wanted())
2069 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2073 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;