1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/socket.h>
24 #include "sd-daemon.h"
30 #include "path-util.h"
33 #include "signal-util.h"
34 #include "unit-name.h"
37 #include "bus-error.h"
38 #include "bus-label.h"
39 #include "bus-message.h"
41 #include "bus-internal.h"
43 static int name_owner_change_callback(sd_bus_message
*m
, void *userdata
, sd_bus_error
*ret_error
) {
44 sd_event
*e
= userdata
;
49 sd_bus_close(sd_bus_message_get_bus(m
));
55 int bus_async_unregister_and_exit(sd_event
*e
, sd_bus
*bus
, const char *name
) {
56 _cleanup_free_
char *match
= NULL
;
64 /* We unregister the name here and then wait for the
65 * NameOwnerChanged signal for this event to arrive before we
66 * quit. We do this in order to make sure that any queued
67 * requests are still processed before we really exit. */
69 r
= sd_bus_get_unique_name(bus
, &unique
);
74 "sender='org.freedesktop.DBus',"
76 "interface='org.freedesktop.DBus',"
77 "member='NameOwnerChanged',"
78 "path='/org/freedesktop/DBus',"
81 "arg2=''", name
, unique
);
85 r
= sd_bus_add_match(bus
, NULL
, match
, name_owner_change_callback
, e
);
89 r
= sd_bus_release_name(bus
, name
);
96 int bus_event_loop_with_idle(
101 check_idle_t check_idle
,
103 bool exiting
= false;
113 r
= sd_event_get_state(e
);
116 if (r
== SD_EVENT_FINISHED
)
120 idle
= check_idle(userdata
);
124 r
= sd_event_run(e
, exiting
|| !idle
? (uint64_t) -1 : timeout
);
128 if (r
== 0 && !exiting
&& idle
) {
130 r
= sd_bus_try_close(bus
);
134 /* Fallback for dbus1 connections: we
135 * unregister the name and wait for the
136 * response to come through for it */
137 if (r
== -EOPNOTSUPP
) {
139 /* Inform the service manager that we
140 * are going down, so that it will
141 * queue all further start requests,
142 * instead of assuming we are already
144 sd_notify(false, "STOPPING=1");
146 r
= bus_async_unregister_and_exit(e
, bus
, name
);
162 r
= sd_event_get_exit_code(e
, &code
);
169 int bus_name_has_owner(sd_bus
*c
, const char *name
, sd_bus_error
*error
) {
170 _cleanup_bus_message_unref_ sd_bus_message
*rep
= NULL
;
171 int r
, has_owner
= 0;
176 r
= sd_bus_call_method(c
,
177 "org.freedesktop.DBus",
178 "/org/freedesktop/dbus",
179 "org.freedesktop.DBus",
188 r
= sd_bus_message_read_basic(rep
, 'b', &has_owner
);
190 return sd_bus_error_set_errno(error
, r
);
195 static int check_good_user(sd_bus_message
*m
, uid_t good_user
) {
196 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
202 if (good_user
== UID_INVALID
)
205 r
= sd_bus_query_sender_creds(m
, SD_BUS_CREDS_EUID
, &creds
);
209 /* Don't trust augmented credentials for authorization */
210 assert_return((sd_bus_creds_get_augmented_mask(creds
) & SD_BUS_CREDS_EUID
) == 0, -EPERM
);
212 r
= sd_bus_creds_get_euid(creds
, &sender_uid
);
216 return sender_uid
== good_user
;
220 sd_bus_message
*call
,
223 const char **details
,
233 /* Tests non-interactively! */
235 r
= check_good_user(call
, good_user
);
239 r
= sd_bus_query_sender_privilege(call
, capability
);
246 _cleanup_bus_message_unref_ sd_bus_message
*request
= NULL
;
247 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
248 int authorized
= false, challenge
= false;
249 const char *sender
, **k
, **v
;
251 sender
= sd_bus_message_get_sender(call
);
255 r
= sd_bus_message_new_method_call(
258 "org.freedesktop.PolicyKit1",
259 "/org/freedesktop/PolicyKit1/Authority",
260 "org.freedesktop.PolicyKit1.Authority",
261 "CheckAuthorization");
265 r
= sd_bus_message_append(
268 "system-bus-name", 1, "name", "s", sender
,
273 r
= sd_bus_message_open_container(request
, 'a', "{ss}");
277 STRV_FOREACH_PAIR(k
, v
, details
) {
278 r
= sd_bus_message_append(request
, "{ss}", *k
, *v
);
283 r
= sd_bus_message_close_container(request
);
287 r
= sd_bus_message_append(request
, "us", 0, NULL
);
291 r
= sd_bus_call(call
->bus
, request
, 0, e
, &reply
);
293 /* Treat no PK available as access denied */
294 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
)) {
295 sd_bus_error_free(e
);
302 r
= sd_bus_message_enter_container(reply
, 'r', "bba{ss}");
306 r
= sd_bus_message_read(reply
, "bb", &authorized
, &challenge
);
314 *_challenge
= challenge
;
325 typedef struct AsyncPolkitQuery
{
326 sd_bus_message
*request
, *reply
;
327 sd_bus_message_handler_t callback
;
333 static void async_polkit_query_free(AsyncPolkitQuery
*q
) {
338 sd_bus_slot_unref(q
->slot
);
340 if (q
->registry
&& q
->request
)
341 hashmap_remove(q
->registry
, q
->request
);
343 sd_bus_message_unref(q
->request
);
344 sd_bus_message_unref(q
->reply
);
349 static int async_polkit_callback(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
350 _cleanup_bus_error_free_ sd_bus_error error_buffer
= SD_BUS_ERROR_NULL
;
351 AsyncPolkitQuery
*q
= userdata
;
357 q
->slot
= sd_bus_slot_unref(q
->slot
);
358 q
->reply
= sd_bus_message_ref(reply
);
360 r
= sd_bus_message_rewind(q
->request
, true);
362 r
= sd_bus_reply_method_errno(q
->request
, r
, NULL
);
366 r
= q
->callback(q
->request
, q
->userdata
, &error_buffer
);
367 r
= bus_maybe_reply_error(q
->request
, r
, &error_buffer
);
370 async_polkit_query_free(q
);
377 int bus_verify_polkit_async(
378 sd_bus_message
*call
,
381 const char **details
,
385 sd_bus_error
*error
) {
388 _cleanup_bus_message_unref_ sd_bus_message
*pk
= NULL
;
390 const char *sender
, **k
, **v
;
391 sd_bus_message_handler_t callback
;
401 r
= check_good_user(call
, good_user
);
406 q
= hashmap_get(*registry
, call
);
408 int authorized
, challenge
;
410 /* This is the second invocation of this function, and
411 * there's already a response from polkit, let's
415 if (sd_bus_message_is_method_error(q
->reply
, NULL
)) {
416 const sd_bus_error
*e
;
418 /* Copy error from polkit reply */
419 e
= sd_bus_message_get_error(q
->reply
);
420 sd_bus_error_copy(error
, e
);
422 /* Treat no PK available as access denied */
423 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
))
426 return -sd_bus_error_get_errno(e
);
429 r
= sd_bus_message_enter_container(q
->reply
, 'r', "bba{ss}");
431 r
= sd_bus_message_read(q
->reply
, "bb", &authorized
, &challenge
);
440 return sd_bus_error_set(error
, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED
, "Interactive authentication required.");
446 r
= sd_bus_query_sender_privilege(call
, capability
);
453 if (sd_bus_get_current_message(call
->bus
) != call
)
456 callback
= sd_bus_get_current_handler(call
->bus
);
460 userdata
= sd_bus_get_current_userdata(call
->bus
);
462 sender
= sd_bus_message_get_sender(call
);
466 c
= sd_bus_message_get_allow_interactive_authorization(call
);
472 r
= hashmap_ensure_allocated(registry
, NULL
);
476 r
= sd_bus_message_new_method_call(
479 "org.freedesktop.PolicyKit1",
480 "/org/freedesktop/PolicyKit1/Authority",
481 "org.freedesktop.PolicyKit1.Authority",
482 "CheckAuthorization");
486 r
= sd_bus_message_append(
489 "system-bus-name", 1, "name", "s", sender
,
494 r
= sd_bus_message_open_container(pk
, 'a', "{ss}");
498 STRV_FOREACH_PAIR(k
, v
, details
) {
499 r
= sd_bus_message_append(pk
, "{ss}", *k
, *v
);
504 r
= sd_bus_message_close_container(pk
);
508 r
= sd_bus_message_append(pk
, "us", !!interactive
, NULL
);
512 q
= new0(AsyncPolkitQuery
, 1);
516 q
->request
= sd_bus_message_ref(call
);
517 q
->callback
= callback
;
518 q
->userdata
= userdata
;
520 r
= hashmap_put(*registry
, call
, q
);
522 async_polkit_query_free(q
);
526 q
->registry
= *registry
;
528 r
= sd_bus_call_async(call
->bus
, &q
->slot
, pk
, async_polkit_callback
, q
, 0);
530 async_polkit_query_free(q
);
540 void bus_verify_polkit_async_registry_free(Hashmap
*registry
) {
544 while ((q
= hashmap_steal_first(registry
)))
545 async_polkit_query_free(q
);
547 hashmap_free(registry
);
551 int bus_check_peercred(sd_bus
*c
) {
558 fd
= sd_bus_get_fd(c
);
562 l
= sizeof(struct ucred
);
563 if (getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &ucred
, &l
) < 0)
566 if (l
!= sizeof(struct ucred
))
569 if (ucred
.uid
!= 0 && ucred
.uid
!= geteuid())
575 int bus_open_system_systemd(sd_bus
**_bus
) {
576 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
582 return sd_bus_open_system(_bus
);
584 /* If we are root and kdbus is not available, then let's talk
585 * directly to the system instance, instead of going via the
588 r
= sd_bus_new(&bus
);
592 r
= sd_bus_set_address(bus
, KERNEL_SYSTEM_BUS_ADDRESS
);
596 bus
->bus_client
= true;
598 r
= sd_bus_start(bus
);
605 bus
= sd_bus_unref(bus
);
607 r
= sd_bus_new(&bus
);
611 r
= sd_bus_set_address(bus
, "unix:path=/run/systemd/private");
615 r
= sd_bus_start(bus
);
617 return sd_bus_open_system(_bus
);
619 r
= bus_check_peercred(bus
);
629 int bus_open_user_systemd(sd_bus
**_bus
) {
630 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
631 _cleanup_free_
char *ee
= NULL
;
635 /* Try via kdbus first, and then directly */
639 r
= sd_bus_new(&bus
);
643 if (asprintf(&bus
->address
, KERNEL_USER_BUS_ADDRESS_FMT
, getuid()) < 0)
646 bus
->bus_client
= true;
648 r
= sd_bus_start(bus
);
655 bus
= sd_bus_unref(bus
);
657 e
= secure_getenv("XDG_RUNTIME_DIR");
659 return sd_bus_open_user(_bus
);
661 ee
= bus_address_escape(e
);
665 r
= sd_bus_new(&bus
);
669 bus
->address
= strjoin("unix:path=", ee
, "/systemd/private", NULL
);
673 r
= sd_bus_start(bus
);
675 return sd_bus_open_user(_bus
);
677 r
= bus_check_peercred(bus
);
687 int bus_print_property(const char *name
, sd_bus_message
*property
, bool all
) {
689 const char *contents
;
695 r
= sd_bus_message_peek_type(property
, &type
, &contents
);
701 case SD_BUS_TYPE_STRING
: {
704 r
= sd_bus_message_read_basic(property
, type
, &s
);
708 if (all
|| !isempty(s
)) {
709 _cleanup_free_
char *escaped
= NULL
;
711 escaped
= xescape(s
, "\n");
715 printf("%s=%s\n", name
, escaped
);
721 case SD_BUS_TYPE_BOOLEAN
: {
724 r
= sd_bus_message_read_basic(property
, type
, &b
);
728 printf("%s=%s\n", name
, yes_no(b
));
733 case SD_BUS_TYPE_UINT64
: {
736 r
= sd_bus_message_read_basic(property
, type
, &u
);
740 /* Yes, heuristics! But we can change this check
741 * should it turn out to not be sufficient */
743 if (endswith(name
, "Timestamp")) {
744 char timestamp
[FORMAT_TIMESTAMP_MAX
], *t
;
746 t
= format_timestamp(timestamp
, sizeof(timestamp
), u
);
748 printf("%s=%s\n", name
, strempty(t
));
750 } else if (strstr(name
, "USec")) {
751 char timespan
[FORMAT_TIMESPAN_MAX
];
753 printf("%s=%s\n", name
, format_timespan(timespan
, sizeof(timespan
), u
, 0));
755 printf("%s=%llu\n", name
, (unsigned long long) u
);
760 case SD_BUS_TYPE_INT64
: {
763 r
= sd_bus_message_read_basic(property
, type
, &i
);
767 printf("%s=%lld\n", name
, (long long) i
);
772 case SD_BUS_TYPE_UINT32
: {
775 r
= sd_bus_message_read_basic(property
, type
, &u
);
779 if (strstr(name
, "UMask") || strstr(name
, "Mode"))
780 printf("%s=%04o\n", name
, u
);
782 printf("%s=%u\n", name
, (unsigned) u
);
787 case SD_BUS_TYPE_INT32
: {
790 r
= sd_bus_message_read_basic(property
, type
, &i
);
794 printf("%s=%i\n", name
, (int) i
);
798 case SD_BUS_TYPE_DOUBLE
: {
801 r
= sd_bus_message_read_basic(property
, type
, &d
);
805 printf("%s=%g\n", name
, d
);
809 case SD_BUS_TYPE_ARRAY
:
810 if (streq(contents
, "s")) {
814 r
= sd_bus_message_enter_container(property
, SD_BUS_TYPE_ARRAY
, contents
);
818 while((r
= sd_bus_message_read_basic(property
, SD_BUS_TYPE_STRING
, &str
)) > 0) {
819 _cleanup_free_
char *escaped
= NULL
;
824 escaped
= xescape(str
, "\n ");
828 printf("%s%s", first
? "" : " ", escaped
);
840 r
= sd_bus_message_exit_container(property
);
846 } else if (streq(contents
, "y")) {
850 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_BYTE
, (const void**) &u
, &n
);
859 for (i
= 0; i
< n
; i
++)
860 printf("%02x", u
[i
]);
867 } else if (streq(contents
, "u")) {
871 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_UINT32
, (const void**) &u
, &n
);
880 for (i
= 0; i
< n
; i
++)
881 printf("%08x", u
[i
]);
895 int bus_print_all_properties(sd_bus
*bus
, const char *dest
, const char *path
, char **filter
, bool all
) {
896 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
897 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
903 r
= sd_bus_call_method(bus
,
906 "org.freedesktop.DBus.Properties",
914 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
918 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
920 const char *contents
;
922 r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &name
);
926 if (!filter
|| strv_find(filter
, name
)) {
927 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
931 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
935 r
= bus_print_property(name
, reply
, all
);
940 printf("%s=[unprintable]\n", name
);
941 /* skip what we didn't read */
942 r
= sd_bus_message_skip(reply
, contents
);
947 r
= sd_bus_message_exit_container(reply
);
951 r
= sd_bus_message_skip(reply
, "v");
956 r
= sd_bus_message_exit_container(reply
);
963 r
= sd_bus_message_exit_container(reply
);
970 int bus_map_id128(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
971 sd_id128_t
*p
= userdata
;
976 r
= sd_bus_message_read_array(m
, SD_BUS_TYPE_BYTE
, &v
, &n
);
983 memcpy((*p
).bytes
, v
, n
);
990 static int map_basic(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
994 r
= sd_bus_message_peek_type(m
, &type
, NULL
);
999 case SD_BUS_TYPE_STRING
: {
1001 char **p
= userdata
;
1003 r
= sd_bus_message_read_basic(m
, type
, &s
);
1010 r
= free_and_strdup(p
, s
);
1014 case SD_BUS_TYPE_ARRAY
: {
1015 _cleanup_strv_free_
char **l
= NULL
;
1016 char ***p
= userdata
;
1018 r
= bus_message_read_strv_extend(m
, &l
);
1029 case SD_BUS_TYPE_BOOLEAN
: {
1033 r
= sd_bus_message_read_basic(m
, type
, &b
);
1042 case SD_BUS_TYPE_UINT32
: {
1044 uint32_t *p
= userdata
;
1046 r
= sd_bus_message_read_basic(m
, type
, &u
);
1055 case SD_BUS_TYPE_UINT64
: {
1057 uint64_t *p
= userdata
;
1059 r
= sd_bus_message_read_basic(m
, type
, &t
);
1075 int bus_message_map_all_properties(
1077 const struct bus_properties_map
*map
,
1080 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1086 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
1090 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1091 const struct bus_properties_map
*prop
;
1093 const char *contents
;
1097 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
);
1101 for (i
= 0, prop
= NULL
; map
[i
].member
; i
++)
1102 if (streq(map
[i
].member
, member
)) {
1108 r
= sd_bus_message_peek_type(m
, NULL
, &contents
);
1112 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, contents
);
1116 v
= (uint8_t *)userdata
+ prop
->offset
;
1118 r
= prop
->set(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1120 r
= map_basic(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1124 r
= sd_bus_message_exit_container(m
);
1128 r
= sd_bus_message_skip(m
, "v");
1133 r
= sd_bus_message_exit_container(m
);
1140 return sd_bus_message_exit_container(m
);
1143 int bus_message_map_properties_changed(
1145 const struct bus_properties_map
*map
,
1149 int r
, invalidated
, i
;
1154 r
= bus_message_map_all_properties(m
, map
, userdata
);
1158 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "s");
1163 while ((r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
)) > 0)
1164 for (i
= 0; map
[i
].member
; i
++)
1165 if (streq(map
[i
].member
, member
)) {
1172 r
= sd_bus_message_exit_container(m
);
1179 int bus_map_all_properties(
1181 const char *destination
,
1183 const struct bus_properties_map
*map
,
1186 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1187 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1191 assert(destination
);
1195 r
= sd_bus_call_method(
1199 "org.freedesktop.DBus.Properties",
1207 return bus_message_map_all_properties(m
, map
, userdata
);
1210 int bus_open_transport(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1213 assert(transport
>= 0);
1214 assert(transport
< _BUS_TRANSPORT_MAX
);
1217 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1218 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1220 switch (transport
) {
1222 case BUS_TRANSPORT_LOCAL
:
1224 r
= sd_bus_default_user(bus
);
1226 r
= sd_bus_default_system(bus
);
1230 case BUS_TRANSPORT_REMOTE
:
1231 r
= sd_bus_open_system_remote(bus
, host
);
1234 case BUS_TRANSPORT_MACHINE
:
1235 r
= sd_bus_open_system_machine(bus
, host
);
1239 assert_not_reached("Hmm, unknown transport type.");
1245 int bus_open_transport_systemd(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1248 assert(transport
>= 0);
1249 assert(transport
< _BUS_TRANSPORT_MAX
);
1252 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1253 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1255 switch (transport
) {
1257 case BUS_TRANSPORT_LOCAL
:
1259 r
= bus_open_user_systemd(bus
);
1261 r
= bus_open_system_systemd(bus
);
1265 case BUS_TRANSPORT_REMOTE
:
1266 r
= sd_bus_open_system_remote(bus
, host
);
1269 case BUS_TRANSPORT_MACHINE
:
1270 r
= sd_bus_open_system_machine(bus
, host
);
1274 assert_not_reached("Hmm, unknown transport type.");
1280 int bus_property_get_bool(
1283 const char *interface
,
1284 const char *property
,
1285 sd_bus_message
*reply
,
1287 sd_bus_error
*error
) {
1289 int b
= *(bool*) userdata
;
1291 return sd_bus_message_append_basic(reply
, 'b', &b
);
1294 #if __SIZEOF_SIZE_T__ != 8
1295 int bus_property_get_size(
1298 const char *interface
,
1299 const char *property
,
1300 sd_bus_message
*reply
,
1302 sd_bus_error
*error
) {
1304 uint64_t sz
= *(size_t*) userdata
;
1306 return sd_bus_message_append_basic(reply
, 't', &sz
);
1310 #if __SIZEOF_LONG__ != 8
1311 int bus_property_get_long(
1314 const char *interface
,
1315 const char *property
,
1316 sd_bus_message
*reply
,
1318 sd_bus_error
*error
) {
1320 int64_t l
= *(long*) userdata
;
1322 return sd_bus_message_append_basic(reply
, 'x', &l
);
1325 int bus_property_get_ulong(
1328 const char *interface
,
1329 const char *property
,
1330 sd_bus_message
*reply
,
1332 sd_bus_error
*error
) {
1334 uint64_t ul
= *(unsigned long*) userdata
;
1336 return sd_bus_message_append_basic(reply
, 't', &ul
);
1340 int bus_log_parse_error(int r
) {
1341 return log_error_errno(r
, "Failed to parse bus message: %m");
1344 int bus_log_create_error(int r
) {
1345 return log_error_errno(r
, "Failed to create bus message: %m");
1348 int bus_parse_unit_info(sd_bus_message
*message
, UnitInfo
*u
) {
1354 return sd_bus_message_read(
1369 int bus_append_unit_property_assignment(sd_bus_message
*m
, const char *assignment
) {
1370 const char *eq
, *field
;
1376 eq
= strchr(assignment
, '=');
1378 log_error("Not an assignment: %s", assignment
);
1382 field
= strndupa(assignment
, eq
- assignment
);
1385 if (streq(field
, "CPUQuota")) {
1389 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, "CPUQuotaPerSecUSec");
1391 return bus_log_create_error(r
);
1393 r
= sd_bus_message_append(m
, "v", "t", USEC_INFINITY
);
1395 } else if (endswith(eq
, "%")) {
1398 if (sscanf(eq
, "%lf%%", &percent
) != 1 || percent
<= 0) {
1399 log_error("CPU quota '%s' invalid.", eq
);
1403 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, "CPUQuotaPerSecUSec");
1405 return bus_log_create_error(r
);
1407 r
= sd_bus_message_append(m
, "v", "t", (usec_t
) percent
* USEC_PER_SEC
/ 100);
1409 log_error("CPU quota needs to be in percent.");
1414 return bus_log_create_error(r
);
1419 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
1421 return bus_log_create_error(r
);
1423 if (STR_IN_SET(field
,
1424 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
1425 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
1426 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) {
1428 r
= parse_boolean(eq
);
1430 log_error("Failed to parse boolean assignment %s.", assignment
);
1434 r
= sd_bus_message_append(m
, "v", "b", r
);
1436 } else if (streq(field
, "MemoryLimit")) {
1439 if (isempty(eq
) || streq(eq
, "infinity"))
1440 bytes
= (uint64_t) -1;
1442 r
= parse_size(eq
, 1024, &bytes
);
1444 log_error("Failed to parse bytes specification %s", assignment
);
1449 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
1451 } else if (streq(field
, "TasksMax")) {
1454 if (isempty(eq
) || streq(eq
, "infinity"))
1457 r
= safe_atou64(eq
, &n
);
1459 log_error("Failed to parse maximum tasks specification %s", assignment
);
1464 r
= sd_bus_message_append(m
, "v", "t", n
);
1466 } else if (STR_IN_SET(field
, "CPUShares", "BlockIOWeight")) {
1469 r
= safe_atou64(eq
, &u
);
1471 log_error("Failed to parse %s value %s.", field
, eq
);
1475 r
= sd_bus_message_append(m
, "v", "t", u
);
1477 } else if (STR_IN_SET(field
,
1478 "User", "Group", "DevicePolicy", "KillMode",
1479 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1480 "StandardInput", "StandardOutput", "StandardError",
1481 "Description", "Slice", "Type"))
1482 r
= sd_bus_message_append(m
, "v", "s", eq
);
1484 else if (streq(field
, "DeviceAllow")) {
1487 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1489 const char *path
, *rwm
, *e
;
1491 e
= strchr(eq
, ' ');
1493 path
= strndupa(eq
, e
- eq
);
1500 if (!path_startswith(path
, "/dev")) {
1501 log_error("%s is not a device file in /dev.", path
);
1505 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1508 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1511 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1513 const char *path
, *bandwidth
, *e
;
1516 e
= strchr(eq
, ' ');
1518 path
= strndupa(eq
, e
- eq
);
1521 log_error("Failed to parse %s value %s.", field
, eq
);
1525 if (!path_startswith(path
, "/dev")) {
1526 log_error("%s is not a device file in /dev.", path
);
1530 r
= parse_size(bandwidth
, 1000, &bytes
);
1532 log_error("Failed to parse byte value %s.", bandwidth
);
1536 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
1539 } else if (streq(field
, "BlockIODeviceWeight")) {
1542 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1544 const char *path
, *weight
, *e
;
1547 e
= strchr(eq
, ' ');
1549 path
= strndupa(eq
, e
- eq
);
1552 log_error("Failed to parse %s value %s.", field
, eq
);
1556 if (!path_startswith(path
, "/dev")) {
1557 log_error("%s is not a device file in /dev.", path
);
1561 r
= safe_atou64(weight
, &u
);
1563 log_error("Failed to parse %s value %s.", field
, weight
);
1566 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1569 } else if (rlimit_from_string(field
) >= 0) {
1572 if (streq(eq
, "infinity"))
1575 r
= safe_atou64(eq
, &rl
);
1577 log_error("Invalid resource limit: %s", eq
);
1582 r
= sd_bus_message_append(m
, "v", "t", rl
);
1584 } else if (streq(field
, "Nice")) {
1587 r
= safe_atoi32(eq
, &i
);
1589 log_error("Failed to parse %s value %s.", field
, eq
);
1593 r
= sd_bus_message_append(m
, "v", "i", i
);
1595 } else if (streq(field
, "Environment")) {
1597 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1599 } else if (streq(field
, "KillSignal")) {
1602 sig
= signal_from_string_try_harder(eq
);
1604 log_error("Failed to parse %s value %s.", field
, eq
);
1608 r
= sd_bus_message_append(m
, "v", "i", sig
);
1610 } else if (streq(field
, "AccuracySec")) {
1613 r
= parse_sec(eq
, &u
);
1615 log_error("Failed to parse %s value %s", field
, eq
);
1619 r
= sd_bus_message_append(m
, "v", "t", u
);
1622 log_error("Unknown assignment %s.", assignment
);
1627 return bus_log_create_error(r
);
1632 typedef struct BusWaitForJobs
{
1639 sd_bus_slot
*slot_job_removed
;
1640 sd_bus_slot
*slot_disconnected
;
1643 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1646 log_error("Warning! D-Bus connection terminated.");
1647 sd_bus_close(sd_bus_message_get_bus(m
));
1652 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1653 const char *path
, *unit
, *result
;
1654 BusWaitForJobs
*d
= userdata
;
1662 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1664 bus_log_parse_error(r
);
1668 found
= set_remove(d
->jobs
, (char*) path
);
1674 if (!isempty(result
))
1675 d
->result
= strdup(result
);
1678 d
->name
= strdup(unit
);
1683 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1687 set_free_free(d
->jobs
);
1689 sd_bus_slot_unref(d
->slot_disconnected
);
1690 sd_bus_slot_unref(d
->slot_job_removed
);
1692 sd_bus_unref(d
->bus
);
1700 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1701 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1707 d
= new0(BusWaitForJobs
, 1);
1711 d
->bus
= sd_bus_ref(bus
);
1713 /* When we are a bus client we match by sender. Direct
1714 * connections OTOH have no initialized sender field, and
1715 * hence we ignore the sender then */
1716 r
= sd_bus_add_match(
1718 &d
->slot_job_removed
,
1721 "sender='org.freedesktop.systemd1',"
1722 "interface='org.freedesktop.systemd1.Manager',"
1723 "member='JobRemoved',"
1724 "path='/org/freedesktop/systemd1'" :
1726 "interface='org.freedesktop.systemd1.Manager',"
1727 "member='JobRemoved',"
1728 "path='/org/freedesktop/systemd1'",
1729 match_job_removed
, d
);
1733 r
= sd_bus_add_match(
1735 &d
->slot_disconnected
,
1737 "sender='org.freedesktop.DBus.Local',"
1738 "interface='org.freedesktop.DBus.Local',"
1739 "member='Disconnected'",
1740 match_disconnected
, d
);
1750 static int bus_process_wait(sd_bus
*bus
) {
1754 r
= sd_bus_process(bus
, NULL
);
1760 r
= sd_bus_wait(bus
, (uint64_t) -1);
1766 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1767 _cleanup_free_
char *dbus_path
= NULL
;
1773 dbus_path
= unit_dbus_path_from_name(d
->name
);
1777 return sd_bus_get_property_string(d
->bus
,
1778 "org.freedesktop.systemd1",
1780 "org.freedesktop.systemd1.Service",
1786 static const struct {
1787 const char *result
, *explanation
;
1788 } explanations
[] = {
1789 { "resources", "a configured resource limit was exceeded" },
1790 { "timeout", "a timeout was exceeded" },
1791 { "exit-code", "the control process exited with error code" },
1792 { "signal", "a fatal signal was delivered to the control process" },
1793 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1794 { "watchdog", "the service failed to send watchdog ping" },
1795 { "start-limit", "start of the service was attempted too often" }
1798 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1799 _cleanup_free_
char *service_shell_quoted
= NULL
;
1803 service_shell_quoted
= shell_maybe_quote(service
);
1805 if (!isempty(result
)) {
1808 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1809 if (streq(result
, explanations
[i
].result
))
1812 if (i
< ELEMENTSOF(explanations
)) {
1813 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1815 explanations
[i
].explanation
,
1816 strna(service_shell_quoted
));
1822 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1824 strna(service_shell_quoted
));
1827 /* For some results maybe additional explanation is required */
1828 if (streq_ptr(result
, "start-limit"))
1829 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1830 strna(service_shell_quoted
));
1833 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1839 if (streq(d
->result
, "canceled"))
1840 log_error("Job for %s canceled.", strna(d
->name
));
1841 else if (streq(d
->result
, "timeout"))
1842 log_error("Job for %s timed out.", strna(d
->name
));
1843 else if (streq(d
->result
, "dependency"))
1844 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1845 else if (streq(d
->result
, "invalid"))
1846 log_error("Job for %s invalid.", strna(d
->name
));
1847 else if (streq(d
->result
, "assert"))
1848 log_error("Assertion failed on job for %s.", strna(d
->name
));
1849 else if (streq(d
->result
, "unsupported"))
1850 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1851 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1854 _cleanup_free_
char *result
= NULL
;
1856 q
= bus_job_get_service_result(d
, &result
);
1858 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1860 log_job_error_with_service_result(d
->name
, result
);
1862 log_error("Job failed. See \"journalctl -xe\" for details.");
1866 if (streq(d
->result
, "canceled"))
1868 else if (streq(d
->result
, "timeout"))
1870 else if (streq(d
->result
, "dependency"))
1872 else if (streq(d
->result
, "invalid"))
1874 else if (streq(d
->result
, "assert"))
1876 else if (streq(d
->result
, "unsupported"))
1878 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1884 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1889 while (!set_isempty(d
->jobs
)) {
1892 q
= bus_process_wait(d
->bus
);
1894 return log_error_errno(q
, "Failed to wait for response: %m");
1897 q
= check_wait_response(d
, quiet
);
1898 /* Return the first error as it is most likely to be
1900 if (q
< 0 && r
== 0)
1903 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1906 d
->name
= mfree(d
->name
);
1907 d
->result
= mfree(d
->result
);
1913 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1918 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1922 return set_put_strdup(d
->jobs
, path
);
1925 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1928 r
= bus_wait_for_jobs_add(d
, path
);
1932 return bus_wait_for_jobs(d
, quiet
);
1935 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1936 const char *type
, *path
, *source
;
1939 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1941 return bus_log_parse_error(r
);
1943 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1945 if (streq(type
, "symlink"))
1946 log_info("Created symlink from %s to %s.", path
, source
);
1948 log_info("Removed symlink %s.", path
);
1951 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
1956 return bus_log_parse_error(r
);
1958 r
= sd_bus_message_exit_container(m
);
1960 return bus_log_parse_error(r
);
1966 * bus_path_encode_unique() - encode unique object path
1967 * @b: bus connection or NULL
1968 * @prefix: object path prefix
1969 * @sender_id: unique-name of client, or NULL
1970 * @external_id: external ID to be chosen by client, or NULL
1971 * @ret_path: storage for encoded object path pointer
1973 * Whenever we provide a bus API that allows clients to create and manage
1974 * server-side objects, we need to provide a unique name for these objects. If
1975 * we let the server choose the name, we suffer from a race condition: If a
1976 * client creates an object asynchronously, it cannot destroy that object until
1977 * it received the method reply. It cannot know the name of the new object,
1978 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1980 * Therefore, many APIs allow the client to choose the unique name for newly
1981 * created objects. There're two problems to solve, though:
1982 * 1) Object names are usually defined via dbus object paths, which are
1983 * usually globally namespaced. Therefore, multiple clients must be able
1984 * to choose unique object names without interference.
1985 * 2) If multiple libraries share the same bus connection, they must be
1986 * able to choose unique object names without interference.
1987 * The first problem is solved easily by prefixing a name with the
1988 * unique-bus-name of a connection. The server side must enforce this and
1989 * reject any other name. The second problem is solved by providing unique
1990 * suffixes from within sd-bus.
1992 * This helper allows clients to create unique object-paths. It uses the
1993 * template '/prefix/sender_id/external_id' and returns the new path in
1994 * @ret_path (must be freed by the caller).
1995 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1996 * NULL, this function allocates a unique suffix via @b (by requesting a new
1997 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2000 * Returns: 0 on success, negative error code on failure.
2002 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
2003 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
2004 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
2007 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
2008 assert_return(object_path_is_valid(prefix
), -EINVAL
);
2009 assert_return(ret_path
, -EINVAL
);
2012 r
= sd_bus_get_unique_name(b
, &sender_id
);
2018 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
2019 external_id
= external_buf
;
2022 sender_label
= bus_label_escape(sender_id
);
2026 external_label
= bus_label_escape(external_id
);
2027 if (!external_label
)
2030 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2039 * bus_path_decode_unique() - decode unique object path
2040 * @path: object path to decode
2041 * @prefix: object path prefix
2042 * @ret_sender: output parameter for sender-id label
2043 * @ret_external: output parameter for external-id label
2045 * This does the reverse of bus_path_encode_unique() (see its description for
2046 * details). Both trailing labels, sender-id and external-id, are unescaped and
2047 * returned in the given output parameters (the caller must free them).
2049 * Note that this function returns 0 if the path does not match the template
2050 * (see bus_path_encode_unique()), 1 if it matched.
2052 * Returns: Negative error code on failure, 0 if the given object path does not
2053 * match the template (return parameters are set to NULL), 1 if it was
2054 * parsed successfully (return parameters contain allocated labels).
2056 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2058 char *sender
, *external
;
2060 assert(object_path_is_valid(path
));
2061 assert(object_path_is_valid(prefix
));
2063 assert(ret_external
);
2065 p
= object_path_startswith(path
, prefix
);
2068 *ret_external
= NULL
;
2075 *ret_external
= NULL
;
2079 sender
= bus_label_unescape_n(p
, q
- p
);
2080 external
= bus_label_unescape(q
+ 1);
2081 if (!sender
|| !external
) {
2087 *ret_sender
= sender
;
2088 *ret_external
= external
;
2092 bool is_kdbus_wanted(void) {
2093 _cleanup_free_
char *value
= NULL
;
2095 const bool configured
= true;
2097 const bool configured
= false;
2102 if (get_proc_cmdline_key("kdbus", NULL
) > 0)
2105 r
= get_proc_cmdline_key("kdbus=", &value
);
2109 return parse_boolean(value
) == 1;
2112 bool is_kdbus_available(void) {
2113 _cleanup_close_
int fd
= -1;
2114 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2116 if (!is_kdbus_wanted())
2119 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2123 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;