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 mac_smack_apply_label_and_drop_cap_mac_admin(pid_t its_pid, const char *new_label) {
577 if (!mac_smack_use())
580 if (new_label && its_pid > 0)
581 r = mac_smack_apply_pid(its_pid, new_label);
583 k = drop_capability(CAP_MAC_ADMIN);
584 return r < 0 ? r : k;
591 int main(int argc, char *argv[]) {
593 _cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
594 sd_id128_t server_id;
595 int r, in_fd, out_fd;
596 bool got_hello = false;
598 struct ucred ucred = {};
599 _cleanup_free_ char *peersec = NULL;
600 Policy policy_buffer = {}, *policy = NULL;
601 _cleanup_set_free_free_ Set *owned_names = NULL;
604 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
605 log_parse_environment();
608 r = parse_argv(argc, argv);
612 r = sd_listen_fds(0);
614 in_fd = STDIN_FILENO;
615 out_fd = STDOUT_FILENO;
617 in_fd = SD_LISTEN_FDS_START;
618 out_fd = SD_LISTEN_FDS_START;
620 log_error("Illegal number of file descriptors passed");
624 original_uid = getuid();
627 sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
628 sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
631 (void) getpeercred(in_fd, &ucred);
632 (void) getpeersec(in_fd, &peersec);
634 r = mac_smack_apply_label_and_drop_cap_mac_admin(getpid(), peersec);
636 log_warning_errno(r, "Failed to set SMACK label (%s) and drop CAP_MAC_ADMIN: %m", peersec);
639 if (arg_drop_privileges) {
640 const char *user = "systemd-bus-proxy";
644 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
646 log_error_errno(r, "Cannot resolve user name %s: %m", user);
650 r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
655 owned_names = set_new(&string_hash_ops);
663 log_error_errno(r, "Failed to allocate bus: %m");
667 r = sd_bus_set_description(a, "sd-proxy");
669 log_error_errno(r, "Failed to set bus name: %m");
673 r = sd_bus_set_address(a, arg_address);
675 log_error_errno(r, "Failed to set address to connect to: %m");
679 r = sd_bus_negotiate_fds(a, is_unix);
681 log_error_errno(r, "Failed to set FD negotiation: %m");
685 r = sd_bus_negotiate_creds(a, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
687 log_error_errno(r, "Failed to set credential negotiation: %m");
692 a->fake_pids.pid = ucred.pid;
693 a->fake_pids_valid = true;
695 a->fake_creds.uid = ucred.uid;
696 a->fake_creds.euid = UID_INVALID;
697 a->fake_creds.suid = UID_INVALID;
698 a->fake_creds.fsuid = UID_INVALID;
699 a->fake_creds.gid = ucred.gid;
700 a->fake_creds.egid = GID_INVALID;
701 a->fake_creds.sgid = GID_INVALID;
702 a->fake_creds.fsgid = GID_INVALID;
703 a->fake_creds_valid = true;
707 a->fake_label = peersec;
711 a->manual_peer_interface = true;
715 log_error_errno(r, "Failed to start bus client: %m");
719 r = sd_bus_get_bus_id(a, &server_id);
721 log_error_errno(r, "Failed to get server ID: %m");
726 if (!arg_configuration) {
729 r = sd_bus_get_scope(a, &scope);
731 log_error_errno(r, "Couldn't determine bus scope: %m");
735 if (streq(scope, "system"))
736 arg_configuration = strv_new(
737 "/etc/dbus-1/system.conf",
738 "/etc/dbus-1/system.d/",
739 "/etc/dbus-1/system-local.conf",
741 else if (streq(scope, "user"))
742 arg_configuration = strv_new(
743 "/etc/dbus-1/session.conf",
744 "/etc/dbus-1/session.d/",
745 "/etc/dbus-1/session-local.conf",
748 log_error("Unknown scope %s, don't know which policy to load. Refusing.", scope);
752 if (!arg_configuration) {
758 r = policy_load(&policy_buffer, arg_configuration);
760 log_error_errno(r, "Failed to load policy: %m");
764 policy = &policy_buffer;
765 /* policy_dump(policy); */
767 if (ucred.uid == original_uid)
768 log_debug("Permitting access, since bus owner matches bus client.");
769 else if (policy_check_hello(policy, ucred.uid, ucred.gid))
770 log_debug("Permitting access due to XML policy.");
772 r = log_error_errno(EPERM, "Policy denied connection.");
779 log_error_errno(r, "Failed to allocate bus: %m");
783 r = sd_bus_set_fd(b, in_fd, out_fd);
785 log_error_errno(r, "Failed to set fds: %m");
789 r = sd_bus_set_server(b, 1, server_id);
791 log_error_errno(r, "Failed to set server mode: %m");
795 r = sd_bus_negotiate_fds(b, is_unix);
797 log_error_errno(r, "Failed to set FD negotiation: %m");
801 r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
803 log_error_errno(r, "Failed to set credential negotiation: %m");
807 r = sd_bus_set_anonymous(b, true);
809 log_error_errno(r, "Failed to set anonymous authentication: %m");
813 b->manual_peer_interface = true;
817 log_error_errno(r, "Failed to start bus client: %m");
821 r = rename_service(a, b);
823 log_debug_errno(r, "Failed to rename process: %m");
826 _cleanup_free_ char *match = NULL;
829 r = sd_bus_get_unique_name(a, &unique);
831 log_error_errno(r, "Failed to get unique name: %m");
835 match = strjoin("type='signal',"
836 "sender='org.freedesktop.DBus',"
837 "path='/org/freedesktop/DBus',"
838 "interface='org.freedesktop.DBus',"
839 "member='NameOwnerChanged',"
849 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
851 log_error_errno(r, "Failed to add match for NameLost: %m");
856 match = strjoin("type='signal',"
857 "sender='org.freedesktop.DBus',"
858 "path='/org/freedesktop/DBus',"
859 "interface='org.freedesktop.DBus',"
860 "member='NameOwnerChanged',"
870 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
872 log_error_errno(r, "Failed to add match for NameAcquired: %m");
878 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
879 int events_a, events_b, fd;
880 uint64_t timeout_a, timeout_b, t;
881 struct timespec _ts, *ts;
882 struct pollfd *pollfd;
886 /* Read messages from bus, to pass them on to our client */
888 r = sd_bus_process(a, &m);
890 /* treat 'connection reset by peer' as clean exit condition */
891 if (r == -ECONNRESET)
894 log_error_errno(r, "Failed to process bus a: %m");
900 bool processed = false;
902 /* We officially got EOF, let's quit */
903 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
908 k = synthesize_name_acquired(a, b, m);
911 log_error_errno(r, "Failed to synthesize message: %m");
918 k = process_policy(a, b, m, policy, &ucred, owned_names);
921 log_error_errno(r, "Failed to process policy: %m");
930 k = sd_bus_send(b, m, NULL);
932 if (k == -ECONNRESET) {
935 } else if (k == -EPERM && m->reply_cookie > 0) {
936 /* If the peer tries to send a reply and it is rejected with EPERM
937 * by the kernel, we ignore the error. This catches cases where the
938 * original method-call didn't had EXPECT_REPLY set, but the proxy-peer
939 * still sends a reply. This is allowed in dbus1, but not in kdbus. We
940 * don't want to track reply-windows in the proxy, so we simply ignore
941 * EPERM for all replies. The only downside is, that callers are no
942 * longer notified if their replies are dropped. However, this is
943 * equivalent to the caller's timeout to expire, so this should be
944 * acceptable. Nobody sane sends replies without a matching method-call,
945 * so nobody should care. */
949 log_error_errno(r, "Failed to send message to client: %m");
961 /* Read messages from our client, to pass them on to the bus */
962 r = sd_bus_process(b, &m);
964 /* treat 'connection reset by peer' as clean exit condition */
965 if (r == -ECONNRESET)
968 log_error_errno(r, "Failed to process bus b: %m");
974 bool processed = false;
976 /* We officially got EOF, let's quit */
977 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
982 k = process_hello(a, b, m, &got_hello);
985 log_error_errno(r, "Failed to process HELLO: %m");
993 k = bus_proxy_process_driver(a, b, m, policy, &ucred, owned_names);
996 log_error_errno(r, "Failed to process driver calls: %m");
1007 k = process_policy(b, a, m, policy, &ucred, owned_names);
1010 log_error_errno(r, "Failed to process policy: %m");
1019 k = sd_bus_send(a, m, NULL);
1021 if (k == -EREMCHG) {
1022 /* The name database changed since the policy check, hence let's check again */
1024 } else if (k == -ECONNRESET) {
1027 } else if (k == -EPERM && m->reply_cookie > 0) {
1028 /* see above why EPERM is ignored for replies */
1032 log_error_errno(r, "Failed to send message to bus: %m");
1047 fd = sd_bus_get_fd(a);
1049 log_error_errno(r, "Failed to get fd: %m");
1053 events_a = sd_bus_get_events(a);
1055 log_error_errno(r, "Failed to get events mask: %m");
1059 r = sd_bus_get_timeout(a, &timeout_a);
1061 log_error_errno(r, "Failed to get timeout: %m");
1065 events_b = sd_bus_get_events(b);
1067 log_error_errno(r, "Failed to get events mask: %m");
1071 r = sd_bus_get_timeout(b, &timeout_b);
1073 log_error_errno(r, "Failed to get timeout: %m");
1078 if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
1081 if (t == (uint64_t) -1)
1086 nw = now(CLOCK_MONOTONIC);
1092 ts = timespec_store(&_ts, t);
1095 pollfd = (struct pollfd[3]) {
1096 {.fd = fd, .events = events_a, },
1097 {.fd = in_fd, .events = events_b & POLLIN, },
1098 {.fd = out_fd, .events = events_b & POLLOUT, }
1101 r = ppoll(pollfd, 3, ts, NULL);
1103 log_error_errno(errno, "ppoll() failed: %m");
1111 "STATUS=Shutting down.");
1113 policy_free(&policy_buffer);
1114 strv_free(arg_configuration);
1117 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;