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",
1397 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) {
1399 r = parse_boolean(eq);
1401 log_error("Failed to parse boolean assignment %s.", assignment);
1405 r = sd_bus_message_append(m, "v", "b", r);
1407 } else if (streq(field, "MemoryLimit")) {
1410 r = parse_size(eq, 1024, &bytes);
1412 log_error("Failed to parse bytes specification %s", assignment);
1416 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1418 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1421 r = safe_atou64(eq, &u);
1423 log_error("Failed to parse %s value %s.", field, eq);
1427 r = sd_bus_message_append(m, "v", "t", u);
1429 } else if (STR_IN_SET(field,
1430 "User", "Group", "DevicePolicy", "KillMode",
1431 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1432 "StandardInput", "StandardOutput", "StandardError",
1433 "Description", "Slice", "Type"))
1434 r = sd_bus_message_append(m, "v", "s", eq);
1436 else if (streq(field, "DeviceAllow")) {
1439 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1441 const char *path, *rwm, *e;
1443 e = strchr(eq, ' ');
1445 path = strndupa(eq, e - eq);
1452 if (!path_startswith(path, "/dev")) {
1453 log_error("%s is not a device file in /dev.", path);
1457 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1460 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1463 r = sd_bus_message_append(m, "v", "a(st)", 0);
1465 const char *path, *bandwidth, *e;
1468 e = strchr(eq, ' ');
1470 path = strndupa(eq, e - eq);
1473 log_error("Failed to parse %s value %s.", field, eq);
1477 if (!path_startswith(path, "/dev")) {
1478 log_error("%s is not a device file in /dev.", path);
1482 r = parse_size(bandwidth, 1000, &bytes);
1484 log_error("Failed to parse byte value %s.", bandwidth);
1488 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1491 } else if (streq(field, "BlockIODeviceWeight")) {
1494 r = sd_bus_message_append(m, "v", "a(st)", 0);
1496 const char *path, *weight, *e;
1499 e = strchr(eq, ' ');
1501 path = strndupa(eq, e - eq);
1504 log_error("Failed to parse %s value %s.", field, eq);
1508 if (!path_startswith(path, "/dev")) {
1509 log_error("%s is not a device file in /dev.", path);
1513 r = safe_atou64(weight, &u);
1515 log_error("Failed to parse %s value %s.", field, weight);
1518 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1521 } else if (rlimit_from_string(field) >= 0) {
1524 if (streq(eq, "infinity"))
1527 r = safe_atou64(eq, &rl);
1529 log_error("Invalid resource limit: %s", eq);
1534 r = sd_bus_message_append(m, "v", "t", rl);
1536 } else if (streq(field, "Nice")) {
1539 r = safe_atoi32(eq, &i);
1541 log_error("Failed to parse %s value %s.", field, eq);
1545 r = sd_bus_message_append(m, "v", "i", i);
1547 } else if (streq(field, "Environment")) {
1549 r = sd_bus_message_append(m, "v", "as", 1, eq);
1551 } else if (streq(field, "KillSignal")) {
1554 sig = signal_from_string_try_harder(eq);
1556 log_error("Failed to parse %s value %s.", field, eq);
1560 r = sd_bus_message_append(m, "v", "i", sig);
1562 } else if (streq(field, "AccuracySec")) {
1565 r = parse_sec(eq, &u);
1567 log_error("Failed to parse %s value %s", field, eq);
1571 r = sd_bus_message_append(m, "v", "t", u);
1574 log_error("Unknown assignment %s.", assignment);
1579 return bus_log_create_error(r);
1585 typedef struct BusWaitForJobs {
1592 sd_bus_slot *slot_job_removed;
1593 sd_bus_slot *slot_disconnected;
1596 /// UNNEEDED by elogind
1598 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1601 log_error("Warning! D-Bus connection terminated.");
1602 sd_bus_close(sd_bus_message_get_bus(m));
1607 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1608 const char *path, *unit, *result;
1609 BusWaitForJobs *d = userdata;
1617 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1619 bus_log_parse_error(r);
1623 found = set_remove(d->jobs, (char*) path);
1629 if (!isempty(result))
1630 d->result = strdup(result);
1633 d->name = strdup(unit);
1639 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1643 set_free_free(d->jobs);
1645 sd_bus_slot_unref(d->slot_disconnected);
1646 sd_bus_slot_unref(d->slot_job_removed);
1648 sd_bus_unref(d->bus);
1656 /// UNNEEDED by elogind
1658 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1659 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1665 d = new0(BusWaitForJobs, 1);
1669 d->bus = sd_bus_ref(bus);
1671 /* When we are a bus client we match by sender. Direct
1672 * connections OTOH have no initialized sender field, and
1673 * hence we ignore the sender then */
1674 r = sd_bus_add_match(
1676 &d->slot_job_removed,
1679 "sender='org.freedesktop.systemd1',"
1680 "interface='org.freedesktop.systemd1.Manager',"
1681 "member='JobRemoved',"
1682 "path='/org/freedesktop/systemd1'" :
1684 "interface='org.freedesktop.systemd1.Manager',"
1685 "member='JobRemoved',"
1686 "path='/org/freedesktop/systemd1'",
1687 match_job_removed, d);
1691 r = sd_bus_add_match(
1693 &d->slot_disconnected,
1695 "sender='org.freedesktop.DBus.Local',"
1696 "interface='org.freedesktop.DBus.Local',"
1697 "member='Disconnected'",
1698 match_disconnected, d);
1709 static int bus_process_wait(sd_bus *bus) {
1713 r = sd_bus_process(bus, NULL);
1719 r = sd_bus_wait(bus, (uint64_t) -1);
1725 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1726 _cleanup_free_ char *dbus_path = NULL;
1732 dbus_path = unit_dbus_path_from_name(d->name);
1736 return sd_bus_get_property_string(d->bus,
1737 "org.freedesktop.systemd1",
1739 "org.freedesktop.systemd1.Service",
1745 static const struct {
1746 const char *result, *explanation;
1747 } explanations [] = {
1748 { "resources", "a configured resource limit was exceeded" },
1749 { "timeout", "a timeout was exceeded" },
1750 { "exit-code", "the control process exited with error code" },
1751 { "signal", "a fatal signal was delivered to the control process" },
1752 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1753 { "watchdog", "the service failed to send watchdog ping" },
1754 { "start-limit", "start of the service was attempted too often" }
1757 static void log_job_error_with_service_result(const char* service, const char *result) {
1758 _cleanup_free_ char *service_shell_quoted = NULL;
1762 service_shell_quoted = shell_maybe_quote(service);
1764 if (!isempty(result)) {
1767 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1768 if (streq(result, explanations[i].result))
1771 if (i < ELEMENTSOF(explanations)) {
1772 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1774 explanations[i].explanation,
1775 strna(service_shell_quoted));
1781 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1783 strna(service_shell_quoted));
1786 /* For some results maybe additional explanation is required */
1787 if (streq_ptr(result, "start-limit"))
1788 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1789 strna(service_shell_quoted));
1792 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1798 if (streq(d->result, "canceled"))
1799 log_error("Job for %s canceled.", strna(d->name));
1800 else if (streq(d->result, "timeout"))
1801 log_error("Job for %s timed out.", strna(d->name));
1802 else if (streq(d->result, "dependency"))
1803 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1804 else if (streq(d->result, "invalid"))
1805 log_error("Job for %s invalid.", strna(d->name));
1806 else if (streq(d->result, "assert"))
1807 log_error("Assertion failed on job for %s.", strna(d->name));
1808 else if (streq(d->result, "unsupported"))
1809 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1810 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1813 _cleanup_free_ char *result = NULL;
1815 q = bus_job_get_service_result(d, &result);
1817 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1819 log_job_error_with_service_result(d->name, result);
1821 log_error("Job failed. See \"journalctl -xe\" for details.");
1825 if (streq(d->result, "canceled"))
1827 else if (streq(d->result, "timeout"))
1829 else if (streq(d->result, "dependency"))
1831 else if (streq(d->result, "invalid"))
1833 else if (streq(d->result, "assert"))
1835 else if (streq(d->result, "unsupported"))
1837 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1843 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1848 while (!set_isempty(d->jobs)) {
1851 q = bus_process_wait(d->bus);
1853 return log_error_errno(q, "Failed to wait for response: %m");
1856 q = check_wait_response(d, quiet);
1857 /* Return the first error as it is most likely to be
1859 if (q < 0 && r == 0)
1862 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1875 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1880 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1884 return set_put_strdup(d->jobs, path);
1887 /// UNNEEDED by elogind
1889 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1890 const char *type, *path, *source;
1893 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1895 return bus_log_parse_error(r);
1897 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1899 if (streq(type, "symlink"))
1900 log_info("Created symlink from %s to %s.", path, source);
1902 log_info("Removed symlink %s.", path);
1905 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1910 return bus_log_parse_error(r);
1912 r = sd_bus_message_exit_container(m);
1914 return bus_log_parse_error(r);
1921 * bus_path_encode_unique() - encode unique object path
1922 * @b: bus connection or NULL
1923 * @prefix: object path prefix
1924 * @sender_id: unique-name of client, or NULL
1925 * @external_id: external ID to be chosen by client, or NULL
1926 * @ret_path: storage for encoded object path pointer
1928 * Whenever we provide a bus API that allows clients to create and manage
1929 * server-side objects, we need to provide a unique name for these objects. If
1930 * we let the server choose the name, we suffer from a race condition: If a
1931 * client creates an object asynchronously, it cannot destroy that object until
1932 * it received the method reply. It cannot know the name of the new object,
1933 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1935 * Therefore, many APIs allow the client to choose the unique name for newly
1936 * created objects. There're two problems to solve, though:
1937 * 1) Object names are usually defined via dbus object paths, which are
1938 * usually globally namespaced. Therefore, multiple clients must be able
1939 * to choose unique object names without interference.
1940 * 2) If multiple libraries share the same bus connection, they must be
1941 * able to choose unique object names without interference.
1942 * The first problem is solved easily by prefixing a name with the
1943 * unique-bus-name of a connection. The server side must enforce this and
1944 * reject any other name. The second problem is solved by providing unique
1945 * suffixes from within sd-bus.
1947 * This helper allows clients to create unique object-paths. It uses the
1948 * template '/prefix/sender_id/external_id' and returns the new path in
1949 * @ret_path (must be freed by the caller).
1950 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1951 * NULL, this function allocates a unique suffix via @b (by requesting a new
1952 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1955 * Returns: 0 on success, negative error code on failure.
1957 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1958 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1959 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1962 assert_return(b || (sender_id && external_id), -EINVAL);
1963 assert_return(object_path_is_valid(prefix), -EINVAL);
1964 assert_return(ret_path, -EINVAL);
1967 r = sd_bus_get_unique_name(b, &sender_id);
1973 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1974 external_id = external_buf;
1977 sender_label = bus_label_escape(sender_id);
1981 external_label = bus_label_escape(external_id);
1982 if (!external_label)
1985 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
1994 * bus_path_decode_unique() - decode unique object path
1995 * @path: object path to decode
1996 * @prefix: object path prefix
1997 * @ret_sender: output parameter for sender-id label
1998 * @ret_external: output parameter for external-id label
2000 * This does the reverse of bus_path_encode_unique() (see its description for
2001 * details). Both trailing labels, sender-id and external-id, are unescaped and
2002 * returned in the given output parameters (the caller must free them).
2004 * Note that this function returns 0 if the path does not match the template
2005 * (see bus_path_encode_unique()), 1 if it matched.
2007 * Returns: Negative error code on failure, 0 if the given object path does not
2008 * match the template (return parameters are set to NULL), 1 if it was
2009 * parsed successfully (return parameters contain allocated labels).
2011 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2013 char *sender, *external;
2015 assert(object_path_is_valid(path));
2016 assert(object_path_is_valid(prefix));
2018 assert(ret_external);
2020 p = object_path_startswith(path, prefix);
2023 *ret_external = NULL;
2030 *ret_external = NULL;
2034 sender = bus_label_unescape_n(p, q - p);
2035 external = bus_label_unescape(q + 1);
2036 if (!sender || !external) {
2042 *ret_sender = sender;
2043 *ret_external = external;
2047 bool is_kdbus_wanted(void) {
2048 _cleanup_free_ char *value = NULL;
2050 const bool configured = true;
2052 const bool configured = false;
2057 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2060 r = get_proc_cmdline_key("kdbus=", &value);
2064 return parse_boolean(value) == 1;
2067 bool is_kdbus_available(void) {
2068 _cleanup_close_ int fd = -1;
2069 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2071 if (!is_kdbus_wanted())
2074 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2078 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;