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,
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 int bus_check_peercred(sd_bus *c) {
561 fd = sd_bus_get_fd(c);
565 l = sizeof(struct ucred);
566 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
569 if (l != sizeof(struct ucred))
572 if (ucred.uid != 0 && ucred.uid != geteuid())
578 int bus_open_system_systemd(sd_bus **_bus) {
579 _cleanup_bus_unref_ sd_bus *bus = NULL;
585 return sd_bus_open_system(_bus);
587 /* If we are root and kdbus is not available, then let's talk
588 * directly to the system instance, instead of going via the
591 r = sd_bus_new(&bus);
595 r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
599 bus->bus_client = true;
601 r = sd_bus_start(bus);
608 bus = sd_bus_unref(bus);
610 r = sd_bus_new(&bus);
614 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
618 r = sd_bus_start(bus);
620 return sd_bus_open_system(_bus);
622 r = bus_check_peercred(bus);
632 int bus_open_user_systemd(sd_bus **_bus) {
633 _cleanup_bus_unref_ sd_bus *bus = NULL;
634 _cleanup_free_ char *ee = NULL;
638 /* Try via kdbus first, and then directly */
642 r = sd_bus_new(&bus);
646 if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
649 bus->bus_client = true;
651 r = sd_bus_start(bus);
658 bus = sd_bus_unref(bus);
660 e = secure_getenv("XDG_RUNTIME_DIR");
662 return sd_bus_open_user(_bus);
664 ee = bus_address_escape(e);
668 r = sd_bus_new(&bus);
672 bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
676 r = sd_bus_start(bus);
678 return sd_bus_open_user(_bus);
680 r = bus_check_peercred(bus);
690 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
692 const char *contents;
698 r = sd_bus_message_peek_type(property, &type, &contents);
704 case SD_BUS_TYPE_STRING: {
707 r = sd_bus_message_read_basic(property, type, &s);
711 if (all || !isempty(s)) {
712 _cleanup_free_ char *escaped = NULL;
714 escaped = xescape(s, "\n");
718 printf("%s=%s\n", name, escaped);
724 case SD_BUS_TYPE_BOOLEAN: {
727 r = sd_bus_message_read_basic(property, type, &b);
731 printf("%s=%s\n", name, yes_no(b));
736 case SD_BUS_TYPE_UINT64: {
739 r = sd_bus_message_read_basic(property, type, &u);
743 /* Yes, heuristics! But we can change this check
744 * should it turn out to not be sufficient */
746 if (endswith(name, "Timestamp")) {
747 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
749 t = format_timestamp(timestamp, sizeof(timestamp), u);
751 printf("%s=%s\n", name, strempty(t));
753 } else if (strstr(name, "USec")) {
754 char timespan[FORMAT_TIMESPAN_MAX];
756 printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
758 printf("%s=%llu\n", name, (unsigned long long) u);
763 case SD_BUS_TYPE_INT64: {
766 r = sd_bus_message_read_basic(property, type, &i);
770 printf("%s=%lld\n", name, (long long) i);
775 case SD_BUS_TYPE_UINT32: {
778 r = sd_bus_message_read_basic(property, type, &u);
782 if (strstr(name, "UMask") || strstr(name, "Mode"))
783 printf("%s=%04o\n", name, u);
785 printf("%s=%u\n", name, (unsigned) u);
790 case SD_BUS_TYPE_INT32: {
793 r = sd_bus_message_read_basic(property, type, &i);
797 printf("%s=%i\n", name, (int) i);
801 case SD_BUS_TYPE_DOUBLE: {
804 r = sd_bus_message_read_basic(property, type, &d);
808 printf("%s=%g\n", name, d);
812 case SD_BUS_TYPE_ARRAY:
813 if (streq(contents, "s")) {
817 r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
821 while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
822 _cleanup_free_ char *escaped = NULL;
827 escaped = xescape(str, "\n ");
831 printf("%s%s", first ? "" : " ", escaped);
843 r = sd_bus_message_exit_container(property);
849 } else if (streq(contents, "y")) {
853 r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
862 for (i = 0; i < n; i++)
863 printf("%02x", u[i]);
870 } else if (streq(contents, "u")) {
874 r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
883 for (i = 0; i < n; i++)
884 printf("%08x", u[i]);
898 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
899 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
900 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
906 r = sd_bus_call_method(bus,
909 "org.freedesktop.DBus.Properties",
917 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
921 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
923 const char *contents;
925 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
929 if (!filter || strv_find(filter, name)) {
930 r = sd_bus_message_peek_type(reply, NULL, &contents);
934 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
938 r = bus_print_property(name, reply, all);
943 printf("%s=[unprintable]\n", name);
944 /* skip what we didn't read */
945 r = sd_bus_message_skip(reply, contents);
950 r = sd_bus_message_exit_container(reply);
954 r = sd_bus_message_skip(reply, "v");
959 r = sd_bus_message_exit_container(reply);
966 r = sd_bus_message_exit_container(reply);
973 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
974 sd_id128_t *p = userdata;
979 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
986 memcpy((*p).bytes, v, n);
993 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
997 r = sd_bus_message_peek_type(m, &type, NULL);
1002 case SD_BUS_TYPE_STRING: {
1004 char **p = userdata;
1006 r = sd_bus_message_read_basic(m, type, &s);
1013 r = free_and_strdup(p, s);
1017 case SD_BUS_TYPE_ARRAY: {
1018 _cleanup_strv_free_ char **l = NULL;
1019 char ***p = userdata;
1021 r = bus_message_read_strv_extend(m, &l);
1032 case SD_BUS_TYPE_BOOLEAN: {
1036 r = sd_bus_message_read_basic(m, type, &b);
1045 case SD_BUS_TYPE_UINT32: {
1047 uint32_t *p = userdata;
1049 r = sd_bus_message_read_basic(m, type, &u);
1058 case SD_BUS_TYPE_UINT64: {
1060 uint64_t *p = userdata;
1062 r = sd_bus_message_read_basic(m, type, &t);
1078 int bus_message_map_all_properties(
1080 const struct bus_properties_map *map,
1083 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1089 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1093 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1094 const struct bus_properties_map *prop;
1096 const char *contents;
1100 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1104 for (i = 0, prop = NULL; map[i].member; i++)
1105 if (streq(map[i].member, member)) {
1111 r = sd_bus_message_peek_type(m, NULL, &contents);
1115 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1119 v = (uint8_t *)userdata + prop->offset;
1121 r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
1123 r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
1127 r = sd_bus_message_exit_container(m);
1131 r = sd_bus_message_skip(m, "v");
1136 r = sd_bus_message_exit_container(m);
1143 return sd_bus_message_exit_container(m);
1146 /// UNNEEDED by elogind
1148 int bus_message_map_properties_changed(
1150 const struct bus_properties_map *map,
1154 int r, invalidated, i;
1159 r = bus_message_map_all_properties(m, map, userdata);
1163 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1168 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1169 for (i = 0; map[i].member; i++)
1170 if (streq(map[i].member, member)) {
1177 r = sd_bus_message_exit_container(m);
1185 int bus_map_all_properties(
1187 const char *destination,
1189 const struct bus_properties_map *map,
1192 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1193 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1197 assert(destination);
1201 r = sd_bus_call_method(
1205 "org.freedesktop.DBus.Properties",
1213 return bus_message_map_all_properties(m, map, userdata);
1216 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1219 assert(transport >= 0);
1220 assert(transport < _BUS_TRANSPORT_MAX);
1223 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1224 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1226 switch (transport) {
1228 case BUS_TRANSPORT_LOCAL:
1230 r = sd_bus_default_user(bus);
1232 r = sd_bus_default_system(bus);
1236 case BUS_TRANSPORT_REMOTE:
1237 r = sd_bus_open_system_remote(bus, host);
1240 case BUS_TRANSPORT_MACHINE:
1241 r = sd_bus_open_system_machine(bus, host);
1245 assert_not_reached("Hmm, unknown transport type.");
1251 /// UNNEEDED by elogind
1253 int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1256 assert(transport >= 0);
1257 assert(transport < _BUS_TRANSPORT_MAX);
1260 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1261 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1263 switch (transport) {
1265 case BUS_TRANSPORT_LOCAL:
1267 r = bus_open_user_systemd(bus);
1269 r = bus_open_system_systemd(bus);
1273 case BUS_TRANSPORT_REMOTE:
1274 r = sd_bus_open_system_remote(bus, host);
1277 case BUS_TRANSPORT_MACHINE:
1278 r = sd_bus_open_system_machine(bus, host);
1282 assert_not_reached("Hmm, unknown transport type.");
1289 int bus_property_get_bool(
1292 const char *interface,
1293 const char *property,
1294 sd_bus_message *reply,
1296 sd_bus_error *error) {
1298 int b = *(bool*) userdata;
1300 return sd_bus_message_append_basic(reply, 'b', &b);
1303 #if __SIZEOF_SIZE_T__ != 8
1304 int bus_property_get_size(
1307 const char *interface,
1308 const char *property,
1309 sd_bus_message *reply,
1311 sd_bus_error *error) {
1313 uint64_t sz = *(size_t*) userdata;
1315 return sd_bus_message_append_basic(reply, 't', &sz);
1319 #if __SIZEOF_LONG__ != 8
1320 int bus_property_get_long(
1323 const char *interface,
1324 const char *property,
1325 sd_bus_message *reply,
1327 sd_bus_error *error) {
1329 int64_t l = *(long*) userdata;
1331 return sd_bus_message_append_basic(reply, 'x', &l);
1334 int bus_property_get_ulong(
1337 const char *interface,
1338 const char *property,
1339 sd_bus_message *reply,
1341 sd_bus_error *error) {
1343 uint64_t ul = *(unsigned long*) userdata;
1345 return sd_bus_message_append_basic(reply, 't', &ul);
1349 int bus_log_parse_error(int r) {
1350 return log_error_errno(r, "Failed to parse bus message: %m");
1353 int bus_log_create_error(int r) {
1354 return log_error_errno(r, "Failed to create bus message: %m");
1357 /// UNNEEDED by elogind
1359 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1365 return sd_bus_message_read(
1380 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1381 const char *eq, *field;
1387 eq = strchr(assignment, '=');
1389 log_error("Not an assignment: %s", assignment);
1393 field = strndupa(assignment, eq - assignment);
1396 if (streq(field, "CPUQuota")) {
1400 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1402 return bus_log_create_error(r);
1404 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1406 } else if (endswith(eq, "%")) {
1409 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1410 log_error("CPU quota '%s' invalid.", eq);
1414 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1416 return bus_log_create_error(r);
1418 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1420 log_error("CPU quota needs to be in percent.");
1425 return bus_log_create_error(r);
1430 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1432 return bus_log_create_error(r);
1434 if (STR_IN_SET(field,
1435 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1436 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
1437 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) {
1439 r = parse_boolean(eq);
1441 log_error("Failed to parse boolean assignment %s.", assignment);
1445 r = sd_bus_message_append(m, "v", "b", r);
1447 } else if (streq(field, "MemoryLimit")) {
1450 r = parse_size(eq, 1024, &bytes);
1452 log_error("Failed to parse bytes specification %s", assignment);
1456 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1458 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1461 r = safe_atou64(eq, &u);
1463 log_error("Failed to parse %s value %s.", field, eq);
1467 r = sd_bus_message_append(m, "v", "t", u);
1469 } else if (STR_IN_SET(field,
1470 "User", "Group", "DevicePolicy", "KillMode",
1471 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1472 "StandardInput", "StandardOutput", "StandardError",
1473 "Description", "Slice", "Type"))
1474 r = sd_bus_message_append(m, "v", "s", eq);
1476 else if (streq(field, "DeviceAllow")) {
1479 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1481 const char *path, *rwm, *e;
1483 e = strchr(eq, ' ');
1485 path = strndupa(eq, e - eq);
1492 if (!path_startswith(path, "/dev")) {
1493 log_error("%s is not a device file in /dev.", path);
1497 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1500 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1503 r = sd_bus_message_append(m, "v", "a(st)", 0);
1505 const char *path, *bandwidth, *e;
1508 e = strchr(eq, ' ');
1510 path = strndupa(eq, e - eq);
1513 log_error("Failed to parse %s value %s.", field, eq);
1517 if (!path_startswith(path, "/dev")) {
1518 log_error("%s is not a device file in /dev.", path);
1522 r = parse_size(bandwidth, 1000, &bytes);
1524 log_error("Failed to parse byte value %s.", bandwidth);
1528 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1531 } else if (streq(field, "BlockIODeviceWeight")) {
1534 r = sd_bus_message_append(m, "v", "a(st)", 0);
1536 const char *path, *weight, *e;
1539 e = strchr(eq, ' ');
1541 path = strndupa(eq, e - eq);
1544 log_error("Failed to parse %s value %s.", field, eq);
1548 if (!path_startswith(path, "/dev")) {
1549 log_error("%s is not a device file in /dev.", path);
1553 r = safe_atou64(weight, &u);
1555 log_error("Failed to parse %s value %s.", field, weight);
1558 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1561 } else if (rlimit_from_string(field) >= 0) {
1564 if (streq(eq, "infinity"))
1567 r = safe_atou64(eq, &rl);
1569 log_error("Invalid resource limit: %s", eq);
1574 r = sd_bus_message_append(m, "v", "t", rl);
1576 } else if (streq(field, "Nice")) {
1579 r = safe_atoi32(eq, &i);
1581 log_error("Failed to parse %s value %s.", field, eq);
1585 r = sd_bus_message_append(m, "v", "i", i);
1587 } else if (streq(field, "Environment")) {
1589 r = sd_bus_message_append(m, "v", "as", 1, eq);
1591 } else if (streq(field, "KillSignal")) {
1594 sig = signal_from_string_try_harder(eq);
1596 log_error("Failed to parse %s value %s.", field, eq);
1600 r = sd_bus_message_append(m, "v", "i", sig);
1602 } else if (streq(field, "AccuracySec")) {
1605 r = parse_sec(eq, &u);
1607 log_error("Failed to parse %s value %s", field, eq);
1611 r = sd_bus_message_append(m, "v", "t", u);
1614 log_error("Unknown assignment %s.", assignment);
1619 return bus_log_create_error(r);
1625 typedef struct BusWaitForJobs {
1632 sd_bus_slot *slot_job_removed;
1633 sd_bus_slot *slot_disconnected;
1636 /// UNNEEDED by elogind
1638 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1641 log_error("Warning! D-Bus connection terminated.");
1642 sd_bus_close(sd_bus_message_get_bus(m));
1647 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1648 const char *path, *unit, *result;
1649 BusWaitForJobs *d = userdata;
1657 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1659 bus_log_parse_error(r);
1663 found = set_remove(d->jobs, (char*) path);
1669 if (!isempty(result))
1670 d->result = strdup(result);
1673 d->name = strdup(unit);
1679 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1683 set_free_free(d->jobs);
1685 sd_bus_slot_unref(d->slot_disconnected);
1686 sd_bus_slot_unref(d->slot_job_removed);
1688 sd_bus_unref(d->bus);
1696 /// UNNEEDED by elogind
1698 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1699 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1705 d = new0(BusWaitForJobs, 1);
1709 d->bus = sd_bus_ref(bus);
1711 /* When we are a bus client we match by sender. Direct
1712 * connections OTOH have no initialized sender field, and
1713 * hence we ignore the sender then */
1714 r = sd_bus_add_match(
1716 &d->slot_job_removed,
1719 "sender='org.freedesktop.systemd1',"
1720 "interface='org.freedesktop.systemd1.Manager',"
1721 "member='JobRemoved',"
1722 "path='/org/freedesktop/systemd1'" :
1724 "interface='org.freedesktop.systemd1.Manager',"
1725 "member='JobRemoved',"
1726 "path='/org/freedesktop/systemd1'",
1727 match_job_removed, d);
1731 r = sd_bus_add_match(
1733 &d->slot_disconnected,
1735 "sender='org.freedesktop.DBus.Local',"
1736 "interface='org.freedesktop.DBus.Local',"
1737 "member='Disconnected'",
1738 match_disconnected, d);
1749 static int bus_process_wait(sd_bus *bus) {
1753 r = sd_bus_process(bus, NULL);
1759 r = sd_bus_wait(bus, (uint64_t) -1);
1765 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1766 _cleanup_free_ char *dbus_path = NULL;
1772 dbus_path = unit_dbus_path_from_name(d->name);
1776 return sd_bus_get_property_string(d->bus,
1777 "org.freedesktop.systemd1",
1779 "org.freedesktop.systemd1.Service",
1785 static const struct {
1786 const char *result, *explanation;
1787 } explanations [] = {
1788 { "resources", "a configured resource limit was exceeded" },
1789 { "timeout", "a timeout was exceeded" },
1790 { "exit-code", "the control process exited with error code" },
1791 { "signal", "a fatal signal was delivered to the control process" },
1792 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1793 { "watchdog", "the service failed to send watchdog ping" },
1794 { "start-limit", "start of the service was attempted too often" }
1797 static void log_job_error_with_service_result(const char* service, const char *result) {
1798 _cleanup_free_ char *service_shell_quoted = NULL;
1802 service_shell_quoted = shell_maybe_quote(service);
1804 if (!isempty(result)) {
1807 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1808 if (streq(result, explanations[i].result))
1811 if (i < ELEMENTSOF(explanations)) {
1812 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1814 explanations[i].explanation,
1815 strna(service_shell_quoted));
1821 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1823 strna(service_shell_quoted));
1826 /* For some results maybe additional explanation is required */
1827 if (streq_ptr(result, "start-limit"))
1828 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1829 strna(service_shell_quoted));
1832 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1838 if (streq(d->result, "canceled"))
1839 log_error("Job for %s canceled.", strna(d->name));
1840 else if (streq(d->result, "timeout"))
1841 log_error("Job for %s timed out.", strna(d->name));
1842 else if (streq(d->result, "dependency"))
1843 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1844 else if (streq(d->result, "invalid"))
1845 log_error("Job for %s invalid.", strna(d->name));
1846 else if (streq(d->result, "assert"))
1847 log_error("Assertion failed on job for %s.", strna(d->name));
1848 else if (streq(d->result, "unsupported"))
1849 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1850 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1853 _cleanup_free_ char *result = NULL;
1855 q = bus_job_get_service_result(d, &result);
1857 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1859 log_job_error_with_service_result(d->name, result);
1861 log_error("Job failed. See \"journalctl -xe\" for details.");
1865 if (streq(d->result, "canceled"))
1867 else if (streq(d->result, "timeout"))
1869 else if (streq(d->result, "dependency"))
1871 else if (streq(d->result, "invalid"))
1873 else if (streq(d->result, "assert"))
1875 else if (streq(d->result, "unsupported"))
1877 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1883 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1888 while (!set_isempty(d->jobs)) {
1891 q = bus_process_wait(d->bus);
1893 return log_error_errno(q, "Failed to wait for response: %m");
1896 q = check_wait_response(d, quiet);
1897 /* Return the first error as it is most likely to be
1899 if (q < 0 && r == 0)
1902 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1915 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1920 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1924 return set_put_strdup(d->jobs, path);
1927 /// UNNEEDED by elogind
1929 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1930 const char *type, *path, *source;
1933 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1935 return bus_log_parse_error(r);
1937 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1939 if (streq(type, "symlink"))
1940 log_info("Created symlink from %s to %s.", path, source);
1942 log_info("Removed symlink %s.", path);
1945 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1950 return bus_log_parse_error(r);
1952 r = sd_bus_message_exit_container(m);
1954 return bus_log_parse_error(r);
1961 * bus_path_encode_unique() - encode unique object path
1962 * @b: bus connection or NULL
1963 * @prefix: object path prefix
1964 * @sender_id: unique-name of client, or NULL
1965 * @external_id: external ID to be chosen by client, or NULL
1966 * @ret_path: storage for encoded object path pointer
1968 * Whenever we provide a bus API that allows clients to create and manage
1969 * server-side objects, we need to provide a unique name for these objects. If
1970 * we let the server choose the name, we suffer from a race condition: If a
1971 * client creates an object asynchronously, it cannot destroy that object until
1972 * it received the method reply. It cannot know the name of the new object,
1973 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1975 * Therefore, many APIs allow the client to choose the unique name for newly
1976 * created objects. There're two problems to solve, though:
1977 * 1) Object names are usually defined via dbus object paths, which are
1978 * usually globally namespaced. Therefore, multiple clients must be able
1979 * to choose unique object names without interference.
1980 * 2) If multiple libraries share the same bus connection, they must be
1981 * able to choose unique object names without interference.
1982 * The first problem is solved easily by prefixing a name with the
1983 * unique-bus-name of a connection. The server side must enforce this and
1984 * reject any other name. The second problem is solved by providing unique
1985 * suffixes from within sd-bus.
1987 * This helper allows clients to create unique object-paths. It uses the
1988 * template '/prefix/sender_id/external_id' and returns the new path in
1989 * @ret_path (must be freed by the caller).
1990 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1991 * NULL, this function allocates a unique suffix via @b (by requesting a new
1992 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1995 * Returns: 0 on success, negative error code on failure.
1997 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1998 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1999 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
2002 assert_return(b || (sender_id && external_id), -EINVAL);
2003 assert_return(object_path_is_valid(prefix), -EINVAL);
2004 assert_return(ret_path, -EINVAL);
2007 r = sd_bus_get_unique_name(b, &sender_id);
2013 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
2014 external_id = external_buf;
2017 sender_label = bus_label_escape(sender_id);
2021 external_label = bus_label_escape(external_id);
2022 if (!external_label)
2025 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
2034 * bus_path_decode_unique() - decode unique object path
2035 * @path: object path to decode
2036 * @prefix: object path prefix
2037 * @ret_sender: output parameter for sender-id label
2038 * @ret_external: output parameter for external-id label
2040 * This does the reverse of bus_path_encode_unique() (see its description for
2041 * details). Both trailing labels, sender-id and external-id, are unescaped and
2042 * returned in the given output parameters (the caller must free them).
2044 * Note that this function returns 0 if the path does not match the template
2045 * (see bus_path_encode_unique()), 1 if it matched.
2047 * Returns: Negative error code on failure, 0 if the given object path does not
2048 * match the template (return parameters are set to NULL), 1 if it was
2049 * parsed successfully (return parameters contain allocated labels).
2051 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2053 char *sender, *external;
2055 assert(object_path_is_valid(path));
2056 assert(object_path_is_valid(prefix));
2058 assert(ret_external);
2060 p = object_path_startswith(path, prefix);
2063 *ret_external = NULL;
2070 *ret_external = NULL;
2074 sender = bus_label_unescape_n(p, q - p);
2075 external = bus_label_unescape(q + 1);
2076 if (!sender || !external) {
2082 *ret_sender = sender;
2083 *ret_external = external;
2087 bool is_kdbus_wanted(void) {
2088 _cleanup_free_ char *value = NULL;
2090 const bool configured = true;
2092 const bool configured = false;
2097 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2100 r = get_proc_cmdline_key("kdbus=", &value);
2104 return parse_boolean(value) == 1;
2107 bool is_kdbus_available(void) {
2108 _cleanup_close_ int fd = -1;
2109 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2111 if (!is_kdbus_wanted())
2114 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2118 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;