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", "WorkingDirectory",
1497 r
= sd_bus_message_append(m
, "v", "s", eq
);
1499 else if (streq(field
, "DeviceAllow")) {
1502 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1504 const char *path
, *rwm
, *e
;
1506 e
= strchr(eq
, ' ');
1508 path
= strndupa(eq
, e
- eq
);
1515 if (!path_startswith(path
, "/dev")) {
1516 log_error("%s is not a device file in /dev.", path
);
1520 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1523 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1526 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1528 const char *path
, *bandwidth
, *e
;
1531 e
= strchr(eq
, ' ');
1533 path
= strndupa(eq
, e
- eq
);
1536 log_error("Failed to parse %s value %s.", field
, eq
);
1540 if (!path_startswith(path
, "/dev")) {
1541 log_error("%s is not a device file in /dev.", path
);
1545 r
= parse_size(bandwidth
, 1000, &bytes
);
1547 log_error("Failed to parse byte value %s.", bandwidth
);
1551 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, bytes
);
1554 } else if (streq(field
, "BlockIODeviceWeight")) {
1557 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1559 const char *path
, *weight
, *e
;
1562 e
= strchr(eq
, ' ');
1564 path
= strndupa(eq
, e
- eq
);
1567 log_error("Failed to parse %s value %s.", field
, eq
);
1571 if (!path_startswith(path
, "/dev")) {
1572 log_error("%s is not a device file in /dev.", path
);
1576 r
= safe_atou64(weight
, &u
);
1578 log_error("Failed to parse %s value %s.", field
, weight
);
1581 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1584 } else if (rlimit_from_string(field
) >= 0) {
1587 if (streq(eq
, "infinity"))
1590 r
= safe_atou64(eq
, &rl
);
1592 log_error("Invalid resource limit: %s", eq
);
1597 r
= sd_bus_message_append(m
, "v", "t", rl
);
1599 } else if (streq(field
, "Nice")) {
1602 r
= safe_atoi32(eq
, &i
);
1604 log_error("Failed to parse %s value %s.", field
, eq
);
1608 r
= sd_bus_message_append(m
, "v", "i", i
);
1610 } else if (streq(field
, "Environment")) {
1612 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1614 } else if (streq(field
, "KillSignal")) {
1617 sig
= signal_from_string_try_harder(eq
);
1619 log_error("Failed to parse %s value %s.", field
, eq
);
1623 r
= sd_bus_message_append(m
, "v", "i", sig
);
1625 } else if (streq(field
, "AccuracySec")) {
1628 r
= parse_sec(eq
, &u
);
1630 log_error("Failed to parse %s value %s", field
, eq
);
1634 r
= sd_bus_message_append(m
, "v", "t", u
);
1637 log_error("Unknown assignment %s.", assignment
);
1642 return bus_log_create_error(r
);
1647 typedef struct BusWaitForJobs
{
1654 sd_bus_slot
*slot_job_removed
;
1655 sd_bus_slot
*slot_disconnected
;
1658 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1661 log_error("Warning! D-Bus connection terminated.");
1662 sd_bus_close(sd_bus_message_get_bus(m
));
1667 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1668 const char *path
, *unit
, *result
;
1669 BusWaitForJobs
*d
= userdata
;
1677 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1679 bus_log_parse_error(r
);
1683 found
= set_remove(d
->jobs
, (char*) path
);
1689 if (!isempty(result
))
1690 d
->result
= strdup(result
);
1693 d
->name
= strdup(unit
);
1698 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1702 set_free_free(d
->jobs
);
1704 sd_bus_slot_unref(d
->slot_disconnected
);
1705 sd_bus_slot_unref(d
->slot_job_removed
);
1707 sd_bus_unref(d
->bus
);
1715 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1716 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1722 d
= new0(BusWaitForJobs
, 1);
1726 d
->bus
= sd_bus_ref(bus
);
1728 /* When we are a bus client we match by sender. Direct
1729 * connections OTOH have no initialized sender field, and
1730 * hence we ignore the sender then */
1731 r
= sd_bus_add_match(
1733 &d
->slot_job_removed
,
1736 "sender='org.freedesktop.systemd1',"
1737 "interface='org.freedesktop.systemd1.Manager',"
1738 "member='JobRemoved',"
1739 "path='/org/freedesktop/systemd1'" :
1741 "interface='org.freedesktop.systemd1.Manager',"
1742 "member='JobRemoved',"
1743 "path='/org/freedesktop/systemd1'",
1744 match_job_removed
, d
);
1748 r
= sd_bus_add_match(
1750 &d
->slot_disconnected
,
1752 "sender='org.freedesktop.DBus.Local',"
1753 "interface='org.freedesktop.DBus.Local',"
1754 "member='Disconnected'",
1755 match_disconnected
, d
);
1765 static int bus_process_wait(sd_bus
*bus
) {
1769 r
= sd_bus_process(bus
, NULL
);
1775 r
= sd_bus_wait(bus
, (uint64_t) -1);
1781 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1782 _cleanup_free_
char *dbus_path
= NULL
;
1788 dbus_path
= unit_dbus_path_from_name(d
->name
);
1792 return sd_bus_get_property_string(d
->bus
,
1793 "org.freedesktop.systemd1",
1795 "org.freedesktop.systemd1.Service",
1801 static const struct {
1802 const char *result
, *explanation
;
1803 } explanations
[] = {
1804 { "resources", "a configured resource limit was exceeded" },
1805 { "timeout", "a timeout was exceeded" },
1806 { "exit-code", "the control process exited with error code" },
1807 { "signal", "a fatal signal was delivered to the control process" },
1808 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1809 { "watchdog", "the service failed to send watchdog ping" },
1810 { "start-limit", "start of the service was attempted too often" }
1813 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1814 _cleanup_free_
char *service_shell_quoted
= NULL
;
1818 service_shell_quoted
= shell_maybe_quote(service
);
1820 if (!isempty(result
)) {
1823 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1824 if (streq(result
, explanations
[i
].result
))
1827 if (i
< ELEMENTSOF(explanations
)) {
1828 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1830 explanations
[i
].explanation
,
1831 strna(service_shell_quoted
));
1837 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1839 strna(service_shell_quoted
));
1842 /* For some results maybe additional explanation is required */
1843 if (streq_ptr(result
, "start-limit"))
1844 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1845 strna(service_shell_quoted
));
1848 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1854 if (streq(d
->result
, "canceled"))
1855 log_error("Job for %s canceled.", strna(d
->name
));
1856 else if (streq(d
->result
, "timeout"))
1857 log_error("Job for %s timed out.", strna(d
->name
));
1858 else if (streq(d
->result
, "dependency"))
1859 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1860 else if (streq(d
->result
, "invalid"))
1861 log_error("Job for %s invalid.", strna(d
->name
));
1862 else if (streq(d
->result
, "assert"))
1863 log_error("Assertion failed on job for %s.", strna(d
->name
));
1864 else if (streq(d
->result
, "unsupported"))
1865 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1866 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1869 _cleanup_free_
char *result
= NULL
;
1871 q
= bus_job_get_service_result(d
, &result
);
1873 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1875 log_job_error_with_service_result(d
->name
, result
);
1877 log_error("Job failed. See \"journalctl -xe\" for details.");
1881 if (streq(d
->result
, "canceled"))
1883 else if (streq(d
->result
, "timeout"))
1885 else if (streq(d
->result
, "dependency"))
1887 else if (streq(d
->result
, "invalid"))
1889 else if (streq(d
->result
, "assert"))
1891 else if (streq(d
->result
, "unsupported"))
1893 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1899 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1904 while (!set_isempty(d
->jobs
)) {
1907 q
= bus_process_wait(d
->bus
);
1909 return log_error_errno(q
, "Failed to wait for response: %m");
1912 q
= check_wait_response(d
, quiet
);
1913 /* Return the first error as it is most likely to be
1915 if (q
< 0 && r
== 0)
1918 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1921 d
->name
= mfree(d
->name
);
1922 d
->result
= mfree(d
->result
);
1928 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1933 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1937 return set_put_strdup(d
->jobs
, path
);
1940 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1943 r
= bus_wait_for_jobs_add(d
, path
);
1947 return bus_wait_for_jobs(d
, quiet
);
1950 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1951 const char *type
, *path
, *source
;
1954 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1956 return bus_log_parse_error(r
);
1958 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1960 if (streq(type
, "symlink"))
1961 log_info("Created symlink from %s to %s.", path
, source
);
1963 log_info("Removed symlink %s.", path
);
1966 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
1971 return bus_log_parse_error(r
);
1973 r
= sd_bus_message_exit_container(m
);
1975 return bus_log_parse_error(r
);
1981 * bus_path_encode_unique() - encode unique object path
1982 * @b: bus connection or NULL
1983 * @prefix: object path prefix
1984 * @sender_id: unique-name of client, or NULL
1985 * @external_id: external ID to be chosen by client, or NULL
1986 * @ret_path: storage for encoded object path pointer
1988 * Whenever we provide a bus API that allows clients to create and manage
1989 * server-side objects, we need to provide a unique name for these objects. If
1990 * we let the server choose the name, we suffer from a race condition: If a
1991 * client creates an object asynchronously, it cannot destroy that object until
1992 * it received the method reply. It cannot know the name of the new object,
1993 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1995 * Therefore, many APIs allow the client to choose the unique name for newly
1996 * created objects. There're two problems to solve, though:
1997 * 1) Object names are usually defined via dbus object paths, which are
1998 * usually globally namespaced. Therefore, multiple clients must be able
1999 * to choose unique object names without interference.
2000 * 2) If multiple libraries share the same bus connection, they must be
2001 * able to choose unique object names without interference.
2002 * The first problem is solved easily by prefixing a name with the
2003 * unique-bus-name of a connection. The server side must enforce this and
2004 * reject any other name. The second problem is solved by providing unique
2005 * suffixes from within sd-bus.
2007 * This helper allows clients to create unique object-paths. It uses the
2008 * template '/prefix/sender_id/external_id' and returns the new path in
2009 * @ret_path (must be freed by the caller).
2010 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
2011 * NULL, this function allocates a unique suffix via @b (by requesting a new
2012 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2015 * Returns: 0 on success, negative error code on failure.
2017 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
2018 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
2019 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
2022 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
2023 assert_return(object_path_is_valid(prefix
), -EINVAL
);
2024 assert_return(ret_path
, -EINVAL
);
2027 r
= sd_bus_get_unique_name(b
, &sender_id
);
2033 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
2034 external_id
= external_buf
;
2037 sender_label
= bus_label_escape(sender_id
);
2041 external_label
= bus_label_escape(external_id
);
2042 if (!external_label
)
2045 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2054 * bus_path_decode_unique() - decode unique object path
2055 * @path: object path to decode
2056 * @prefix: object path prefix
2057 * @ret_sender: output parameter for sender-id label
2058 * @ret_external: output parameter for external-id label
2060 * This does the reverse of bus_path_encode_unique() (see its description for
2061 * details). Both trailing labels, sender-id and external-id, are unescaped and
2062 * returned in the given output parameters (the caller must free them).
2064 * Note that this function returns 0 if the path does not match the template
2065 * (see bus_path_encode_unique()), 1 if it matched.
2067 * Returns: Negative error code on failure, 0 if the given object path does not
2068 * match the template (return parameters are set to NULL), 1 if it was
2069 * parsed successfully (return parameters contain allocated labels).
2071 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2073 char *sender
, *external
;
2075 assert(object_path_is_valid(path
));
2076 assert(object_path_is_valid(prefix
));
2078 assert(ret_external
);
2080 p
= object_path_startswith(path
, prefix
);
2083 *ret_external
= NULL
;
2090 *ret_external
= NULL
;
2094 sender
= bus_label_unescape_n(p
, q
- p
);
2095 external
= bus_label_unescape(q
+ 1);
2096 if (!sender
|| !external
) {
2102 *ret_sender
= sender
;
2103 *ret_external
= external
;
2107 bool is_kdbus_wanted(void) {
2108 _cleanup_free_
char *value
= NULL
;
2110 const bool configured
= true;
2112 const bool configured
= false;
2117 if (get_proc_cmdline_key("kdbus", NULL
) > 0)
2120 r
= get_proc_cmdline_key("kdbus=", &value
);
2124 return parse_boolean(value
) == 1;
2127 bool is_kdbus_available(void) {
2128 _cleanup_close_
int fd
= -1;
2129 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2131 if (!is_kdbus_wanted())
2134 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2138 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;