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"
28 #include "bus-error.h"
29 #include "bus-internal.h"
30 #include "bus-label.h"
31 #include "bus-message.h"
32 #include "cgroup-util.h"
36 #include "path-util.h"
38 #include "signal-util.h"
40 #include "unit-name.h"
45 static int name_owner_change_callback(sd_bus_message
*m
, void *userdata
, sd_bus_error
*ret_error
) {
46 sd_event
*e
= userdata
;
51 sd_bus_close(sd_bus_message_get_bus(m
));
57 int bus_async_unregister_and_exit(sd_event
*e
, sd_bus
*bus
, const char *name
) {
58 _cleanup_free_
char *match
= NULL
;
66 /* We unregister the name here and then wait for the
67 * NameOwnerChanged signal for this event to arrive before we
68 * quit. We do this in order to make sure that any queued
69 * requests are still processed before we really exit. */
71 r
= sd_bus_get_unique_name(bus
, &unique
);
76 "sender='org.freedesktop.DBus',"
78 "interface='org.freedesktop.DBus',"
79 "member='NameOwnerChanged',"
80 "path='/org/freedesktop/DBus',"
83 "arg2=''", name
, unique
);
87 r
= sd_bus_add_match(bus
, NULL
, match
, name_owner_change_callback
, e
);
91 r
= sd_bus_release_name(bus
, name
);
98 int bus_event_loop_with_idle(
103 check_idle_t check_idle
,
105 bool exiting
= false;
115 r
= sd_event_get_state(e
);
118 if (r
== SD_EVENT_FINISHED
)
122 idle
= check_idle(userdata
);
126 r
= sd_event_run(e
, exiting
|| !idle
? (uint64_t) -1 : timeout
);
130 if (r
== 0 && !exiting
&& idle
) {
132 r
= sd_bus_try_close(bus
);
136 /* Fallback for dbus1 connections: we
137 * unregister the name and wait for the
138 * response to come through for it */
139 if (r
== -EOPNOTSUPP
) {
141 /* Inform the service manager that we
142 * are going down, so that it will
143 * queue all further start requests,
144 * instead of assuming we are already
146 sd_notify(false, "STOPPING=1");
148 r
= bus_async_unregister_and_exit(e
, bus
, name
);
164 r
= sd_event_get_exit_code(e
, &code
);
171 int bus_name_has_owner(sd_bus
*c
, const char *name
, sd_bus_error
*error
) {
172 _cleanup_bus_message_unref_ sd_bus_message
*rep
= NULL
;
173 int r
, has_owner
= 0;
178 r
= sd_bus_call_method(c
,
179 "org.freedesktop.DBus",
180 "/org/freedesktop/dbus",
181 "org.freedesktop.DBus",
190 r
= sd_bus_message_read_basic(rep
, 'b', &has_owner
);
192 return sd_bus_error_set_errno(error
, r
);
197 static int check_good_user(sd_bus_message
*m
, uid_t good_user
) {
198 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
204 if (good_user
== UID_INVALID
)
207 r
= sd_bus_query_sender_creds(m
, SD_BUS_CREDS_EUID
, &creds
);
211 /* Don't trust augmented credentials for authorization */
212 assert_return((sd_bus_creds_get_augmented_mask(creds
) & SD_BUS_CREDS_EUID
) == 0, -EPERM
);
214 r
= sd_bus_creds_get_euid(creds
, &sender_uid
);
218 return sender_uid
== good_user
;
222 sd_bus_message
*call
,
225 const char **details
,
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
*request
= NULL
;
249 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
250 int authorized
= false, challenge
= false;
251 const char *sender
, **k
, **v
;
253 sender
= sd_bus_message_get_sender(call
);
257 r
= sd_bus_message_new_method_call(
260 "org.freedesktop.PolicyKit1",
261 "/org/freedesktop/PolicyKit1/Authority",
262 "org.freedesktop.PolicyKit1.Authority",
263 "CheckAuthorization");
267 r
= sd_bus_message_append(
270 "system-bus-name", 1, "name", "s", sender
,
275 r
= sd_bus_message_open_container(request
, 'a', "{ss}");
279 STRV_FOREACH_PAIR(k
, v
, details
) {
280 r
= sd_bus_message_append(request
, "{ss}", *k
, *v
);
285 r
= sd_bus_message_close_container(request
);
289 r
= sd_bus_message_append(request
, "us", 0, NULL
);
293 r
= sd_bus_call(call
->bus
, request
, 0, e
, &reply
);
295 /* Treat no PK available as access denied */
296 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
)) {
297 sd_bus_error_free(e
);
304 r
= sd_bus_message_enter_container(reply
, 'r', "bba{ss}");
308 r
= sd_bus_message_read(reply
, "bb", &authorized
, &challenge
);
316 *_challenge
= challenge
;
327 typedef struct AsyncPolkitQuery
{
328 sd_bus_message
*request
, *reply
;
329 sd_bus_message_handler_t callback
;
335 static void async_polkit_query_free(AsyncPolkitQuery
*q
) {
340 sd_bus_slot_unref(q
->slot
);
342 if (q
->registry
&& q
->request
)
343 hashmap_remove(q
->registry
, q
->request
);
345 sd_bus_message_unref(q
->request
);
346 sd_bus_message_unref(q
->reply
);
351 static int async_polkit_callback(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
352 _cleanup_bus_error_free_ sd_bus_error error_buffer
= SD_BUS_ERROR_NULL
;
353 AsyncPolkitQuery
*q
= userdata
;
359 q
->slot
= sd_bus_slot_unref(q
->slot
);
360 q
->reply
= sd_bus_message_ref(reply
);
362 r
= sd_bus_message_rewind(q
->request
, true);
364 r
= sd_bus_reply_method_errno(q
->request
, r
, NULL
);
368 r
= q
->callback(q
->request
, q
->userdata
, &error_buffer
);
369 r
= bus_maybe_reply_error(q
->request
, r
, &error_buffer
);
372 async_polkit_query_free(q
);
379 int bus_verify_polkit_async(
380 sd_bus_message
*call
,
383 const char **details
,
387 sd_bus_error
*error
) {
390 _cleanup_bus_message_unref_ sd_bus_message
*pk
= NULL
;
392 const char *sender
, **k
, **v
;
393 sd_bus_message_handler_t callback
;
403 r
= check_good_user(call
, good_user
);
408 q
= hashmap_get(*registry
, call
);
410 int authorized
, challenge
;
412 /* This is the second invocation of this function, and
413 * there's already a response from polkit, let's
417 if (sd_bus_message_is_method_error(q
->reply
, NULL
)) {
418 const sd_bus_error
*e
;
420 /* Copy error from polkit reply */
421 e
= sd_bus_message_get_error(q
->reply
);
422 sd_bus_error_copy(error
, e
);
424 /* Treat no PK available as access denied */
425 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
))
428 return -sd_bus_error_get_errno(e
);
431 r
= sd_bus_message_enter_container(q
->reply
, 'r', "bba{ss}");
433 r
= sd_bus_message_read(q
->reply
, "bb", &authorized
, &challenge
);
442 return sd_bus_error_set(error
, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED
, "Interactive authentication required.");
448 r
= sd_bus_query_sender_privilege(call
, capability
);
455 if (sd_bus_get_current_message(call
->bus
) != call
)
458 callback
= sd_bus_get_current_handler(call
->bus
);
462 userdata
= sd_bus_get_current_userdata(call
->bus
);
464 sender
= sd_bus_message_get_sender(call
);
468 c
= sd_bus_message_get_allow_interactive_authorization(call
);
474 r
= hashmap_ensure_allocated(registry
, NULL
);
478 r
= sd_bus_message_new_method_call(
481 "org.freedesktop.PolicyKit1",
482 "/org/freedesktop/PolicyKit1/Authority",
483 "org.freedesktop.PolicyKit1.Authority",
484 "CheckAuthorization");
488 r
= sd_bus_message_append(
491 "system-bus-name", 1, "name", "s", sender
,
496 r
= sd_bus_message_open_container(pk
, 'a', "{ss}");
500 STRV_FOREACH_PAIR(k
, v
, details
) {
501 r
= sd_bus_message_append(pk
, "{ss}", *k
, *v
);
506 r
= sd_bus_message_close_container(pk
);
510 r
= sd_bus_message_append(pk
, "us", !!interactive
, NULL
);
514 q
= new0(AsyncPolkitQuery
, 1);
518 q
->request
= sd_bus_message_ref(call
);
519 q
->callback
= callback
;
520 q
->userdata
= userdata
;
522 r
= hashmap_put(*registry
, call
, q
);
524 async_polkit_query_free(q
);
528 q
->registry
= *registry
;
530 r
= sd_bus_call_async(call
->bus
, &q
->slot
, pk
, async_polkit_callback
, q
, 0);
532 async_polkit_query_free(q
);
542 void bus_verify_polkit_async_registry_free(Hashmap
*registry
) {
546 while ((q
= hashmap_steal_first(registry
)))
547 async_polkit_query_free(q
);
549 hashmap_free(registry
);
553 int bus_check_peercred(sd_bus
*c
) {
560 fd
= sd_bus_get_fd(c
);
564 l
= sizeof(struct ucred
);
565 if (getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &ucred
, &l
) < 0)
568 if (l
!= sizeof(struct ucred
))
571 if (ucred
.uid
!= 0 && ucred
.uid
!= geteuid())
577 int bus_open_system_systemd(sd_bus
**_bus
) {
578 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
584 return sd_bus_open_system(_bus
);
586 /* If we are root and kdbus is not available, then let's talk
587 * directly to the system instance, instead of going via the
590 r
= sd_bus_new(&bus
);
594 r
= sd_bus_set_address(bus
, KERNEL_SYSTEM_BUS_ADDRESS
);
598 bus
->bus_client
= true;
600 r
= sd_bus_start(bus
);
607 bus
= sd_bus_unref(bus
);
609 r
= sd_bus_new(&bus
);
613 r
= sd_bus_set_address(bus
, "unix:path=/run/systemd/private");
617 r
= sd_bus_start(bus
);
619 return sd_bus_open_system(_bus
);
621 r
= bus_check_peercred(bus
);
631 int bus_open_user_systemd(sd_bus
**_bus
) {
632 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
633 _cleanup_free_
char *ee
= NULL
;
637 /* Try via kdbus first, and then directly */
641 r
= sd_bus_new(&bus
);
645 if (asprintf(&bus
->address
, KERNEL_USER_BUS_ADDRESS_FMT
, getuid()) < 0)
648 bus
->bus_client
= true;
650 r
= sd_bus_start(bus
);
657 bus
= sd_bus_unref(bus
);
659 e
= secure_getenv("XDG_RUNTIME_DIR");
661 return sd_bus_open_user(_bus
);
663 ee
= bus_address_escape(e
);
667 r
= sd_bus_new(&bus
);
671 bus
->address
= strjoin("unix:path=", ee
, "/systemd/private", NULL
);
675 r
= sd_bus_start(bus
);
677 return sd_bus_open_user(_bus
);
679 r
= bus_check_peercred(bus
);
689 int bus_print_property(const char *name
, sd_bus_message
*property
, bool all
) {
691 const char *contents
;
697 r
= sd_bus_message_peek_type(property
, &type
, &contents
);
703 case SD_BUS_TYPE_STRING
: {
706 r
= sd_bus_message_read_basic(property
, type
, &s
);
710 if (all
|| !isempty(s
)) {
711 _cleanup_free_
char *escaped
= NULL
;
713 escaped
= xescape(s
, "\n");
717 printf("%s=%s\n", name
, escaped
);
723 case SD_BUS_TYPE_BOOLEAN
: {
726 r
= sd_bus_message_read_basic(property
, type
, &b
);
730 printf("%s=%s\n", name
, yes_no(b
));
735 case SD_BUS_TYPE_UINT64
: {
738 r
= sd_bus_message_read_basic(property
, type
, &u
);
742 /* Yes, heuristics! But we can change this check
743 * should it turn out to not be sufficient */
745 if (endswith(name
, "Timestamp")) {
746 char timestamp
[FORMAT_TIMESTAMP_MAX
], *t
;
748 t
= format_timestamp(timestamp
, sizeof(timestamp
), u
);
750 printf("%s=%s\n", name
, strempty(t
));
752 } else if (strstr(name
, "USec")) {
753 char timespan
[FORMAT_TIMESPAN_MAX
];
755 printf("%s=%s\n", name
, format_timespan(timespan
, sizeof(timespan
), u
, 0));
757 printf("%s=%llu\n", name
, (unsigned long long) u
);
762 case SD_BUS_TYPE_INT64
: {
765 r
= sd_bus_message_read_basic(property
, type
, &i
);
769 printf("%s=%lld\n", name
, (long long) i
);
774 case SD_BUS_TYPE_UINT32
: {
777 r
= sd_bus_message_read_basic(property
, type
, &u
);
781 if (strstr(name
, "UMask") || strstr(name
, "Mode"))
782 printf("%s=%04o\n", name
, u
);
784 printf("%s=%u\n", name
, (unsigned) u
);
789 case SD_BUS_TYPE_INT32
: {
792 r
= sd_bus_message_read_basic(property
, type
, &i
);
796 printf("%s=%i\n", name
, (int) i
);
800 case SD_BUS_TYPE_DOUBLE
: {
803 r
= sd_bus_message_read_basic(property
, type
, &d
);
807 printf("%s=%g\n", name
, d
);
811 case SD_BUS_TYPE_ARRAY
:
812 if (streq(contents
, "s")) {
816 r
= sd_bus_message_enter_container(property
, SD_BUS_TYPE_ARRAY
, contents
);
820 while((r
= sd_bus_message_read_basic(property
, SD_BUS_TYPE_STRING
, &str
)) > 0) {
821 _cleanup_free_
char *escaped
= NULL
;
826 escaped
= xescape(str
, "\n ");
830 printf("%s%s", first
? "" : " ", escaped
);
842 r
= sd_bus_message_exit_container(property
);
848 } else if (streq(contents
, "y")) {
852 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_BYTE
, (const void**) &u
, &n
);
861 for (i
= 0; i
< n
; i
++)
862 printf("%02x", u
[i
]);
869 } else if (streq(contents
, "u")) {
873 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_UINT32
, (const void**) &u
, &n
);
882 for (i
= 0; i
< n
; i
++)
883 printf("%08x", u
[i
]);
897 int bus_print_all_properties(sd_bus
*bus
, const char *dest
, const char *path
, char **filter
, bool all
) {
898 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
899 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
905 r
= sd_bus_call_method(bus
,
908 "org.freedesktop.DBus.Properties",
916 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
920 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
922 const char *contents
;
924 r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &name
);
928 if (!filter
|| strv_find(filter
, name
)) {
929 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
933 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
937 r
= bus_print_property(name
, reply
, all
);
942 printf("%s=[unprintable]\n", name
);
943 /* skip what we didn't read */
944 r
= sd_bus_message_skip(reply
, contents
);
949 r
= sd_bus_message_exit_container(reply
);
953 r
= sd_bus_message_skip(reply
, "v");
958 r
= sd_bus_message_exit_container(reply
);
965 r
= sd_bus_message_exit_container(reply
);
972 int bus_map_id128(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
973 sd_id128_t
*p
= userdata
;
978 r
= sd_bus_message_read_array(m
, SD_BUS_TYPE_BYTE
, &v
, &n
);
985 memcpy((*p
).bytes
, v
, n
);
992 static int map_basic(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
996 r
= sd_bus_message_peek_type(m
, &type
, NULL
);
1001 case SD_BUS_TYPE_STRING
: {
1003 char **p
= userdata
;
1005 r
= sd_bus_message_read_basic(m
, type
, &s
);
1012 r
= free_and_strdup(p
, s
);
1016 case SD_BUS_TYPE_ARRAY
: {
1017 _cleanup_strv_free_
char **l
= NULL
;
1018 char ***p
= userdata
;
1020 r
= bus_message_read_strv_extend(m
, &l
);
1031 case SD_BUS_TYPE_BOOLEAN
: {
1035 r
= sd_bus_message_read_basic(m
, type
, &b
);
1044 case SD_BUS_TYPE_UINT32
: {
1046 uint32_t *p
= userdata
;
1048 r
= sd_bus_message_read_basic(m
, type
, &u
);
1057 case SD_BUS_TYPE_UINT64
: {
1059 uint64_t *p
= userdata
;
1061 r
= sd_bus_message_read_basic(m
, type
, &t
);
1077 int bus_message_map_all_properties(
1079 const struct bus_properties_map
*map
,
1082 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1088 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
1092 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1093 const struct bus_properties_map
*prop
;
1095 const char *contents
;
1099 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
);
1103 for (i
= 0, prop
= NULL
; map
[i
].member
; i
++)
1104 if (streq(map
[i
].member
, member
)) {
1110 r
= sd_bus_message_peek_type(m
, NULL
, &contents
);
1114 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, contents
);
1118 v
= (uint8_t *)userdata
+ prop
->offset
;
1120 r
= prop
->set(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1122 r
= map_basic(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1126 r
= sd_bus_message_exit_container(m
);
1130 r
= sd_bus_message_skip(m
, "v");
1135 r
= sd_bus_message_exit_container(m
);
1142 return sd_bus_message_exit_container(m
);
1145 int bus_message_map_properties_changed(
1147 const struct bus_properties_map
*map
,
1151 int r
, invalidated
, i
;
1156 r
= bus_message_map_all_properties(m
, map
, userdata
);
1160 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "s");
1165 while ((r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
)) > 0)
1166 for (i
= 0; map
[i
].member
; i
++)
1167 if (streq(map
[i
].member
, member
)) {
1174 r
= sd_bus_message_exit_container(m
);
1181 int bus_map_all_properties(
1183 const char *destination
,
1185 const struct bus_properties_map
*map
,
1188 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1189 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1193 assert(destination
);
1197 r
= sd_bus_call_method(
1201 "org.freedesktop.DBus.Properties",
1209 return bus_message_map_all_properties(m
, map
, userdata
);
1212 int bus_open_transport(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1215 assert(transport
>= 0);
1216 assert(transport
< _BUS_TRANSPORT_MAX
);
1219 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1220 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1222 switch (transport
) {
1224 case BUS_TRANSPORT_LOCAL
:
1226 r
= sd_bus_default_user(bus
);
1228 r
= sd_bus_default_system(bus
);
1232 case BUS_TRANSPORT_REMOTE
:
1233 r
= sd_bus_open_system_remote(bus
, host
);
1236 case BUS_TRANSPORT_MACHINE
:
1237 r
= sd_bus_open_system_machine(bus
, host
);
1241 assert_not_reached("Hmm, unknown transport type.");
1247 int bus_open_transport_systemd(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1250 assert(transport
>= 0);
1251 assert(transport
< _BUS_TRANSPORT_MAX
);
1254 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1255 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1257 switch (transport
) {
1259 case BUS_TRANSPORT_LOCAL
:
1261 r
= bus_open_user_systemd(bus
);
1263 r
= bus_open_system_systemd(bus
);
1267 case BUS_TRANSPORT_REMOTE
:
1268 r
= sd_bus_open_system_remote(bus
, host
);
1271 case BUS_TRANSPORT_MACHINE
:
1272 r
= sd_bus_open_system_machine(bus
, host
);
1276 assert_not_reached("Hmm, unknown transport type.");
1282 int bus_property_get_bool(
1285 const char *interface
,
1286 const char *property
,
1287 sd_bus_message
*reply
,
1289 sd_bus_error
*error
) {
1291 int b
= *(bool*) userdata
;
1293 return sd_bus_message_append_basic(reply
, 'b', &b
);
1296 #if __SIZEOF_SIZE_T__ != 8
1297 int bus_property_get_size(
1300 const char *interface
,
1301 const char *property
,
1302 sd_bus_message
*reply
,
1304 sd_bus_error
*error
) {
1306 uint64_t sz
= *(size_t*) userdata
;
1308 return sd_bus_message_append_basic(reply
, 't', &sz
);
1312 #if __SIZEOF_LONG__ != 8
1313 int bus_property_get_long(
1316 const char *interface
,
1317 const char *property
,
1318 sd_bus_message
*reply
,
1320 sd_bus_error
*error
) {
1322 int64_t l
= *(long*) userdata
;
1324 return sd_bus_message_append_basic(reply
, 'x', &l
);
1327 int bus_property_get_ulong(
1330 const char *interface
,
1331 const char *property
,
1332 sd_bus_message
*reply
,
1334 sd_bus_error
*error
) {
1336 uint64_t ul
= *(unsigned long*) userdata
;
1338 return sd_bus_message_append_basic(reply
, 't', &ul
);
1342 int bus_log_parse_error(int r
) {
1343 return log_error_errno(r
, "Failed to parse bus message: %m");
1346 int bus_log_create_error(int r
) {
1347 return log_error_errno(r
, "Failed to create bus message: %m");
1350 int bus_parse_unit_info(sd_bus_message
*message
, UnitInfo
*u
) {
1356 return sd_bus_message_read(
1371 int bus_append_unit_property_assignment(sd_bus_message
*m
, const char *assignment
) {
1372 const char *eq
, *field
;
1378 eq
= strchr(assignment
, '=');
1380 log_error("Not an assignment: %s", assignment
);
1384 field
= strndupa(assignment
, eq
- assignment
);
1387 if (streq(field
, "CPUQuota")) {
1391 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, "CPUQuotaPerSecUSec");
1393 return bus_log_create_error(r
);
1395 r
= sd_bus_message_append(m
, "v", "t", USEC_INFINITY
);
1397 } else if (endswith(eq
, "%")) {
1400 if (sscanf(eq
, "%lf%%", &percent
) != 1 || percent
<= 0) {
1401 log_error("CPU quota '%s' invalid.", eq
);
1405 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, "CPUQuotaPerSecUSec");
1407 return bus_log_create_error(r
);
1409 r
= sd_bus_message_append(m
, "v", "t", (usec_t
) percent
* USEC_PER_SEC
/ 100);
1411 log_error("CPU quota needs to be in percent.");
1416 return bus_log_create_error(r
);
1421 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
1423 return bus_log_create_error(r
);
1425 if (STR_IN_SET(field
,
1426 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
1427 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
1428 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
1429 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges")) {
1431 r
= parse_boolean(eq
);
1433 log_error("Failed to parse boolean assignment %s.", assignment
);
1437 r
= sd_bus_message_append(m
, "v", "b", r
);
1439 } else if (streq(field
, "MemoryLimit")) {
1442 if (isempty(eq
) || streq(eq
, "infinity"))
1443 bytes
= (uint64_t) -1;
1445 r
= parse_size(eq
, 1024, &bytes
);
1447 log_error("Failed to parse bytes specification %s", assignment
);
1452 r
= sd_bus_message_append(m
, "v", "t", bytes
);
1454 } else if (streq(field
, "TasksMax")) {
1457 if (isempty(eq
) || streq(eq
, "infinity"))
1460 r
= safe_atou64(eq
, &n
);
1462 log_error("Failed to parse maximum tasks specification %s", assignment
);
1467 r
= sd_bus_message_append(m
, "v", "t", n
);
1469 } else if (STR_IN_SET(field
, "CPUShares", "StartupCPUShares")) {
1472 r
= cg_cpu_shares_parse(eq
, &u
);
1474 log_error("Failed to parse %s value %s.", field
, eq
);
1478 r
= sd_bus_message_append(m
, "v", "t", u
);
1480 } else if (STR_IN_SET(field
, "BlockIOWeight", "StartupBlockIOWeight")) {
1483 r
= cg_cpu_shares_parse(eq
, &u
);
1485 log_error("Failed to parse %s value %s.", field
, eq
);
1489 r
= sd_bus_message_append(m
, "v", "t", u
);
1491 } else if (STR_IN_SET(field
,
1492 "User", "Group", "DevicePolicy", "KillMode",
1493 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1494 "StandardInput", "StandardOutput", "StandardError",
1495 "Description", "Slice", "Type"))
1496 r
= sd_bus_message_append(m
, "v", "s", eq
);
1498 else if (streq(field
, "DeviceAllow")) {
1501 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1503 const char *path
, *rwm
, *e
;
1505 e
= strchr(eq
, ' ');
1507 path
= strndupa(eq
, e
- eq
);
1514 if (!path_startswith(path
, "/dev")) {
1515 log_error("%s is not a device file in /dev.", path
);
1519 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1522 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1525 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1527 const char *path
, *bandwidth
, *e
;
1530 e
= strchr(eq
, ' ');
1532 path
= strndupa(eq
, e
- eq
);
1535 log_error("Failed to parse %s value %s.", field
, eq
);
1539 if (!path_startswith(path
, "/dev")) {
1540 log_error("%s is not a device file in /dev.", path
);
1544 r
= parse_size(bandwidth
, 1000, &bytes
);
1546 log_error("Failed to parse byte value %s.", bandwidth
);
1550 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, bytes
);
1553 } else if (streq(field
, "BlockIODeviceWeight")) {
1556 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1558 const char *path
, *weight
, *e
;
1561 e
= strchr(eq
, ' ');
1563 path
= strndupa(eq
, e
- eq
);
1566 log_error("Failed to parse %s value %s.", field
, eq
);
1570 if (!path_startswith(path
, "/dev")) {
1571 log_error("%s is not a device file in /dev.", path
);
1575 r
= safe_atou64(weight
, &u
);
1577 log_error("Failed to parse %s value %s.", field
, weight
);
1580 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1583 } else if (rlimit_from_string(field
) >= 0) {
1586 if (streq(eq
, "infinity"))
1589 r
= safe_atou64(eq
, &rl
);
1591 log_error("Invalid resource limit: %s", eq
);
1596 r
= sd_bus_message_append(m
, "v", "t", rl
);
1598 } else if (streq(field
, "Nice")) {
1601 r
= safe_atoi32(eq
, &i
);
1603 log_error("Failed to parse %s value %s.", field
, eq
);
1607 r
= sd_bus_message_append(m
, "v", "i", i
);
1609 } else if (streq(field
, "Environment")) {
1611 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1613 } else if (streq(field
, "KillSignal")) {
1616 sig
= signal_from_string_try_harder(eq
);
1618 log_error("Failed to parse %s value %s.", field
, eq
);
1622 r
= sd_bus_message_append(m
, "v", "i", sig
);
1624 } else if (streq(field
, "AccuracySec")) {
1627 r
= parse_sec(eq
, &u
);
1629 log_error("Failed to parse %s value %s", field
, eq
);
1633 r
= sd_bus_message_append(m
, "v", "t", u
);
1636 log_error("Unknown assignment %s.", assignment
);
1641 return bus_log_create_error(r
);
1646 typedef struct BusWaitForJobs
{
1653 sd_bus_slot
*slot_job_removed
;
1654 sd_bus_slot
*slot_disconnected
;
1657 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1660 log_error("Warning! D-Bus connection terminated.");
1661 sd_bus_close(sd_bus_message_get_bus(m
));
1666 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1667 const char *path
, *unit
, *result
;
1668 BusWaitForJobs
*d
= userdata
;
1676 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1678 bus_log_parse_error(r
);
1682 found
= set_remove(d
->jobs
, (char*) path
);
1688 if (!isempty(result
))
1689 d
->result
= strdup(result
);
1692 d
->name
= strdup(unit
);
1697 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1701 set_free_free(d
->jobs
);
1703 sd_bus_slot_unref(d
->slot_disconnected
);
1704 sd_bus_slot_unref(d
->slot_job_removed
);
1706 sd_bus_unref(d
->bus
);
1714 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1715 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1721 d
= new0(BusWaitForJobs
, 1);
1725 d
->bus
= sd_bus_ref(bus
);
1727 /* When we are a bus client we match by sender. Direct
1728 * connections OTOH have no initialized sender field, and
1729 * hence we ignore the sender then */
1730 r
= sd_bus_add_match(
1732 &d
->slot_job_removed
,
1735 "sender='org.freedesktop.systemd1',"
1736 "interface='org.freedesktop.systemd1.Manager',"
1737 "member='JobRemoved',"
1738 "path='/org/freedesktop/systemd1'" :
1740 "interface='org.freedesktop.systemd1.Manager',"
1741 "member='JobRemoved',"
1742 "path='/org/freedesktop/systemd1'",
1743 match_job_removed
, d
);
1747 r
= sd_bus_add_match(
1749 &d
->slot_disconnected
,
1751 "sender='org.freedesktop.DBus.Local',"
1752 "interface='org.freedesktop.DBus.Local',"
1753 "member='Disconnected'",
1754 match_disconnected
, d
);
1764 static int bus_process_wait(sd_bus
*bus
) {
1768 r
= sd_bus_process(bus
, NULL
);
1774 r
= sd_bus_wait(bus
, (uint64_t) -1);
1780 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1781 _cleanup_free_
char *dbus_path
= NULL
;
1787 dbus_path
= unit_dbus_path_from_name(d
->name
);
1791 return sd_bus_get_property_string(d
->bus
,
1792 "org.freedesktop.systemd1",
1794 "org.freedesktop.systemd1.Service",
1800 static const struct {
1801 const char *result
, *explanation
;
1802 } explanations
[] = {
1803 { "resources", "a configured resource limit was exceeded" },
1804 { "timeout", "a timeout was exceeded" },
1805 { "exit-code", "the control process exited with error code" },
1806 { "signal", "a fatal signal was delivered to the control process" },
1807 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1808 { "watchdog", "the service failed to send watchdog ping" },
1809 { "start-limit", "start of the service was attempted too often" }
1812 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1813 _cleanup_free_
char *service_shell_quoted
= NULL
;
1817 service_shell_quoted
= shell_maybe_quote(service
);
1819 if (!isempty(result
)) {
1822 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1823 if (streq(result
, explanations
[i
].result
))
1826 if (i
< ELEMENTSOF(explanations
)) {
1827 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1829 explanations
[i
].explanation
,
1830 strna(service_shell_quoted
));
1836 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1838 strna(service_shell_quoted
));
1841 /* For some results maybe additional explanation is required */
1842 if (streq_ptr(result
, "start-limit"))
1843 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1844 strna(service_shell_quoted
));
1847 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1853 if (streq(d
->result
, "canceled"))
1854 log_error("Job for %s canceled.", strna(d
->name
));
1855 else if (streq(d
->result
, "timeout"))
1856 log_error("Job for %s timed out.", strna(d
->name
));
1857 else if (streq(d
->result
, "dependency"))
1858 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1859 else if (streq(d
->result
, "invalid"))
1860 log_error("Job for %s invalid.", strna(d
->name
));
1861 else if (streq(d
->result
, "assert"))
1862 log_error("Assertion failed on job for %s.", strna(d
->name
));
1863 else if (streq(d
->result
, "unsupported"))
1864 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1865 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1868 _cleanup_free_
char *result
= NULL
;
1870 q
= bus_job_get_service_result(d
, &result
);
1872 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1874 log_job_error_with_service_result(d
->name
, result
);
1876 log_error("Job failed. See \"journalctl -xe\" for details.");
1880 if (streq(d
->result
, "canceled"))
1882 else if (streq(d
->result
, "timeout"))
1884 else if (streq(d
->result
, "dependency"))
1886 else if (streq(d
->result
, "invalid"))
1888 else if (streq(d
->result
, "assert"))
1890 else if (streq(d
->result
, "unsupported"))
1892 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1898 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1903 while (!set_isempty(d
->jobs
)) {
1906 q
= bus_process_wait(d
->bus
);
1908 return log_error_errno(q
, "Failed to wait for response: %m");
1911 q
= check_wait_response(d
, quiet
);
1912 /* Return the first error as it is most likely to be
1914 if (q
< 0 && r
== 0)
1917 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1920 d
->name
= mfree(d
->name
);
1921 d
->result
= mfree(d
->result
);
1927 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1932 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1936 return set_put_strdup(d
->jobs
, path
);
1939 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1942 r
= bus_wait_for_jobs_add(d
, path
);
1946 return bus_wait_for_jobs(d
, quiet
);
1949 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1950 const char *type
, *path
, *source
;
1953 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1955 return bus_log_parse_error(r
);
1957 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1959 if (streq(type
, "symlink"))
1960 log_info("Created symlink from %s to %s.", path
, source
);
1962 log_info("Removed symlink %s.", path
);
1965 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
1970 return bus_log_parse_error(r
);
1972 r
= sd_bus_message_exit_container(m
);
1974 return bus_log_parse_error(r
);
1980 * bus_path_encode_unique() - encode unique object path
1981 * @b: bus connection or NULL
1982 * @prefix: object path prefix
1983 * @sender_id: unique-name of client, or NULL
1984 * @external_id: external ID to be chosen by client, or NULL
1985 * @ret_path: storage for encoded object path pointer
1987 * Whenever we provide a bus API that allows clients to create and manage
1988 * server-side objects, we need to provide a unique name for these objects. If
1989 * we let the server choose the name, we suffer from a race condition: If a
1990 * client creates an object asynchronously, it cannot destroy that object until
1991 * it received the method reply. It cannot know the name of the new object,
1992 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1994 * Therefore, many APIs allow the client to choose the unique name for newly
1995 * created objects. There're two problems to solve, though:
1996 * 1) Object names are usually defined via dbus object paths, which are
1997 * usually globally namespaced. Therefore, multiple clients must be able
1998 * to choose unique object names without interference.
1999 * 2) If multiple libraries share the same bus connection, they must be
2000 * able to choose unique object names without interference.
2001 * The first problem is solved easily by prefixing a name with the
2002 * unique-bus-name of a connection. The server side must enforce this and
2003 * reject any other name. The second problem is solved by providing unique
2004 * suffixes from within sd-bus.
2006 * This helper allows clients to create unique object-paths. It uses the
2007 * template '/prefix/sender_id/external_id' and returns the new path in
2008 * @ret_path (must be freed by the caller).
2009 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
2010 * NULL, this function allocates a unique suffix via @b (by requesting a new
2011 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2014 * Returns: 0 on success, negative error code on failure.
2016 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
2017 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
2018 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
2021 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
2022 assert_return(object_path_is_valid(prefix
), -EINVAL
);
2023 assert_return(ret_path
, -EINVAL
);
2026 r
= sd_bus_get_unique_name(b
, &sender_id
);
2032 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
2033 external_id
= external_buf
;
2036 sender_label
= bus_label_escape(sender_id
);
2040 external_label
= bus_label_escape(external_id
);
2041 if (!external_label
)
2044 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2053 * bus_path_decode_unique() - decode unique object path
2054 * @path: object path to decode
2055 * @prefix: object path prefix
2056 * @ret_sender: output parameter for sender-id label
2057 * @ret_external: output parameter for external-id label
2059 * This does the reverse of bus_path_encode_unique() (see its description for
2060 * details). Both trailing labels, sender-id and external-id, are unescaped and
2061 * returned in the given output parameters (the caller must free them).
2063 * Note that this function returns 0 if the path does not match the template
2064 * (see bus_path_encode_unique()), 1 if it matched.
2066 * Returns: Negative error code on failure, 0 if the given object path does not
2067 * match the template (return parameters are set to NULL), 1 if it was
2068 * parsed successfully (return parameters contain allocated labels).
2070 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2072 char *sender
, *external
;
2074 assert(object_path_is_valid(path
));
2075 assert(object_path_is_valid(prefix
));
2077 assert(ret_external
);
2079 p
= object_path_startswith(path
, prefix
);
2082 *ret_external
= NULL
;
2089 *ret_external
= NULL
;
2093 sender
= bus_label_unescape_n(p
, q
- p
);
2094 external
= bus_label_unescape(q
+ 1);
2095 if (!sender
|| !external
) {
2101 *ret_sender
= sender
;
2102 *ret_external
= external
;
2106 bool is_kdbus_wanted(void) {
2107 _cleanup_free_
char *value
= NULL
;
2109 const bool configured
= true;
2111 const bool configured
= false;
2116 if (get_proc_cmdline_key("kdbus", NULL
) > 0)
2119 r
= get_proc_cmdline_key("kdbus=", &value
);
2123 return parse_boolean(value
) == 1;
2126 bool is_kdbus_available(void) {
2127 _cleanup_close_
int fd
= -1;
2128 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2130 if (!is_kdbus_wanted())
2133 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2137 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;