1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Daniel Mack
8 Copyright 2014 Kay Sievers
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/socket.h>
26 #include <sys/types.h>
37 #include "socket-util.h"
38 #include "sd-daemon.h"
40 #include "bus-internal.h"
41 #include "bus-message.h"
46 #include "capability.h"
47 #include "bus-control.h"
48 #include "smack-util.h"
50 #include "bus-xml-policy.h"
52 #include "synthesize.h"
54 static char *arg_address = NULL;
55 static char *arg_command_line_buffer = NULL;
56 static bool arg_drop_privileges = false;
57 static char **arg_configuration = NULL;
59 static int help(void) {
61 printf("%s [OPTIONS...]\n\n"
62 "Connect STDIO or a socket to a given bus address.\n\n"
63 " -h --help Show this help\n"
64 " --version Show package version\n"
65 " --drop-privileges Drop privileges\n"
66 " --configuration=PATH Configuration file or directory\n"
67 " --machine=MACHINE Connect to specified machine\n"
68 " --address=ADDRESS Connect to the bus specified by ADDRESS\n"
69 " (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
70 program_invocation_short_name);
75 static int parse_argv(int argc, char *argv[]) {
85 static const struct option options[] = {
86 { "help", no_argument, NULL, 'h' },
87 { "version", no_argument, NULL, ARG_VERSION },
88 { "address", required_argument, NULL, ARG_ADDRESS },
89 { "drop-privileges", no_argument, NULL, ARG_DROP_PRIVILEGES },
90 { "configuration", required_argument, NULL, ARG_CONFIGURATION },
91 { "machine", required_argument, NULL, ARG_MACHINE },
100 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
109 puts(PACKAGE_STRING);
110 puts(SYSTEMD_FEATURES);
125 case ARG_DROP_PRIVILEGES:
126 arg_drop_privileges = true;
129 case ARG_CONFIGURATION:
130 r = strv_extend(&arg_configuration, optarg);
136 _cleanup_free_ char *e = NULL;
139 e = bus_address_escape(optarg);
144 a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
146 a = strjoin("x-machine-unix:machine=", e, NULL);
161 assert_not_reached("Unhandled option");
164 /* If the first command line argument is only "x" characters
165 * we'll write who we are talking to into it, so that "ps" is
167 arg_command_line_buffer = argv[optind];
168 if (argc > optind + 1 || (arg_command_line_buffer && !in_charset(arg_command_line_buffer, "x"))) {
169 log_error("Too many arguments");
174 arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
182 static int rename_service(sd_bus *a, sd_bus *b) {
183 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
184 _cleanup_free_ char *p = NULL, *name = NULL;
194 r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds);
198 r = sd_bus_creds_get_uid(creds, &uid);
202 r = sd_bus_creds_get_pid(creds, &pid);
206 r = sd_bus_creds_get_cmdline(creds, &cmdline);
210 r = sd_bus_creds_get_comm(creds, &comm);
214 name = uid_to_name(uid);
218 p = strv_join(cmdline, " ");
222 /* The status string gets the full command line ... */
224 "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)",
228 /* ... and the argv line only the short comm */
229 if (arg_command_line_buffer) {
232 m = strlen(arg_command_line_buffer);
233 w = snprintf(arg_command_line_buffer, m,
234 "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]",
239 memzero(arg_command_line_buffer + w, m - w);
242 log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
250 static int handle_policy_error(sd_bus_message *m, int r) {
251 if (r == -ESRCH || r == -ENXIO)
252 return synthetic_reply_method_errorf(m, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", m->destination);
257 static int process_policy(sd_bus *from, sd_bus *to, sd_bus_message *m, Policy *policy, const struct ucred *our_ucred, Set *owned_names) {
268 * dbus-1 distinguishes expected and non-expected replies by tracking
269 * method-calls and timeouts. By default, DENY rules are *NEVER* applied
270 * on expected replies, unless explicitly specified. But we dont track
271 * method-calls, thus, we cannot know whether a reply is expected.
272 * Fortunately, the kdbus forbids non-expected replies, so we can safely
273 * ignore any policy on those and let the kernel deal with it.
275 * TODO: To be correct, we should only ignore policy-tags that are
276 * applied on non-expected replies. However, so far we don't parse those
277 * tags so we let everything pass. I haven't seen a DENY policy tag on
278 * expected-replies, ever, so don't bother..
280 if (m->reply_cookie > 0)
283 if (from->is_kernel) {
284 uid_t sender_uid = UID_INVALID;
285 gid_t sender_gid = GID_INVALID;
286 char **sender_names = NULL;
287 bool granted = false;
289 /* Driver messages are always OK */
290 if (streq_ptr(m->sender, "org.freedesktop.DBus"))
293 /* The message came from the kernel, and is sent to our legacy client. */
294 sd_bus_creds_get_well_known_names(&m->creds, &sender_names);
296 (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
297 (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
299 if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
300 _cleanup_bus_creds_unref_ sd_bus_creds *sender_creds = NULL;
302 /* If the message came from another legacy
303 * client, then the message creds will be
304 * missing, simply because on legacy clients
305 * per-message creds were unknown. In this
306 * case, query the creds of the peer
309 r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_UID|SD_BUS_CREDS_GID, true, &sender_creds);
311 return handle_policy_error(m, r);
313 (void) sd_bus_creds_get_uid(sender_creds, &sender_uid);
314 (void) sd_bus_creds_get_gid(sender_creds, &sender_gid);
317 /* First check whether the sender can send the message to our name */
318 if (set_isempty(owned_names)) {
319 if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, NULL, m->path, m->interface, m->member, false))
325 SET_FOREACH(n, owned_names, i)
326 if (policy_check_send(policy, sender_uid, sender_gid, m->header->type, n, m->path, m->interface, m->member, false)) {
333 /* Then check whether us (the recipient) can receive from the sender's name */
334 if (strv_isempty(sender_names)) {
335 if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member, false))
340 STRV_FOREACH(n, sender_names) {
341 if (policy_check_recv(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member, false))
347 /* Return an error back to the caller */
348 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
349 return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML receiver policy.");
351 /* Return 1, indicating that the message shall not be processed any further */
356 _cleanup_bus_creds_unref_ sd_bus_creds *destination_creds = NULL;
357 uid_t destination_uid = UID_INVALID;
358 gid_t destination_gid = GID_INVALID;
359 const char *destination_unique = NULL;
360 char **destination_names = NULL;
361 bool granted = false;
363 /* Driver messages are always OK */
364 if (streq_ptr(m->destination, "org.freedesktop.DBus"))
367 /* The message came from the legacy client, and is sent to kdbus. */
368 if (m->destination) {
369 r = bus_get_name_creds_kdbus(to, m->destination,
370 SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME|
371 SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID,
372 true, &destination_creds);
374 return handle_policy_error(m, r);
376 r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
378 return handle_policy_error(m, r);
380 sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
382 (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
383 (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
386 /* First check if we (the sender) can send to this name */
387 if (strv_isempty(destination_names)) {
388 if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, m->path, m->interface, m->member, true))
393 STRV_FOREACH(n, destination_names) {
394 if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, *n, m->path, m->interface, m->member, true)) {
396 /* If we made a receiver decision,
397 then remember which name's policy
398 we used, and to which unique ID it
399 mapped when we made the
400 decision. Then, let's pass this to
401 the kernel when sending the
402 message, so that it refuses the
403 operation should the name and
404 unique ID not map to each other
407 r = free_and_strdup(&m->destination_ptr, *n);
411 r = bus_kernel_parse_unique_name(destination_unique, &m->verify_destination_id);
421 /* Then check if the recipient can receive from our name */
423 if (sd_bus_message_is_signal(m, NULL, NULL)) {
424 /* If we forward a signal from dbus-1 to kdbus,
425 * we have no idea who the recipient is.
426 * Therefore, we cannot apply any dbus-1
427 * receiver policies that match on receiver
428 * credentials. We know sd-bus always sets
429 * KDBUS_MSG_SIGNAL, so the kernel applies
430 * receiver policies to the message. Therefore,
431 * skip policy checks in this case. */
433 } else if (set_isempty(owned_names)) {
434 if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, NULL, m->path, m->interface, m->member, true))
440 SET_FOREACH(n, owned_names, i)
441 if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, n, m->path, m->interface, m->member, true))
446 /* Return an error back to the caller */
447 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
448 return synthetic_reply_method_errorf(m, SD_BUS_ERROR_ACCESS_DENIED, "Access prohibited by XML sender policy.");
450 /* Return 1, indicating that the message shall not be processed any further */
457 static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hello) {
458 _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
467 /* As reaction to hello we need to respond with two messages:
468 * the callback reply and the NameAcquired for the unique
469 * name, since hello is otherwise obsolete on kdbus. */
472 sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "Hello") &&
473 streq_ptr(m->destination, "org.freedesktop.DBus");
480 log_error("First packet isn't hello (it's %s.%s), aborting.", m->interface, m->member);
485 log_error("Got duplicate hello, aborting.");
494 r = sd_bus_message_new_method_return(m, &n);
496 return log_error_errno(r, "Failed to generate HELLO reply: %m");
498 r = sd_bus_message_append(n, "s", a->unique_name);
500 return log_error_errno(r, "Failed to append unique name to HELLO reply: %m");
502 r = bus_message_append_sender(n, "org.freedesktop.DBus");
504 return log_error_errno(r, "Failed to append sender to HELLO reply: %m");
506 r = bus_seal_synthetic_message(b, n);
508 return log_error_errno(r, "Failed to seal HELLO reply: %m");
510 r = sd_bus_send(b, n, NULL);
512 return log_error_errno(r, "Failed to send HELLO reply: %m");
514 n = sd_bus_message_unref(n);
515 r = sd_bus_message_new_signal(
518 "/org/freedesktop/DBus",
519 "org.freedesktop.DBus",
522 return log_error_errno(r, "Failed to allocate initial NameAcquired message: %m");
524 r = sd_bus_message_append(n, "s", a->unique_name);
526 return log_error_errno(r, "Failed to append unique name to NameAcquired message: %m");
528 r = bus_message_append_sender(n, "org.freedesktop.DBus");
530 return log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
532 r = bus_seal_synthetic_message(b, n);
534 return log_error_errno(r, "Failed to seal NameAcquired message: %m");
536 r = sd_bus_send(b, n, NULL);
538 return log_error_errno(r, "Failed to send NameAcquired message: %m");
543 static int patch_sender(sd_bus *a, sd_bus_message *m) {
544 char **well_known = NULL;
554 /* We will change the sender of messages from the bus driver
555 * so that they originate from the bus driver. This is a
556 * speciality originating from dbus1, where the bus driver did
557 * not have a unique id, but only the well-known name. */
559 c = sd_bus_message_get_creds(m);
563 r = sd_bus_creds_get_well_known_names(c, &well_known);
567 if (strv_contains(well_known, "org.freedesktop.DBus"))
568 m->sender = "org.freedesktop.DBus";
573 static int bus_new_destination(sd_bus **out, struct ucred *ucred, const char *peersec, bool negotiate_fds) {
574 _cleanup_bus_close_unref_ sd_bus *a = NULL;
579 return log_error_errno(r, "Failed to allocate bus: %m");
581 r = sd_bus_set_description(a, "sd-proxy");
583 return log_error_errno(r, "Failed to set bus name: %m");
585 r = sd_bus_set_address(a, arg_address);
587 return log_error_errno(r, "Failed to set address to connect to: %m");
589 r = sd_bus_negotiate_fds(a, negotiate_fds);
591 return log_error_errno(r, "Failed to set FD negotiation: %m");
593 r = sd_bus_negotiate_creds(a, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
595 return log_error_errno(r, "Failed to set credential negotiation: %m");
597 if (ucred->pid > 0) {
598 a->fake_pids.pid = ucred->pid;
599 a->fake_pids_valid = true;
601 a->fake_creds.uid = ucred->uid;
602 a->fake_creds.euid = UID_INVALID;
603 a->fake_creds.suid = UID_INVALID;
604 a->fake_creds.fsuid = UID_INVALID;
605 a->fake_creds.gid = ucred->gid;
606 a->fake_creds.egid = GID_INVALID;
607 a->fake_creds.sgid = GID_INVALID;
608 a->fake_creds.fsgid = GID_INVALID;
609 a->fake_creds_valid = true;
613 a->fake_label = strdup(peersec);
618 a->manual_peer_interface = true;
622 return log_error_errno(r, "Failed to start bus client: %m");
629 static int bus_new_local(sd_bus **out, sd_bus *dest, int in_fd, int out_fd, bool negotiate_fds) {
630 _cleanup_bus_close_unref_ sd_bus *b = NULL;
631 sd_id128_t server_id;
636 return log_error_errno(r, "Failed to allocate bus: %m");
638 r = sd_bus_set_fd(b, in_fd, out_fd);
640 return log_error_errno(r, "Failed to set fds: %m");
642 r = sd_bus_get_bus_id(dest, &server_id);
644 return log_error_errno(r, "Failed to get server ID: %m");
646 r = sd_bus_set_server(b, 1, server_id);
648 return log_error_errno(r, "Failed to set server mode: %m");
650 r = sd_bus_negotiate_fds(b, negotiate_fds);
652 return log_error_errno(r, "Failed to set FD negotiation: %m");
654 r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
656 return log_error_errno(r, "Failed to set credential negotiation: %m");
658 r = sd_bus_set_anonymous(b, true);
660 return log_error_errno(r, "Failed to set anonymous authentication: %m");
662 b->manual_peer_interface = true;
666 return log_error_errno(r, "Failed to start bus client: %m");
673 static int mac_smack_apply_label_and_drop_cap_mac_admin(pid_t its_pid, const char *new_label) {
677 if (!mac_smack_use())
680 if (new_label && its_pid > 0)
681 r = mac_smack_apply_pid(its_pid, new_label);
683 k = drop_capability(CAP_MAC_ADMIN);
684 return r < 0 ? r : k;
691 int main(int argc, char *argv[]) {
693 _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
694 int r, in_fd, out_fd;
695 bool got_hello = false;
697 struct ucred ucred = {};
698 _cleanup_free_ char *peersec = NULL;
699 Policy policy_buffer = {}, *policy = NULL;
700 _cleanup_set_free_free_ Set *owned_names = NULL;
703 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
704 log_parse_environment();
707 r = parse_argv(argc, argv);
711 r = sd_listen_fds(0);
713 in_fd = STDIN_FILENO;
714 out_fd = STDOUT_FILENO;
716 in_fd = SD_LISTEN_FDS_START;
717 out_fd = SD_LISTEN_FDS_START;
719 log_error("Illegal number of file descriptors passed");
723 original_uid = getuid();
726 sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
727 sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
730 (void) getpeercred(in_fd, &ucred);
731 (void) getpeersec(in_fd, &peersec);
733 r = mac_smack_apply_label_and_drop_cap_mac_admin(getpid(), peersec);
735 log_warning_errno(r, "Failed to set SMACK label (%s) and drop CAP_MAC_ADMIN: %m", peersec);
738 if (arg_drop_privileges) {
739 const char *user = "systemd-bus-proxy";
743 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
745 log_error_errno(r, "Cannot resolve user name %s: %m", user);
749 r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
754 owned_names = set_new(&string_hash_ops);
760 r = bus_new_destination(&a, &ucred, peersec, is_unix);
765 if (!arg_configuration) {
768 r = sd_bus_get_scope(a, &scope);
770 log_error_errno(r, "Couldn't determine bus scope: %m");
774 if (streq(scope, "system"))
775 arg_configuration = strv_new(
776 "/etc/dbus-1/system.conf",
777 "/etc/dbus-1/system.d/",
778 "/etc/dbus-1/system-local.conf",
780 else if (streq(scope, "user"))
781 arg_configuration = strv_new(
782 "/etc/dbus-1/session.conf",
783 "/etc/dbus-1/session.d/",
784 "/etc/dbus-1/session-local.conf",
787 log_error("Unknown scope %s, don't know which policy to load. Refusing.", scope);
791 if (!arg_configuration) {
797 r = policy_load(&policy_buffer, arg_configuration);
799 log_error_errno(r, "Failed to load policy: %m");
803 policy = &policy_buffer;
804 /* policy_dump(policy); */
806 if (ucred.uid == original_uid)
807 log_debug("Permitting access, since bus owner matches bus client.");
808 else if (policy_check_hello(policy, ucred.uid, ucred.gid))
809 log_debug("Permitting access due to XML policy.");
811 r = log_error_errno(EPERM, "Policy denied connection.");
816 r = bus_new_local(&b, a, in_fd, out_fd, is_unix);
820 r = rename_service(a, b);
822 log_debug_errno(r, "Failed to rename process: %m");
825 _cleanup_free_ char *match = NULL;
828 r = sd_bus_get_unique_name(a, &unique);
830 log_error_errno(r, "Failed to get unique name: %m");
834 match = strjoin("type='signal',"
835 "sender='org.freedesktop.DBus',"
836 "path='/org/freedesktop/DBus',"
837 "interface='org.freedesktop.DBus',"
838 "member='NameOwnerChanged',"
848 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
850 log_error_errno(r, "Failed to add match for NameLost: %m");
855 match = strjoin("type='signal',"
856 "sender='org.freedesktop.DBus',"
857 "path='/org/freedesktop/DBus',"
858 "interface='org.freedesktop.DBus',"
859 "member='NameOwnerChanged',"
869 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
871 log_error_errno(r, "Failed to add match for NameAcquired: %m");
877 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
878 int events_a, events_b, fd;
879 uint64_t timeout_a, timeout_b, t;
880 struct timespec _ts, *ts;
881 struct pollfd *pollfd;
885 /* Read messages from bus, to pass them on to our client */
887 r = sd_bus_process(a, &m);
889 /* treat 'connection reset by peer' as clean exit condition */
890 if (r == -ECONNRESET)
893 log_error_errno(r, "Failed to process bus a: %m");
899 bool processed = false;
901 /* We officially got EOF, let's quit */
902 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
907 k = synthesize_name_acquired(a, b, m);
910 log_error_errno(r, "Failed to synthesize message: %m");
917 k = process_policy(a, b, m, policy, &ucred, owned_names);
920 log_error_errno(r, "Failed to process policy: %m");
929 k = sd_bus_send(b, m, NULL);
931 if (k == -ECONNRESET) {
934 } else if (k == -EPERM && m->reply_cookie > 0) {
935 /* If the peer tries to send a reply and it is rejected with EPERM
936 * by the kernel, we ignore the error. This catches cases where the
937 * original method-call didn't had EXPECT_REPLY set, but the proxy-peer
938 * still sends a reply. This is allowed in dbus1, but not in kdbus. We
939 * don't want to track reply-windows in the proxy, so we simply ignore
940 * EPERM for all replies. The only downside is, that callers are no
941 * longer notified if their replies are dropped. However, this is
942 * equivalent to the caller's timeout to expire, so this should be
943 * acceptable. Nobody sane sends replies without a matching method-call,
944 * so nobody should care. */
948 log_error_errno(r, "Failed to send message to client: %m");
960 /* Read messages from our client, to pass them on to the bus */
961 r = sd_bus_process(b, &m);
963 /* treat 'connection reset by peer' as clean exit condition */
964 if (r == -ECONNRESET)
967 log_error_errno(r, "Failed to process bus b: %m");
973 bool processed = false;
975 /* We officially got EOF, let's quit */
976 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
981 k = process_hello(a, b, m, &got_hello);
984 log_error_errno(r, "Failed to process HELLO: %m");
992 k = bus_proxy_process_driver(a, b, m, policy, &ucred, owned_names);
995 log_error_errno(r, "Failed to process driver calls: %m");
1006 k = process_policy(b, a, m, policy, &ucred, owned_names);
1009 log_error_errno(r, "Failed to process policy: %m");
1018 k = sd_bus_send(a, m, NULL);
1020 if (k == -EREMCHG) {
1021 /* The name database changed since the policy check, hence let's check again */
1023 } else if (k == -ECONNRESET) {
1026 } else if (k == -EPERM && m->reply_cookie > 0) {
1027 /* see above why EPERM is ignored for replies */
1031 log_error_errno(r, "Failed to send message to bus: %m");
1046 fd = sd_bus_get_fd(a);
1048 log_error_errno(r, "Failed to get fd: %m");
1052 events_a = sd_bus_get_events(a);
1054 log_error_errno(r, "Failed to get events mask: %m");
1058 r = sd_bus_get_timeout(a, &timeout_a);
1060 log_error_errno(r, "Failed to get timeout: %m");
1064 events_b = sd_bus_get_events(b);
1066 log_error_errno(r, "Failed to get events mask: %m");
1070 r = sd_bus_get_timeout(b, &timeout_b);
1072 log_error_errno(r, "Failed to get timeout: %m");
1077 if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
1080 if (t == (uint64_t) -1)
1085 nw = now(CLOCK_MONOTONIC);
1091 ts = timespec_store(&_ts, t);
1094 pollfd = (struct pollfd[3]) {
1095 {.fd = fd, .events = events_a, },
1096 {.fd = in_fd, .events = events_b & POLLIN, },
1097 {.fd = out_fd, .events = events_b & POLLOUT, }
1100 r = ppoll(pollfd, 3, ts, NULL);
1102 log_error_errno(errno, "ppoll() failed: %m");
1110 "STATUS=Shutting down.");
1112 policy_free(&policy_buffer);
1113 strv_free(arg_configuration);
1116 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;