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",
1427 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges")) {
1429 r
= parse_boolean(eq
);
1431 log_error("Failed to parse boolean assignment %s.", assignment
);
1435 r
= sd_bus_message_append(m
, "v", "b", r
);
1437 } else if (streq(field
, "MemoryLimit")) {
1440 if (isempty(eq
) || streq(eq
, "infinity"))
1441 bytes
= (uint64_t) -1;
1443 r
= parse_size(eq
, 1024, &bytes
);
1445 log_error("Failed to parse bytes specification %s", assignment
);
1450 r
= sd_bus_message_append(m
, "v", "t", bytes
);
1452 } else if (streq(field
, "TasksMax")) {
1455 if (isempty(eq
) || streq(eq
, "infinity"))
1458 r
= safe_atou64(eq
, &n
);
1460 log_error("Failed to parse maximum tasks specification %s", assignment
);
1465 r
= sd_bus_message_append(m
, "v", "t", n
);
1467 } else if (STR_IN_SET(field
, "CPUShares", "BlockIOWeight")) {
1470 r
= safe_atou64(eq
, &u
);
1472 log_error("Failed to parse %s value %s.", field
, eq
);
1476 r
= sd_bus_message_append(m
, "v", "t", u
);
1478 } else if (STR_IN_SET(field
,
1479 "User", "Group", "DevicePolicy", "KillMode",
1480 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1481 "StandardInput", "StandardOutput", "StandardError",
1482 "Description", "Slice", "Type"))
1483 r
= sd_bus_message_append(m
, "v", "s", eq
);
1485 else if (streq(field
, "DeviceAllow")) {
1488 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1490 const char *path
, *rwm
, *e
;
1492 e
= strchr(eq
, ' ');
1494 path
= strndupa(eq
, e
- eq
);
1501 if (!path_startswith(path
, "/dev")) {
1502 log_error("%s is not a device file in /dev.", path
);
1506 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1509 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1512 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1514 const char *path
, *bandwidth
, *e
;
1517 e
= strchr(eq
, ' ');
1519 path
= strndupa(eq
, e
- eq
);
1522 log_error("Failed to parse %s value %s.", field
, eq
);
1526 if (!path_startswith(path
, "/dev")) {
1527 log_error("%s is not a device file in /dev.", path
);
1531 r
= parse_size(bandwidth
, 1000, &bytes
);
1533 log_error("Failed to parse byte value %s.", bandwidth
);
1537 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, bytes
);
1540 } else if (streq(field
, "BlockIODeviceWeight")) {
1543 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1545 const char *path
, *weight
, *e
;
1548 e
= strchr(eq
, ' ');
1550 path
= strndupa(eq
, e
- eq
);
1553 log_error("Failed to parse %s value %s.", field
, eq
);
1557 if (!path_startswith(path
, "/dev")) {
1558 log_error("%s is not a device file in /dev.", path
);
1562 r
= safe_atou64(weight
, &u
);
1564 log_error("Failed to parse %s value %s.", field
, weight
);
1567 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1570 } else if (rlimit_from_string(field
) >= 0) {
1573 if (streq(eq
, "infinity"))
1576 r
= safe_atou64(eq
, &rl
);
1578 log_error("Invalid resource limit: %s", eq
);
1583 r
= sd_bus_message_append(m
, "v", "t", rl
);
1585 } else if (streq(field
, "Nice")) {
1588 r
= safe_atoi32(eq
, &i
);
1590 log_error("Failed to parse %s value %s.", field
, eq
);
1594 r
= sd_bus_message_append(m
, "v", "i", i
);
1596 } else if (streq(field
, "Environment")) {
1598 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1600 } else if (streq(field
, "KillSignal")) {
1603 sig
= signal_from_string_try_harder(eq
);
1605 log_error("Failed to parse %s value %s.", field
, eq
);
1609 r
= sd_bus_message_append(m
, "v", "i", sig
);
1611 } else if (streq(field
, "AccuracySec")) {
1614 r
= parse_sec(eq
, &u
);
1616 log_error("Failed to parse %s value %s", field
, eq
);
1620 r
= sd_bus_message_append(m
, "v", "t", u
);
1623 log_error("Unknown assignment %s.", assignment
);
1628 return bus_log_create_error(r
);
1633 typedef struct BusWaitForJobs
{
1640 sd_bus_slot
*slot_job_removed
;
1641 sd_bus_slot
*slot_disconnected
;
1644 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1647 log_error("Warning! D-Bus connection terminated.");
1648 sd_bus_close(sd_bus_message_get_bus(m
));
1653 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1654 const char *path
, *unit
, *result
;
1655 BusWaitForJobs
*d
= userdata
;
1663 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1665 bus_log_parse_error(r
);
1669 found
= set_remove(d
->jobs
, (char*) path
);
1675 if (!isempty(result
))
1676 d
->result
= strdup(result
);
1679 d
->name
= strdup(unit
);
1684 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1688 set_free_free(d
->jobs
);
1690 sd_bus_slot_unref(d
->slot_disconnected
);
1691 sd_bus_slot_unref(d
->slot_job_removed
);
1693 sd_bus_unref(d
->bus
);
1701 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1702 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1708 d
= new0(BusWaitForJobs
, 1);
1712 d
->bus
= sd_bus_ref(bus
);
1714 /* When we are a bus client we match by sender. Direct
1715 * connections OTOH have no initialized sender field, and
1716 * hence we ignore the sender then */
1717 r
= sd_bus_add_match(
1719 &d
->slot_job_removed
,
1722 "sender='org.freedesktop.systemd1',"
1723 "interface='org.freedesktop.systemd1.Manager',"
1724 "member='JobRemoved',"
1725 "path='/org/freedesktop/systemd1'" :
1727 "interface='org.freedesktop.systemd1.Manager',"
1728 "member='JobRemoved',"
1729 "path='/org/freedesktop/systemd1'",
1730 match_job_removed
, d
);
1734 r
= sd_bus_add_match(
1736 &d
->slot_disconnected
,
1738 "sender='org.freedesktop.DBus.Local',"
1739 "interface='org.freedesktop.DBus.Local',"
1740 "member='Disconnected'",
1741 match_disconnected
, d
);
1751 static int bus_process_wait(sd_bus
*bus
) {
1755 r
= sd_bus_process(bus
, NULL
);
1761 r
= sd_bus_wait(bus
, (uint64_t) -1);
1767 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1768 _cleanup_free_
char *dbus_path
= NULL
;
1774 dbus_path
= unit_dbus_path_from_name(d
->name
);
1778 return sd_bus_get_property_string(d
->bus
,
1779 "org.freedesktop.systemd1",
1781 "org.freedesktop.systemd1.Service",
1787 static const struct {
1788 const char *result
, *explanation
;
1789 } explanations
[] = {
1790 { "resources", "a configured resource limit was exceeded" },
1791 { "timeout", "a timeout was exceeded" },
1792 { "exit-code", "the control process exited with error code" },
1793 { "signal", "a fatal signal was delivered to the control process" },
1794 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1795 { "watchdog", "the service failed to send watchdog ping" },
1796 { "start-limit", "start of the service was attempted too often" }
1799 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1800 _cleanup_free_
char *service_shell_quoted
= NULL
;
1804 service_shell_quoted
= shell_maybe_quote(service
);
1806 if (!isempty(result
)) {
1809 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1810 if (streq(result
, explanations
[i
].result
))
1813 if (i
< ELEMENTSOF(explanations
)) {
1814 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1816 explanations
[i
].explanation
,
1817 strna(service_shell_quoted
));
1823 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1825 strna(service_shell_quoted
));
1828 /* For some results maybe additional explanation is required */
1829 if (streq_ptr(result
, "start-limit"))
1830 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1831 strna(service_shell_quoted
));
1834 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1840 if (streq(d
->result
, "canceled"))
1841 log_error("Job for %s canceled.", strna(d
->name
));
1842 else if (streq(d
->result
, "timeout"))
1843 log_error("Job for %s timed out.", strna(d
->name
));
1844 else if (streq(d
->result
, "dependency"))
1845 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1846 else if (streq(d
->result
, "invalid"))
1847 log_error("Job for %s invalid.", strna(d
->name
));
1848 else if (streq(d
->result
, "assert"))
1849 log_error("Assertion failed on job for %s.", strna(d
->name
));
1850 else if (streq(d
->result
, "unsupported"))
1851 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1852 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1855 _cleanup_free_
char *result
= NULL
;
1857 q
= bus_job_get_service_result(d
, &result
);
1859 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1861 log_job_error_with_service_result(d
->name
, result
);
1863 log_error("Job failed. See \"journalctl -xe\" for details.");
1867 if (streq(d
->result
, "canceled"))
1869 else if (streq(d
->result
, "timeout"))
1871 else if (streq(d
->result
, "dependency"))
1873 else if (streq(d
->result
, "invalid"))
1875 else if (streq(d
->result
, "assert"))
1877 else if (streq(d
->result
, "unsupported"))
1879 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1885 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1890 while (!set_isempty(d
->jobs
)) {
1893 q
= bus_process_wait(d
->bus
);
1895 return log_error_errno(q
, "Failed to wait for response: %m");
1898 q
= check_wait_response(d
, quiet
);
1899 /* Return the first error as it is most likely to be
1901 if (q
< 0 && r
== 0)
1904 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1907 d
->name
= mfree(d
->name
);
1908 d
->result
= mfree(d
->result
);
1914 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1919 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1923 return set_put_strdup(d
->jobs
, path
);
1926 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1929 r
= bus_wait_for_jobs_add(d
, path
);
1933 return bus_wait_for_jobs(d
, quiet
);
1936 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1937 const char *type
, *path
, *source
;
1940 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1942 return bus_log_parse_error(r
);
1944 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1946 if (streq(type
, "symlink"))
1947 log_info("Created symlink from %s to %s.", path
, source
);
1949 log_info("Removed symlink %s.", path
);
1952 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
1957 return bus_log_parse_error(r
);
1959 r
= sd_bus_message_exit_container(m
);
1961 return bus_log_parse_error(r
);
1967 * bus_path_encode_unique() - encode unique object path
1968 * @b: bus connection or NULL
1969 * @prefix: object path prefix
1970 * @sender_id: unique-name of client, or NULL
1971 * @external_id: external ID to be chosen by client, or NULL
1972 * @ret_path: storage for encoded object path pointer
1974 * Whenever we provide a bus API that allows clients to create and manage
1975 * server-side objects, we need to provide a unique name for these objects. If
1976 * we let the server choose the name, we suffer from a race condition: If a
1977 * client creates an object asynchronously, it cannot destroy that object until
1978 * it received the method reply. It cannot know the name of the new object,
1979 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1981 * Therefore, many APIs allow the client to choose the unique name for newly
1982 * created objects. There're two problems to solve, though:
1983 * 1) Object names are usually defined via dbus object paths, which are
1984 * usually globally namespaced. Therefore, multiple clients must be able
1985 * to choose unique object names without interference.
1986 * 2) If multiple libraries share the same bus connection, they must be
1987 * able to choose unique object names without interference.
1988 * The first problem is solved easily by prefixing a name with the
1989 * unique-bus-name of a connection. The server side must enforce this and
1990 * reject any other name. The second problem is solved by providing unique
1991 * suffixes from within sd-bus.
1993 * This helper allows clients to create unique object-paths. It uses the
1994 * template '/prefix/sender_id/external_id' and returns the new path in
1995 * @ret_path (must be freed by the caller).
1996 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1997 * NULL, this function allocates a unique suffix via @b (by requesting a new
1998 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2001 * Returns: 0 on success, negative error code on failure.
2003 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
2004 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
2005 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
2008 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
2009 assert_return(object_path_is_valid(prefix
), -EINVAL
);
2010 assert_return(ret_path
, -EINVAL
);
2013 r
= sd_bus_get_unique_name(b
, &sender_id
);
2019 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
2020 external_id
= external_buf
;
2023 sender_label
= bus_label_escape(sender_id
);
2027 external_label
= bus_label_escape(external_id
);
2028 if (!external_label
)
2031 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2040 * bus_path_decode_unique() - decode unique object path
2041 * @path: object path to decode
2042 * @prefix: object path prefix
2043 * @ret_sender: output parameter for sender-id label
2044 * @ret_external: output parameter for external-id label
2046 * This does the reverse of bus_path_encode_unique() (see its description for
2047 * details). Both trailing labels, sender-id and external-id, are unescaped and
2048 * returned in the given output parameters (the caller must free them).
2050 * Note that this function returns 0 if the path does not match the template
2051 * (see bus_path_encode_unique()), 1 if it matched.
2053 * Returns: Negative error code on failure, 0 if the given object path does not
2054 * match the template (return parameters are set to NULL), 1 if it was
2055 * parsed successfully (return parameters contain allocated labels).
2057 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2059 char *sender
, *external
;
2061 assert(object_path_is_valid(path
));
2062 assert(object_path_is_valid(prefix
));
2064 assert(ret_external
);
2066 p
= object_path_startswith(path
, prefix
);
2069 *ret_external
= NULL
;
2076 *ret_external
= NULL
;
2080 sender
= bus_label_unescape_n(p
, q
- p
);
2081 external
= bus_label_unescape(q
+ 1);
2082 if (!sender
|| !external
) {
2088 *ret_sender
= sender
;
2089 *ret_external
= external
;
2093 bool is_kdbus_wanted(void) {
2094 _cleanup_free_
char *value
= NULL
;
2096 const bool configured
= true;
2098 const bool configured
= false;
2103 if (get_proc_cmdline_key("kdbus", NULL
) > 0)
2106 r
= get_proc_cmdline_key("kdbus=", &value
);
2110 return parse_boolean(value
) == 1;
2113 bool is_kdbus_available(void) {
2114 _cleanup_close_
int fd
= -1;
2115 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2117 if (!is_kdbus_wanted())
2120 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2124 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;