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_connect_system_systemd(sd_bus
**_bus
) {
578 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
584 return sd_bus_default_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_default_system(_bus
);
621 r
= bus_check_peercred(bus
);
631 int bus_connect_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_default_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_default_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_connect_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_connect_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_connect_user_systemd(bus
);
1263 r
= bus_connect_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",
1430 "SyslogLevelPrefix")) {
1432 r
= parse_boolean(eq
);
1434 log_error("Failed to parse boolean assignment %s.", assignment
);
1438 r
= sd_bus_message_append(m
, "v", "b", r
);
1440 } else if (streq(field
, "MemoryLimit")) {
1443 if (isempty(eq
) || streq(eq
, "infinity"))
1444 bytes
= (uint64_t) -1;
1446 r
= parse_size(eq
, 1024, &bytes
);
1448 log_error("Failed to parse bytes specification %s", assignment
);
1453 r
= sd_bus_message_append(m
, "v", "t", bytes
);
1455 } else if (streq(field
, "TasksMax")) {
1458 if (isempty(eq
) || streq(eq
, "infinity"))
1461 r
= safe_atou64(eq
, &n
);
1463 log_error("Failed to parse maximum tasks specification %s", assignment
);
1468 r
= sd_bus_message_append(m
, "v", "t", n
);
1470 } else if (STR_IN_SET(field
, "CPUShares", "StartupCPUShares")) {
1473 r
= cg_cpu_shares_parse(eq
, &u
);
1475 log_error("Failed to parse %s value %s.", field
, eq
);
1479 r
= sd_bus_message_append(m
, "v", "t", u
);
1481 } else if (STR_IN_SET(field
, "BlockIOWeight", "StartupBlockIOWeight")) {
1484 r
= cg_cpu_shares_parse(eq
, &u
);
1486 log_error("Failed to parse %s value %s.", field
, eq
);
1490 r
= sd_bus_message_append(m
, "v", "t", u
);
1492 } else if (STR_IN_SET(field
,
1493 "User", "Group", "DevicePolicy", "KillMode",
1494 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1495 "StandardInput", "StandardOutput", "StandardError",
1496 "Description", "Slice", "Type", "WorkingDirectory",
1497 "RootDirectory", "SyslogIdentifier"))
1498 r
= sd_bus_message_append(m
, "v", "s", eq
);
1500 else if (streq(field
, "SyslogLevel")) {
1503 level
= log_level_from_string(eq
);
1505 log_error("Failed to parse %s value %s.", field
, eq
);
1509 r
= sd_bus_message_append(m
, "v", "i", level
);
1511 } else if (streq(field
, "SyslogFacility")) {
1514 facility
= log_facility_unshifted_from_string(eq
);
1516 log_error("Failed to parse %s value %s.", field
, eq
);
1520 r
= sd_bus_message_append(m
, "v", "i", facility
);
1522 } else if (streq(field
, "DeviceAllow")) {
1525 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1527 const char *path
, *rwm
, *e
;
1529 e
= strchr(eq
, ' ');
1531 path
= strndupa(eq
, e
- eq
);
1538 if (!path_startswith(path
, "/dev")) {
1539 log_error("%s is not a device file in /dev.", path
);
1543 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1546 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1549 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1551 const char *path
, *bandwidth
, *e
;
1554 e
= strchr(eq
, ' ');
1556 path
= strndupa(eq
, e
- eq
);
1559 log_error("Failed to parse %s value %s.", field
, eq
);
1563 if (!path_startswith(path
, "/dev")) {
1564 log_error("%s is not a device file in /dev.", path
);
1568 r
= parse_size(bandwidth
, 1000, &bytes
);
1570 log_error("Failed to parse byte value %s.", bandwidth
);
1574 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, bytes
);
1577 } else if (streq(field
, "BlockIODeviceWeight")) {
1580 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1582 const char *path
, *weight
, *e
;
1585 e
= strchr(eq
, ' ');
1587 path
= strndupa(eq
, e
- eq
);
1590 log_error("Failed to parse %s value %s.", field
, eq
);
1594 if (!path_startswith(path
, "/dev")) {
1595 log_error("%s is not a device file in /dev.", path
);
1599 r
= safe_atou64(weight
, &u
);
1601 log_error("Failed to parse %s value %s.", field
, weight
);
1604 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1607 } else if (rlimit_from_string(field
) >= 0) {
1610 if (streq(eq
, "infinity"))
1613 r
= safe_atou64(eq
, &rl
);
1615 log_error("Invalid resource limit: %s", eq
);
1620 r
= sd_bus_message_append(m
, "v", "t", rl
);
1622 } else if (streq(field
, "Nice")) {
1625 r
= safe_atoi32(eq
, &i
);
1627 log_error("Failed to parse %s value %s.", field
, eq
);
1631 r
= sd_bus_message_append(m
, "v", "i", i
);
1633 } else if (streq(field
, "Environment")) {
1635 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1637 } else if (streq(field
, "KillSignal")) {
1640 sig
= signal_from_string_try_harder(eq
);
1642 log_error("Failed to parse %s value %s.", field
, eq
);
1646 r
= sd_bus_message_append(m
, "v", "i", sig
);
1648 } else if (streq(field
, "AccuracySec")) {
1651 r
= parse_sec(eq
, &u
);
1653 log_error("Failed to parse %s value %s", field
, eq
);
1657 r
= sd_bus_message_append(m
, "v", "t", u
);
1658 } else if (streq(field
, "TimerSlackNSec")) {
1661 r
= parse_nsec(eq
, &n
);
1663 log_error("Failed to parse %s value %s", field
, eq
);
1667 r
= sd_bus_message_append(m
, "v", "t", n
);
1668 } else if (streq(field
, "OOMScoreAdjust")) {
1671 r
= safe_atoi(eq
, &oa
);
1673 log_error("Failed to parse %s value %s", field
, eq
);
1677 if (!oom_score_adjust_is_valid(oa
)) {
1678 log_error("OOM score adjust value out of range");
1682 r
= sd_bus_message_append(m
, "v", "i", oa
);
1684 log_error("Unknown assignment %s.", assignment
);
1689 return bus_log_create_error(r
);
1694 typedef struct BusWaitForJobs
{
1701 sd_bus_slot
*slot_job_removed
;
1702 sd_bus_slot
*slot_disconnected
;
1705 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1708 log_error("Warning! D-Bus connection terminated.");
1709 sd_bus_close(sd_bus_message_get_bus(m
));
1714 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1715 const char *path
, *unit
, *result
;
1716 BusWaitForJobs
*d
= userdata
;
1724 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1726 bus_log_parse_error(r
);
1730 found
= set_remove(d
->jobs
, (char*) path
);
1736 if (!isempty(result
))
1737 d
->result
= strdup(result
);
1740 d
->name
= strdup(unit
);
1745 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1749 set_free_free(d
->jobs
);
1751 sd_bus_slot_unref(d
->slot_disconnected
);
1752 sd_bus_slot_unref(d
->slot_job_removed
);
1754 sd_bus_unref(d
->bus
);
1762 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1763 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1769 d
= new0(BusWaitForJobs
, 1);
1773 d
->bus
= sd_bus_ref(bus
);
1775 /* When we are a bus client we match by sender. Direct
1776 * connections OTOH have no initialized sender field, and
1777 * hence we ignore the sender then */
1778 r
= sd_bus_add_match(
1780 &d
->slot_job_removed
,
1783 "sender='org.freedesktop.systemd1',"
1784 "interface='org.freedesktop.systemd1.Manager',"
1785 "member='JobRemoved',"
1786 "path='/org/freedesktop/systemd1'" :
1788 "interface='org.freedesktop.systemd1.Manager',"
1789 "member='JobRemoved',"
1790 "path='/org/freedesktop/systemd1'",
1791 match_job_removed
, d
);
1795 r
= sd_bus_add_match(
1797 &d
->slot_disconnected
,
1799 "sender='org.freedesktop.DBus.Local',"
1800 "interface='org.freedesktop.DBus.Local',"
1801 "member='Disconnected'",
1802 match_disconnected
, d
);
1812 static int bus_process_wait(sd_bus
*bus
) {
1816 r
= sd_bus_process(bus
, NULL
);
1822 r
= sd_bus_wait(bus
, (uint64_t) -1);
1828 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1829 _cleanup_free_
char *dbus_path
= NULL
;
1835 dbus_path
= unit_dbus_path_from_name(d
->name
);
1839 return sd_bus_get_property_string(d
->bus
,
1840 "org.freedesktop.systemd1",
1842 "org.freedesktop.systemd1.Service",
1848 static const struct {
1849 const char *result
, *explanation
;
1850 } explanations
[] = {
1851 { "resources", "a configured resource limit was exceeded" },
1852 { "timeout", "a timeout was exceeded" },
1853 { "exit-code", "the control process exited with error code" },
1854 { "signal", "a fatal signal was delivered to the control process" },
1855 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1856 { "watchdog", "the service failed to send watchdog ping" },
1857 { "start-limit", "start of the service was attempted too often" }
1860 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1861 _cleanup_free_
char *service_shell_quoted
= NULL
;
1865 service_shell_quoted
= shell_maybe_quote(service
);
1867 if (!isempty(result
)) {
1870 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1871 if (streq(result
, explanations
[i
].result
))
1874 if (i
< ELEMENTSOF(explanations
)) {
1875 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1877 explanations
[i
].explanation
,
1878 strna(service_shell_quoted
));
1884 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1886 strna(service_shell_quoted
));
1889 /* For some results maybe additional explanation is required */
1890 if (streq_ptr(result
, "start-limit"))
1891 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1892 strna(service_shell_quoted
));
1895 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1901 if (streq(d
->result
, "canceled"))
1902 log_error("Job for %s canceled.", strna(d
->name
));
1903 else if (streq(d
->result
, "timeout"))
1904 log_error("Job for %s timed out.", strna(d
->name
));
1905 else if (streq(d
->result
, "dependency"))
1906 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1907 else if (streq(d
->result
, "invalid"))
1908 log_error("Job for %s invalid.", strna(d
->name
));
1909 else if (streq(d
->result
, "assert"))
1910 log_error("Assertion failed on job for %s.", strna(d
->name
));
1911 else if (streq(d
->result
, "unsupported"))
1912 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1913 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1916 _cleanup_free_
char *result
= NULL
;
1918 q
= bus_job_get_service_result(d
, &result
);
1920 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1922 log_job_error_with_service_result(d
->name
, result
);
1924 log_error("Job failed. See \"journalctl -xe\" for details.");
1928 if (streq(d
->result
, "canceled"))
1930 else if (streq(d
->result
, "timeout"))
1932 else if (streq(d
->result
, "dependency"))
1934 else if (streq(d
->result
, "invalid"))
1936 else if (streq(d
->result
, "assert"))
1938 else if (streq(d
->result
, "unsupported"))
1940 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1946 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1951 while (!set_isempty(d
->jobs
)) {
1954 q
= bus_process_wait(d
->bus
);
1956 return log_error_errno(q
, "Failed to wait for response: %m");
1959 q
= check_wait_response(d
, quiet
);
1960 /* Return the first error as it is most likely to be
1962 if (q
< 0 && r
== 0)
1965 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1968 d
->name
= mfree(d
->name
);
1969 d
->result
= mfree(d
->result
);
1975 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1980 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1984 return set_put_strdup(d
->jobs
, path
);
1987 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1990 r
= bus_wait_for_jobs_add(d
, path
);
1994 return bus_wait_for_jobs(d
, quiet
);
1997 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1998 const char *type
, *path
, *source
;
2001 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
2003 return bus_log_parse_error(r
);
2005 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
2007 if (streq(type
, "symlink"))
2008 log_info("Created symlink from %s to %s.", path
, source
);
2010 log_info("Removed symlink %s.", path
);
2013 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
2018 return bus_log_parse_error(r
);
2020 r
= sd_bus_message_exit_container(m
);
2022 return bus_log_parse_error(r
);
2028 * bus_path_encode_unique() - encode unique object path
2029 * @b: bus connection or NULL
2030 * @prefix: object path prefix
2031 * @sender_id: unique-name of client, or NULL
2032 * @external_id: external ID to be chosen by client, or NULL
2033 * @ret_path: storage for encoded object path pointer
2035 * Whenever we provide a bus API that allows clients to create and manage
2036 * server-side objects, we need to provide a unique name for these objects. If
2037 * we let the server choose the name, we suffer from a race condition: If a
2038 * client creates an object asynchronously, it cannot destroy that object until
2039 * it received the method reply. It cannot know the name of the new object,
2040 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
2042 * Therefore, many APIs allow the client to choose the unique name for newly
2043 * created objects. There're two problems to solve, though:
2044 * 1) Object names are usually defined via dbus object paths, which are
2045 * usually globally namespaced. Therefore, multiple clients must be able
2046 * to choose unique object names without interference.
2047 * 2) If multiple libraries share the same bus connection, they must be
2048 * able to choose unique object names without interference.
2049 * The first problem is solved easily by prefixing a name with the
2050 * unique-bus-name of a connection. The server side must enforce this and
2051 * reject any other name. The second problem is solved by providing unique
2052 * suffixes from within sd-bus.
2054 * This helper allows clients to create unique object-paths. It uses the
2055 * template '/prefix/sender_id/external_id' and returns the new path in
2056 * @ret_path (must be freed by the caller).
2057 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
2058 * NULL, this function allocates a unique suffix via @b (by requesting a new
2059 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2062 * Returns: 0 on success, negative error code on failure.
2064 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
2065 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
2066 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
2069 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
2070 assert_return(object_path_is_valid(prefix
), -EINVAL
);
2071 assert_return(ret_path
, -EINVAL
);
2074 r
= sd_bus_get_unique_name(b
, &sender_id
);
2080 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
2081 external_id
= external_buf
;
2084 sender_label
= bus_label_escape(sender_id
);
2088 external_label
= bus_label_escape(external_id
);
2089 if (!external_label
)
2092 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2101 * bus_path_decode_unique() - decode unique object path
2102 * @path: object path to decode
2103 * @prefix: object path prefix
2104 * @ret_sender: output parameter for sender-id label
2105 * @ret_external: output parameter for external-id label
2107 * This does the reverse of bus_path_encode_unique() (see its description for
2108 * details). Both trailing labels, sender-id and external-id, are unescaped and
2109 * returned in the given output parameters (the caller must free them).
2111 * Note that this function returns 0 if the path does not match the template
2112 * (see bus_path_encode_unique()), 1 if it matched.
2114 * Returns: Negative error code on failure, 0 if the given object path does not
2115 * match the template (return parameters are set to NULL), 1 if it was
2116 * parsed successfully (return parameters contain allocated labels).
2118 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2120 char *sender
, *external
;
2122 assert(object_path_is_valid(path
));
2123 assert(object_path_is_valid(prefix
));
2125 assert(ret_external
);
2127 p
= object_path_startswith(path
, prefix
);
2130 *ret_external
= NULL
;
2137 *ret_external
= NULL
;
2141 sender
= bus_label_unescape_n(p
, q
- p
);
2142 external
= bus_label_unescape(q
+ 1);
2143 if (!sender
|| !external
) {
2149 *ret_sender
= sender
;
2150 *ret_external
= external
;
2154 bool is_kdbus_wanted(void) {
2155 _cleanup_free_
char *value
= NULL
;
2157 const bool configured
= true;
2159 const bool configured
= false;
2164 if (get_proc_cmdline_key("kdbus", NULL
) > 0)
2167 r
= get_proc_cmdline_key("kdbus=", &value
);
2171 return parse_boolean(value
) == 1;
2174 bool is_kdbus_available(void) {
2175 _cleanup_close_
int fd
= -1;
2176 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2178 if (!is_kdbus_wanted())
2181 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2185 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;
2188 int bus_property_get_rlimit(
2191 const char *interface
,
2192 const char *property
,
2193 sd_bus_message
*reply
,
2195 sd_bus_error
*error
) {
2205 rl
= *(struct rlimit
**) userdata
;
2209 struct rlimit buf
= {};
2212 z
= rlimit_from_string(strstr(property
, "Limit"));
2219 /* rlim_t might have different sizes, let's map
2220 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
2222 u
= x
== RLIM_INFINITY
? (uint64_t) -1 : (uint64_t) x
;
2224 return sd_bus_message_append(reply
, "t", u
);