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 "unit-name.h"
36 #include "bus-error.h"
37 #include "bus-label.h"
38 #include "bus-message.h"
40 #include "bus-internal.h"
42 static int name_owner_change_callback(sd_bus_message
*m
, void *userdata
, sd_bus_error
*ret_error
) {
43 sd_event
*e
= userdata
;
48 sd_bus_close(sd_bus_message_get_bus(m
));
54 int bus_async_unregister_and_exit(sd_event
*e
, sd_bus
*bus
, const char *name
) {
55 _cleanup_free_
char *match
= NULL
;
63 /* We unregister the name here and then wait for the
64 * NameOwnerChanged signal for this event to arrive before we
65 * quit. We do this in order to make sure that any queued
66 * requests are still processed before we really exit. */
68 r
= sd_bus_get_unique_name(bus
, &unique
);
73 "sender='org.freedesktop.DBus',"
75 "interface='org.freedesktop.DBus',"
76 "member='NameOwnerChanged',"
77 "path='/org/freedesktop/DBus',"
80 "arg2=''", name
, unique
);
84 r
= sd_bus_add_match(bus
, NULL
, match
, name_owner_change_callback
, e
);
88 r
= sd_bus_release_name(bus
, name
);
95 int bus_event_loop_with_idle(
100 check_idle_t check_idle
,
102 bool exiting
= false;
112 r
= sd_event_get_state(e
);
115 if (r
== SD_EVENT_FINISHED
)
119 idle
= check_idle(userdata
);
123 r
= sd_event_run(e
, exiting
|| !idle
? (uint64_t) -1 : timeout
);
127 if (r
== 0 && !exiting
&& idle
) {
129 r
= sd_bus_try_close(bus
);
133 /* Fallback for dbus1 connections: we
134 * unregister the name and wait for the
135 * response to come through for it */
136 if (r
== -EOPNOTSUPP
) {
138 /* Inform the service manager that we
139 * are going down, so that it will
140 * queue all further start requests,
141 * instead of assuming we are already
143 sd_notify(false, "STOPPING=1");
145 r
= bus_async_unregister_and_exit(e
, bus
, name
);
161 r
= sd_event_get_exit_code(e
, &code
);
168 int bus_name_has_owner(sd_bus
*c
, const char *name
, sd_bus_error
*error
) {
169 _cleanup_bus_message_unref_ sd_bus_message
*rep
= NULL
;
170 int r
, has_owner
= 0;
175 r
= sd_bus_call_method(c
,
176 "org.freedesktop.DBus",
177 "/org/freedesktop/dbus",
178 "org.freedesktop.DBus",
187 r
= sd_bus_message_read_basic(rep
, 'b', &has_owner
);
189 return sd_bus_error_set_errno(error
, r
);
194 static int check_good_user(sd_bus_message
*m
, uid_t good_user
) {
195 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
201 if (good_user
== UID_INVALID
)
204 r
= sd_bus_query_sender_creds(m
, SD_BUS_CREDS_EUID
, &creds
);
208 /* Don't trust augmented credentials for authorization */
209 assert_return((sd_bus_creds_get_augmented_mask(creds
) & SD_BUS_CREDS_EUID
) == 0, -EPERM
);
211 r
= sd_bus_creds_get_euid(creds
, &sender_uid
);
215 return sender_uid
== good_user
;
219 sd_bus_message
*call
,
231 /* Tests non-interactively! */
233 r
= check_good_user(call
, good_user
);
237 r
= sd_bus_query_sender_privilege(call
, capability
);
244 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
245 int authorized
= false, challenge
= false;
248 sender
= sd_bus_message_get_sender(call
);
252 r
= sd_bus_call_method(
254 "org.freedesktop.PolicyKit1",
255 "/org/freedesktop/PolicyKit1/Authority",
256 "org.freedesktop.PolicyKit1.Authority",
257 "CheckAuthorization",
261 "system-bus-name", 1, "name", "s", sender
,
268 /* Treat no PK available as access denied */
269 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
)) {
270 sd_bus_error_free(e
);
277 r
= sd_bus_message_enter_container(reply
, 'r', "bba{ss}");
281 r
= sd_bus_message_read(reply
, "bb", &authorized
, &challenge
);
289 *_challenge
= challenge
;
300 typedef struct AsyncPolkitQuery
{
301 sd_bus_message
*request
, *reply
;
302 sd_bus_message_handler_t callback
;
308 static void async_polkit_query_free(AsyncPolkitQuery
*q
) {
313 sd_bus_slot_unref(q
->slot
);
315 if (q
->registry
&& q
->request
)
316 hashmap_remove(q
->registry
, q
->request
);
318 sd_bus_message_unref(q
->request
);
319 sd_bus_message_unref(q
->reply
);
324 static int async_polkit_callback(sd_bus_message
*reply
, void *userdata
, sd_bus_error
*error
) {
325 _cleanup_bus_error_free_ sd_bus_error error_buffer
= SD_BUS_ERROR_NULL
;
326 AsyncPolkitQuery
*q
= userdata
;
332 q
->slot
= sd_bus_slot_unref(q
->slot
);
333 q
->reply
= sd_bus_message_ref(reply
);
335 r
= sd_bus_message_rewind(q
->request
, true);
337 r
= sd_bus_reply_method_errno(q
->request
, r
, NULL
);
341 r
= q
->callback(q
->request
, q
->userdata
, &error_buffer
);
342 r
= bus_maybe_reply_error(q
->request
, r
, &error_buffer
);
345 async_polkit_query_free(q
);
352 int bus_verify_polkit_async(
353 sd_bus_message
*call
,
359 sd_bus_error
*error
) {
362 _cleanup_bus_message_unref_ sd_bus_message
*pk
= NULL
;
365 sd_bus_message_handler_t callback
;
375 r
= check_good_user(call
, good_user
);
380 q
= hashmap_get(*registry
, call
);
382 int authorized
, challenge
;
384 /* This is the second invocation of this function, and
385 * there's already a response from polkit, let's
389 if (sd_bus_message_is_method_error(q
->reply
, NULL
)) {
390 const sd_bus_error
*e
;
392 /* Copy error from polkit reply */
393 e
= sd_bus_message_get_error(q
->reply
);
394 sd_bus_error_copy(error
, e
);
396 /* Treat no PK available as access denied */
397 if (sd_bus_error_has_name(e
, SD_BUS_ERROR_SERVICE_UNKNOWN
))
400 return -sd_bus_error_get_errno(e
);
403 r
= sd_bus_message_enter_container(q
->reply
, 'r', "bba{ss}");
405 r
= sd_bus_message_read(q
->reply
, "bb", &authorized
, &challenge
);
414 return sd_bus_error_set(error
, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED
, "Interactive authentication required.");
420 r
= sd_bus_query_sender_privilege(call
, capability
);
427 if (sd_bus_get_current_message(call
->bus
) != call
)
430 callback
= sd_bus_get_current_handler(call
->bus
);
434 userdata
= sd_bus_get_current_userdata(call
->bus
);
436 sender
= sd_bus_message_get_sender(call
);
440 c
= sd_bus_message_get_allow_interactive_authorization(call
);
446 r
= hashmap_ensure_allocated(registry
, NULL
);
450 r
= sd_bus_message_new_method_call(
453 "org.freedesktop.PolicyKit1",
454 "/org/freedesktop/PolicyKit1/Authority",
455 "org.freedesktop.PolicyKit1.Authority",
456 "CheckAuthorization");
460 r
= sd_bus_message_append(
463 "system-bus-name", 1, "name", "s", sender
,
471 q
= new0(AsyncPolkitQuery
, 1);
475 q
->request
= sd_bus_message_ref(call
);
476 q
->callback
= callback
;
477 q
->userdata
= userdata
;
479 r
= hashmap_put(*registry
, call
, q
);
481 async_polkit_query_free(q
);
485 q
->registry
= *registry
;
487 r
= sd_bus_call_async(call
->bus
, &q
->slot
, pk
, async_polkit_callback
, q
, 0);
489 async_polkit_query_free(q
);
499 void bus_verify_polkit_async_registry_free(Hashmap
*registry
) {
503 while ((q
= hashmap_steal_first(registry
)))
504 async_polkit_query_free(q
);
506 hashmap_free(registry
);
510 int bus_check_peercred(sd_bus
*c
) {
517 fd
= sd_bus_get_fd(c
);
521 l
= sizeof(struct ucred
);
522 if (getsockopt(fd
, SOL_SOCKET
, SO_PEERCRED
, &ucred
, &l
) < 0)
525 if (l
!= sizeof(struct ucred
))
528 if (ucred
.uid
!= 0 && ucred
.uid
!= geteuid())
534 int bus_open_system_systemd(sd_bus
**_bus
) {
535 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
541 return sd_bus_open_system(_bus
);
543 /* If we are root and kdbus is not available, then let's talk
544 * directly to the system instance, instead of going via the
548 r
= sd_bus_new(&bus
);
552 r
= sd_bus_set_address(bus
, KERNEL_SYSTEM_BUS_ADDRESS
);
556 bus
->bus_client
= true;
558 r
= sd_bus_start(bus
);
565 bus
= sd_bus_unref(bus
);
568 r
= sd_bus_new(&bus
);
572 r
= sd_bus_set_address(bus
, "unix:path=/run/systemd/private");
576 r
= sd_bus_start(bus
);
578 return sd_bus_open_system(_bus
);
580 r
= bus_check_peercred(bus
);
590 int bus_open_user_systemd(sd_bus
**_bus
) {
591 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
592 _cleanup_free_
char *ee
= NULL
;
596 /* Try via kdbus first, and then directly */
601 r
= sd_bus_new(&bus
);
605 if (asprintf(&bus
->address
, KERNEL_USER_BUS_ADDRESS_FMT
, getuid()) < 0)
608 bus
->bus_client
= true;
610 r
= sd_bus_start(bus
);
617 bus
= sd_bus_unref(bus
);
620 e
= secure_getenv("XDG_RUNTIME_DIR");
622 return sd_bus_open_user(_bus
);
624 ee
= bus_address_escape(e
);
628 r
= sd_bus_new(&bus
);
632 bus
->address
= strjoin("unix:path=", ee
, "/systemd/private", NULL
);
636 r
= sd_bus_start(bus
);
638 return sd_bus_open_user(_bus
);
640 r
= bus_check_peercred(bus
);
650 int bus_print_property(const char *name
, sd_bus_message
*property
, bool all
) {
652 const char *contents
;
658 r
= sd_bus_message_peek_type(property
, &type
, &contents
);
664 case SD_BUS_TYPE_STRING
: {
667 r
= sd_bus_message_read_basic(property
, type
, &s
);
671 if (all
|| !isempty(s
)) {
672 _cleanup_free_
char *escaped
= NULL
;
674 escaped
= xescape(s
, "\n");
678 printf("%s=%s\n", name
, escaped
);
684 case SD_BUS_TYPE_BOOLEAN
: {
687 r
= sd_bus_message_read_basic(property
, type
, &b
);
691 printf("%s=%s\n", name
, yes_no(b
));
696 case SD_BUS_TYPE_UINT64
: {
699 r
= sd_bus_message_read_basic(property
, type
, &u
);
703 /* Yes, heuristics! But we can change this check
704 * should it turn out to not be sufficient */
706 if (endswith(name
, "Timestamp")) {
707 char timestamp
[FORMAT_TIMESTAMP_MAX
], *t
;
709 t
= format_timestamp(timestamp
, sizeof(timestamp
), u
);
711 printf("%s=%s\n", name
, strempty(t
));
713 } else if (strstr(name
, "USec")) {
714 char timespan
[FORMAT_TIMESPAN_MAX
];
716 printf("%s=%s\n", name
, format_timespan(timespan
, sizeof(timespan
), u
, 0));
718 printf("%s=%llu\n", name
, (unsigned long long) u
);
723 case SD_BUS_TYPE_INT64
: {
726 r
= sd_bus_message_read_basic(property
, type
, &i
);
730 printf("%s=%lld\n", name
, (long long) i
);
735 case SD_BUS_TYPE_UINT32
: {
738 r
= sd_bus_message_read_basic(property
, type
, &u
);
742 if (strstr(name
, "UMask") || strstr(name
, "Mode"))
743 printf("%s=%04o\n", name
, u
);
745 printf("%s=%u\n", name
, (unsigned) u
);
750 case SD_BUS_TYPE_INT32
: {
753 r
= sd_bus_message_read_basic(property
, type
, &i
);
757 printf("%s=%i\n", name
, (int) i
);
761 case SD_BUS_TYPE_DOUBLE
: {
764 r
= sd_bus_message_read_basic(property
, type
, &d
);
768 printf("%s=%g\n", name
, d
);
772 case SD_BUS_TYPE_ARRAY
:
773 if (streq(contents
, "s")) {
777 r
= sd_bus_message_enter_container(property
, SD_BUS_TYPE_ARRAY
, contents
);
781 while((r
= sd_bus_message_read_basic(property
, SD_BUS_TYPE_STRING
, &str
)) > 0) {
782 _cleanup_free_
char *escaped
= NULL
;
787 escaped
= xescape(str
, "\n ");
791 printf("%s%s", first
? "" : " ", escaped
);
803 r
= sd_bus_message_exit_container(property
);
809 } else if (streq(contents
, "y")) {
813 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_BYTE
, (const void**) &u
, &n
);
822 for (i
= 0; i
< n
; i
++)
823 printf("%02x", u
[i
]);
830 } else if (streq(contents
, "u")) {
834 r
= sd_bus_message_read_array(property
, SD_BUS_TYPE_UINT32
, (const void**) &u
, &n
);
843 for (i
= 0; i
< n
; i
++)
844 printf("%08x", u
[i
]);
858 int bus_print_all_properties(sd_bus
*bus
, const char *dest
, const char *path
, char **filter
, bool all
) {
859 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
860 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
866 r
= sd_bus_call_method(bus
,
869 "org.freedesktop.DBus.Properties",
877 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
881 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
883 const char *contents
;
885 r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &name
);
889 if (!filter
|| strv_find(filter
, name
)) {
890 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
894 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
898 r
= bus_print_property(name
, reply
, all
);
903 printf("%s=[unprintable]\n", name
);
904 /* skip what we didn't read */
905 r
= sd_bus_message_skip(reply
, contents
);
910 r
= sd_bus_message_exit_container(reply
);
914 r
= sd_bus_message_skip(reply
, "v");
919 r
= sd_bus_message_exit_container(reply
);
926 r
= sd_bus_message_exit_container(reply
);
933 int bus_map_id128(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
934 sd_id128_t
*p
= userdata
;
939 r
= sd_bus_message_read_array(m
, SD_BUS_TYPE_BYTE
, &v
, &n
);
946 memcpy((*p
).bytes
, v
, n
);
953 static int map_basic(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
957 r
= sd_bus_message_peek_type(m
, &type
, NULL
);
962 case SD_BUS_TYPE_STRING
: {
966 r
= sd_bus_message_read_basic(m
, type
, &s
);
973 r
= free_and_strdup(p
, s
);
977 case SD_BUS_TYPE_ARRAY
: {
978 _cleanup_strv_free_
char **l
= NULL
;
979 char ***p
= userdata
;
981 r
= bus_message_read_strv_extend(m
, &l
);
992 case SD_BUS_TYPE_BOOLEAN
: {
996 r
= sd_bus_message_read_basic(m
, type
, &b
);
1005 case SD_BUS_TYPE_UINT32
: {
1007 uint32_t *p
= userdata
;
1009 r
= sd_bus_message_read_basic(m
, type
, &u
);
1018 case SD_BUS_TYPE_UINT64
: {
1020 uint64_t *p
= userdata
;
1022 r
= sd_bus_message_read_basic(m
, type
, &t
);
1038 int bus_message_map_all_properties(
1040 const struct bus_properties_map
*map
,
1043 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1049 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
1053 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1054 const struct bus_properties_map
*prop
;
1056 const char *contents
;
1060 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
);
1064 for (i
= 0, prop
= NULL
; map
[i
].member
; i
++)
1065 if (streq(map
[i
].member
, member
)) {
1071 r
= sd_bus_message_peek_type(m
, NULL
, &contents
);
1075 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, contents
);
1079 v
= (uint8_t *)userdata
+ prop
->offset
;
1081 r
= prop
->set(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1083 r
= map_basic(sd_bus_message_get_bus(m
), member
, m
, &error
, v
);
1087 r
= sd_bus_message_exit_container(m
);
1091 r
= sd_bus_message_skip(m
, "v");
1096 r
= sd_bus_message_exit_container(m
);
1103 return sd_bus_message_exit_container(m
);
1106 int bus_message_map_properties_changed(
1108 const struct bus_properties_map
*map
,
1112 int r
, invalidated
, i
;
1117 r
= bus_message_map_all_properties(m
, map
, userdata
);
1121 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "s");
1126 while ((r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &member
)) > 0)
1127 for (i
= 0; map
[i
].member
; i
++)
1128 if (streq(map
[i
].member
, member
)) {
1135 r
= sd_bus_message_exit_container(m
);
1142 int bus_map_all_properties(
1144 const char *destination
,
1146 const struct bus_properties_map
*map
,
1149 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
1150 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1154 assert(destination
);
1158 r
= sd_bus_call_method(
1162 "org.freedesktop.DBus.Properties",
1170 return bus_message_map_all_properties(m
, map
, userdata
);
1173 int bus_open_transport(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1176 assert(transport
>= 0);
1177 assert(transport
< _BUS_TRANSPORT_MAX
);
1180 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1181 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1183 switch (transport
) {
1185 case BUS_TRANSPORT_LOCAL
:
1187 r
= sd_bus_default_user(bus
);
1189 r
= sd_bus_default_system(bus
);
1193 case BUS_TRANSPORT_REMOTE
:
1194 r
= sd_bus_open_system_remote(bus
, host
);
1197 case BUS_TRANSPORT_MACHINE
:
1198 r
= sd_bus_open_system_machine(bus
, host
);
1202 assert_not_reached("Hmm, unknown transport type.");
1208 int bus_open_transport_systemd(BusTransport transport
, const char *host
, bool user
, sd_bus
**bus
) {
1211 assert(transport
>= 0);
1212 assert(transport
< _BUS_TRANSPORT_MAX
);
1215 assert_return((transport
== BUS_TRANSPORT_LOCAL
) == !host
, -EINVAL
);
1216 assert_return(transport
== BUS_TRANSPORT_LOCAL
|| !user
, -EOPNOTSUPP
);
1218 switch (transport
) {
1220 case BUS_TRANSPORT_LOCAL
:
1222 r
= bus_open_user_systemd(bus
);
1224 r
= bus_open_system_systemd(bus
);
1228 case BUS_TRANSPORT_REMOTE
:
1229 r
= sd_bus_open_system_remote(bus
, host
);
1232 case BUS_TRANSPORT_MACHINE
:
1233 r
= sd_bus_open_system_machine(bus
, host
);
1237 assert_not_reached("Hmm, unknown transport type.");
1243 int bus_property_get_bool(
1246 const char *interface
,
1247 const char *property
,
1248 sd_bus_message
*reply
,
1250 sd_bus_error
*error
) {
1252 int b
= *(bool*) userdata
;
1254 return sd_bus_message_append_basic(reply
, 'b', &b
);
1257 #if __SIZEOF_SIZE_T__ != 8
1258 int bus_property_get_size(
1261 const char *interface
,
1262 const char *property
,
1263 sd_bus_message
*reply
,
1265 sd_bus_error
*error
) {
1267 uint64_t sz
= *(size_t*) userdata
;
1269 return sd_bus_message_append_basic(reply
, 't', &sz
);
1273 #if __SIZEOF_LONG__ != 8
1274 int bus_property_get_long(
1277 const char *interface
,
1278 const char *property
,
1279 sd_bus_message
*reply
,
1281 sd_bus_error
*error
) {
1283 int64_t l
= *(long*) userdata
;
1285 return sd_bus_message_append_basic(reply
, 'x', &l
);
1288 int bus_property_get_ulong(
1291 const char *interface
,
1292 const char *property
,
1293 sd_bus_message
*reply
,
1295 sd_bus_error
*error
) {
1297 uint64_t ul
= *(unsigned long*) userdata
;
1299 return sd_bus_message_append_basic(reply
, 't', &ul
);
1303 int bus_log_parse_error(int r
) {
1304 return log_error_errno(r
, "Failed to parse bus message: %m");
1307 int bus_log_create_error(int r
) {
1308 return log_error_errno(r
, "Failed to create bus message: %m");
1311 int bus_parse_unit_info(sd_bus_message
*message
, UnitInfo
*u
) {
1317 return sd_bus_message_read(
1332 int bus_maybe_reply_error(sd_bus_message
*m
, int r
, sd_bus_error
*error
) {
1336 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1337 sd_bus_reply_method_errno(m
, r
, error
);
1339 } else if (sd_bus_error_is_set(error
)) {
1340 if (m
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
)
1341 sd_bus_reply_method_error(m
, error
);
1345 log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
1346 bus_message_type_to_string(m
->header
->type
),
1349 strna(m
->interface
),
1351 strna(m
->root_container
.signature
),
1352 bus_error_message(error
, r
));
1357 int bus_append_unit_property_assignment(sd_bus_message
*m
, const char *assignment
) {
1358 const char *eq
, *field
;
1364 eq
= strchr(assignment
, '=');
1366 log_error("Not an assignment: %s", assignment
);
1370 field
= strndupa(assignment
, eq
- assignment
);
1373 if (streq(field
, "CPUQuota")) {
1377 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, "CPUQuotaPerSecUSec");
1379 return bus_log_create_error(r
);
1381 r
= sd_bus_message_append(m
, "v", "t", USEC_INFINITY
);
1383 } else if (endswith(eq
, "%")) {
1386 if (sscanf(eq
, "%lf%%", &percent
) != 1 || percent
<= 0) {
1387 log_error("CPU quota '%s' invalid.", eq
);
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_t
) percent
* USEC_PER_SEC
/ 100);
1397 log_error("CPU quota needs to be in percent.");
1402 return bus_log_create_error(r
);
1407 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
1409 return bus_log_create_error(r
);
1411 if (STR_IN_SET(field
,
1412 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1413 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
1415 r
= parse_boolean(eq
);
1417 log_error("Failed to parse boolean assignment %s.", assignment
);
1421 r
= sd_bus_message_append(m
, "v", "b", r
);
1423 } else if (streq(field
, "MemoryLimit")) {
1426 r
= parse_size(eq
, 1024, &bytes
);
1428 log_error("Failed to parse bytes specification %s", assignment
);
1432 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
1434 } else if (STR_IN_SET(field
, "CPUShares", "BlockIOWeight")) {
1437 r
= safe_atou64(eq
, &u
);
1439 log_error("Failed to parse %s value %s.", field
, eq
);
1443 r
= sd_bus_message_append(m
, "v", "t", u
);
1445 } else if (STR_IN_SET(field
, "User", "Group", "DevicePolicy", "KillMode"))
1446 r
= sd_bus_message_append(m
, "v", "s", eq
);
1448 else if (streq(field
, "DeviceAllow")) {
1451 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
1453 const char *path
, *rwm
, *e
;
1455 e
= strchr(eq
, ' ');
1457 path
= strndupa(eq
, e
- eq
);
1464 if (!path_startswith(path
, "/dev")) {
1465 log_error("%s is not a device file in /dev.", path
);
1469 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
1472 } else if (STR_IN_SET(field
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1475 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1477 const char *path
, *bandwidth
, *e
;
1480 e
= strchr(eq
, ' ');
1482 path
= strndupa(eq
, e
- eq
);
1485 log_error("Failed to parse %s value %s.", field
, eq
);
1489 if (!path_startswith(path
, "/dev")) {
1490 log_error("%s is not a device file in /dev.", path
);
1494 r
= parse_size(bandwidth
, 1000, &bytes
);
1496 log_error("Failed to parse byte value %s.", bandwidth
);
1500 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
1503 } else if (streq(field
, "BlockIODeviceWeight")) {
1506 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
1508 const char *path
, *weight
, *e
;
1511 e
= strchr(eq
, ' ');
1513 path
= strndupa(eq
, e
- eq
);
1516 log_error("Failed to parse %s value %s.", field
, eq
);
1520 if (!path_startswith(path
, "/dev")) {
1521 log_error("%s is not a device file in /dev.", path
);
1525 r
= safe_atou64(weight
, &u
);
1527 log_error("Failed to parse %s value %s.", field
, weight
);
1530 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
1533 } else if (rlimit_from_string(field
) >= 0) {
1536 if (streq(eq
, "infinity"))
1539 r
= safe_atou64(eq
, &rl
);
1541 log_error("Invalid resource limit: %s", eq
);
1546 r
= sd_bus_message_append(m
, "v", "t", rl
);
1548 } else if (streq(field
, "Nice")) {
1551 r
= safe_atoi32(eq
, &i
);
1553 log_error("Failed to parse %s value %s.", field
, eq
);
1557 r
= sd_bus_message_append(m
, "v", "i", i
);
1559 } else if (streq(field
, "Environment")) {
1561 r
= sd_bus_message_append(m
, "v", "as", 1, eq
);
1563 } else if (streq(field
, "KillSignal")) {
1566 sig
= signal_from_string_try_harder(eq
);
1568 log_error("Failed to parse %s value %s.", field
, eq
);
1572 r
= sd_bus_message_append(m
, "v", "i", sig
);
1574 } else if (streq(field
, "AccuracySec")) {
1577 r
= parse_sec(eq
, &u
);
1579 log_error("Failed to parse %s value %s", field
, eq
);
1583 r
= sd_bus_message_append(m
, "v", "t", u
);
1586 log_error("Unknown assignment %s.", assignment
);
1591 return bus_log_create_error(r
);
1596 typedef struct BusWaitForJobs
{
1603 sd_bus_slot
*slot_job_removed
;
1604 sd_bus_slot
*slot_disconnected
;
1607 static int match_disconnected(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1610 log_error("Warning! D-Bus connection terminated.");
1611 sd_bus_close(sd_bus_message_get_bus(m
));
1616 static int match_job_removed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
1617 const char *path
, *unit
, *result
;
1618 BusWaitForJobs
*d
= userdata
;
1626 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1628 bus_log_parse_error(r
);
1632 found
= set_remove(d
->jobs
, (char*) path
);
1638 if (!isempty(result
))
1639 d
->result
= strdup(result
);
1642 d
->name
= strdup(unit
);
1647 void bus_wait_for_jobs_free(BusWaitForJobs
*d
) {
1651 set_free_free(d
->jobs
);
1653 sd_bus_slot_unref(d
->slot_disconnected
);
1654 sd_bus_slot_unref(d
->slot_job_removed
);
1656 sd_bus_unref(d
->bus
);
1664 int bus_wait_for_jobs_new(sd_bus
*bus
, BusWaitForJobs
**ret
) {
1665 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*d
= NULL
;
1671 d
= new0(BusWaitForJobs
, 1);
1675 d
->bus
= sd_bus_ref(bus
);
1677 /* When we are a bus client we match by sender. Direct
1678 * connections OTOH have no initialized sender field, and
1679 * hence we ignore the sender then */
1680 r
= sd_bus_add_match(
1682 &d
->slot_job_removed
,
1685 "sender='org.freedesktop.systemd1',"
1686 "interface='org.freedesktop.systemd1.Manager',"
1687 "member='JobRemoved',"
1688 "path='/org/freedesktop/systemd1'" :
1690 "interface='org.freedesktop.systemd1.Manager',"
1691 "member='JobRemoved',"
1692 "path='/org/freedesktop/systemd1'",
1693 match_job_removed
, d
);
1697 r
= sd_bus_add_match(
1699 &d
->slot_disconnected
,
1701 "sender='org.freedesktop.DBus.Local',"
1702 "interface='org.freedesktop.DBus.Local',"
1703 "member='Disconnected'",
1704 match_disconnected
, d
);
1714 static int bus_process_wait(sd_bus
*bus
) {
1718 r
= sd_bus_process(bus
, NULL
);
1724 r
= sd_bus_wait(bus
, (uint64_t) -1);
1730 static int bus_job_get_service_result(BusWaitForJobs
*d
, char **result
) {
1731 _cleanup_free_
char *dbus_path
= NULL
;
1737 dbus_path
= unit_dbus_path_from_name(d
->name
);
1741 return sd_bus_get_property_string(d
->bus
,
1742 "org.freedesktop.systemd1",
1744 "org.freedesktop.systemd1.Service",
1750 static const struct {
1751 const char *result
, *explanation
;
1752 } explanations
[] = {
1753 { "resources", "a configured resource limit was exceeded" },
1754 { "timeout", "a timeout was exceeded" },
1755 { "exit-code", "the control process exited with error code" },
1756 { "signal", "a fatal signal was delivered to the control process" },
1757 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1758 { "watchdog", "the service failed to send watchdog ping" },
1759 { "start-limit", "start of the service was attempted too often" }
1762 static void log_job_error_with_service_result(const char* service
, const char *result
) {
1763 _cleanup_free_
char *service_shell_quoted
= NULL
;
1767 service_shell_quoted
= shell_maybe_quote(service
);
1769 if (!isempty(result
)) {
1772 for (i
= 0; i
< ELEMENTSOF(explanations
); ++i
)
1773 if (streq(result
, explanations
[i
].result
))
1776 if (i
< ELEMENTSOF(explanations
)) {
1777 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1779 explanations
[i
].explanation
,
1780 strna(service_shell_quoted
));
1786 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1788 strna(service_shell_quoted
));
1791 /* For some results maybe additional explanation is required */
1792 if (streq_ptr(result
, "start-limit"))
1793 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1794 strna(service_shell_quoted
));
1797 static int check_wait_response(BusWaitForJobs
*d
, bool quiet
) {
1803 if (streq(d
->result
, "canceled"))
1804 log_error("Job for %s canceled.", strna(d
->name
));
1805 else if (streq(d
->result
, "timeout"))
1806 log_error("Job for %s timed out.", strna(d
->name
));
1807 else if (streq(d
->result
, "dependency"))
1808 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d
->name
));
1809 else if (streq(d
->result
, "invalid"))
1810 log_error("Job for %s invalid.", strna(d
->name
));
1811 else if (streq(d
->result
, "assert"))
1812 log_error("Assertion failed on job for %s.", strna(d
->name
));
1813 else if (streq(d
->result
, "unsupported"))
1814 log_error("Operation on or unit type of %s not supported on this system.", strna(d
->name
));
1815 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped")) {
1818 _cleanup_free_
char *result
= NULL
;
1820 q
= bus_job_get_service_result(d
, &result
);
1822 log_debug_errno(q
, "Failed to get Result property of service %s: %m", d
->name
);
1824 log_job_error_with_service_result(d
->name
, result
);
1826 log_error("Job failed. See \"journalctl -xe\" for details.");
1830 if (streq(d
->result
, "canceled"))
1832 else if (streq(d
->result
, "timeout"))
1834 else if (streq(d
->result
, "dependency"))
1836 else if (streq(d
->result
, "invalid"))
1838 else if (streq(d
->result
, "assert"))
1840 else if (streq(d
->result
, "unsupported"))
1842 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1848 int bus_wait_for_jobs(BusWaitForJobs
*d
, bool quiet
) {
1853 while (!set_isempty(d
->jobs
)) {
1856 q
= bus_process_wait(d
->bus
);
1858 return log_error_errno(q
, "Failed to wait for response: %m");
1861 q
= check_wait_response(d
, quiet
);
1862 /* Return the first error as it is most likely to be
1864 if (q
< 0 && r
== 0)
1867 log_debug_errno(q
, "Got result %s/%m for job %s", strna(d
->result
), strna(d
->name
));
1880 int bus_wait_for_jobs_add(BusWaitForJobs
*d
, const char *path
) {
1885 r
= set_ensure_allocated(&d
->jobs
, &string_hash_ops
);
1889 return set_put_strdup(d
->jobs
, path
);
1892 int bus_wait_for_jobs_one(BusWaitForJobs
*d
, const char *path
, bool quiet
) {
1895 r
= bus_wait_for_jobs_add(d
, path
);
1899 return bus_wait_for_jobs(d
, quiet
);
1902 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message
*m
, bool quiet
, UnitFileChange
**changes
, unsigned *n_changes
) {
1903 const char *type
, *path
, *source
;
1906 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1908 return bus_log_parse_error(r
);
1910 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1912 if (streq(type
, "symlink"))
1913 log_info("Created symlink from %s to %s.", path
, source
);
1915 log_info("Removed symlink %s.", path
);
1918 r
= unit_file_changes_add(changes
, n_changes
, streq(type
, "symlink") ? UNIT_FILE_SYMLINK
: UNIT_FILE_UNLINK
, path
, source
);
1923 return bus_log_parse_error(r
);
1925 r
= sd_bus_message_exit_container(m
);
1927 return bus_log_parse_error(r
);
1933 * bus_path_encode_unique() - encode unique object path
1934 * @b: bus connection or NULL
1935 * @prefix: object path prefix
1936 * @sender_id: unique-name of client, or NULL
1937 * @external_id: external ID to be chosen by client, or NULL
1938 * @ret_path: storage for encoded object path pointer
1940 * Whenever we provide a bus API that allows clients to create and manage
1941 * server-side objects, we need to provide a unique name for these objects. If
1942 * we let the server choose the name, we suffer from a race condition: If a
1943 * client creates an object asynchronously, it cannot destroy that object until
1944 * it received the method reply. It cannot know the name of the new object,
1945 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1947 * Therefore, many APIs allow the client to choose the unique name for newly
1948 * created objects. There're two problems to solve, though:
1949 * 1) Object names are usually defined via dbus object paths, which are
1950 * usually globally namespaced. Therefore, multiple clients must be able
1951 * to choose unique object names without interference.
1952 * 2) If multiple libraries share the same bus connection, they must be
1953 * able to choose unique object names without interference.
1954 * The first problem is solved easily by prefixing a name with the
1955 * unique-bus-name of a connection. The server side must enforce this and
1956 * reject any other name. The second problem is solved by providing unique
1957 * suffixes from within sd-bus.
1959 * This helper allows clients to create unique object-paths. It uses the
1960 * template '/prefix/sender_id/external_id' and returns the new path in
1961 * @ret_path (must be freed by the caller).
1962 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1963 * NULL, this function allocates a unique suffix via @b (by requesting a new
1964 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1967 * Returns: 0 on success, negative error code on failure.
1969 int bus_path_encode_unique(sd_bus
*b
, const char *prefix
, const char *sender_id
, const char *external_id
, char **ret_path
) {
1970 _cleanup_free_
char *sender_label
= NULL
, *external_label
= NULL
;
1971 char external_buf
[DECIMAL_STR_MAX(uint64_t)], *p
;
1974 assert_return(b
|| (sender_id
&& external_id
), -EINVAL
);
1975 assert_return(object_path_is_valid(prefix
), -EINVAL
);
1976 assert_return(ret_path
, -EINVAL
);
1979 r
= sd_bus_get_unique_name(b
, &sender_id
);
1985 xsprintf(external_buf
, "%"PRIu64
, ++b
->cookie
);
1986 external_id
= external_buf
;
1989 sender_label
= bus_label_escape(sender_id
);
1993 external_label
= bus_label_escape(external_id
);
1994 if (!external_label
)
1997 p
= strjoin(prefix
, "/", sender_label
, "/", external_label
, NULL
);
2006 * bus_path_decode_unique() - decode unique object path
2007 * @path: object path to decode
2008 * @prefix: object path prefix
2009 * @ret_sender: output parameter for sender-id label
2010 * @ret_external: output parameter for external-id label
2012 * This does the reverse of bus_path_encode_unique() (see its description for
2013 * details). Both trailing labels, sender-id and external-id, are unescaped and
2014 * returned in the given output parameters (the caller must free them).
2016 * Note that this function returns 0 if the path does not match the template
2017 * (see bus_path_encode_unique()), 1 if it matched.
2019 * Returns: Negative error code on failure, 0 if the given object path does not
2020 * match the template (return parameters are set to NULL), 1 if it was
2021 * parsed successfully (return parameters contain allocated labels).
2023 int bus_path_decode_unique(const char *path
, const char *prefix
, char **ret_sender
, char **ret_external
) {
2025 char *sender
, *external
;
2027 assert(object_path_is_valid(path
));
2028 assert(object_path_is_valid(prefix
));
2030 assert(ret_external
);
2032 p
= object_path_startswith(path
, prefix
);
2035 *ret_external
= NULL
;
2042 *ret_external
= NULL
;
2046 sender
= bus_label_unescape_n(p
, q
- p
);
2047 external
= bus_label_unescape(q
+ 1);
2048 if (!sender
|| !external
) {
2054 *ret_sender
= sender
;
2055 *ret_external
= external
;
2059 bool is_kdbus_wanted(void) {
2060 _cleanup_free_
char *value
= NULL
;
2063 if (get_proc_cmdline_key("kdbus", NULL
) <= 0) {
2064 r
= get_proc_cmdline_key("kdbus=", &value
);
2065 if (r
<= 0 || parse_boolean(value
) != 1)
2072 bool is_kdbus_available(void) {
2073 _cleanup_close_
int fd
= -1;
2074 struct kdbus_cmd cmd
= { .size
= sizeof(cmd
), .flags
= KDBUS_FLAG_NEGOTIATE
};
2076 if (!is_kdbus_wanted())
2079 fd
= open("/sys/fs/kdbus/control", O_RDWR
| O_CLOEXEC
| O_NONBLOCK
| O_NOCTTY
);
2083 return ioctl(fd
, KDBUS_CMD_BUS_MAKE
, &cmd
) >= 0;