chiark / gitweb /
13b27b4322533d11fa099fa3a678af2b62d6be64
[elogind.git] / src / bus-proxyd / bus-proxyd.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7   Copyright 2013 Daniel Mack
8   Copyright 2014 Kay Sievers
9
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.
14
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.
19
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/>.
22 ***/
23
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/types.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <sys/poll.h>
32 #include <stddef.h>
33 #include <getopt.h>
34
35 #include "log.h"
36 #include "util.h"
37 #include "socket-util.h"
38 #include "sd-daemon.h"
39 #include "sd-bus.h"
40 #include "bus-internal.h"
41 #include "bus-message.h"
42 #include "bus-util.h"
43 #include "build.h"
44 #include "strv.h"
45 #include "def.h"
46 #include "capability.h"
47 #include "bus-control.h"
48 #include "smack-util.h"
49 #include "set.h"
50 #include "bus-xml-policy.h"
51 #include "driver.h"
52 #include "synthesize.h"
53
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;
58
59 static int help(void) {
60
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);
71
72         return 0;
73 }
74
75 static int parse_argv(int argc, char *argv[]) {
76
77         enum {
78                 ARG_VERSION = 0x100,
79                 ARG_ADDRESS,
80                 ARG_DROP_PRIVILEGES,
81                 ARG_CONFIGURATION,
82                 ARG_MACHINE,
83         };
84
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         },
92                 {},
93         };
94
95         int c, r;
96
97         assert(argc >= 0);
98         assert(argv);
99
100         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
101
102                 switch (c) {
103
104                 case 'h':
105                         help();
106                         return 0;
107
108                 case ARG_VERSION:
109                         puts(PACKAGE_STRING);
110                         puts(SYSTEMD_FEATURES);
111                         return 0;
112
113                 case ARG_ADDRESS: {
114                         char *a;
115
116                         a = strdup(optarg);
117                         if (!a)
118                                 return log_oom();
119
120                         free(arg_address);
121                         arg_address = a;
122                         break;
123                 }
124
125                 case ARG_DROP_PRIVILEGES:
126                         arg_drop_privileges = true;
127                         break;
128
129                 case ARG_CONFIGURATION:
130                         r = strv_extend(&arg_configuration, optarg);
131                         if (r < 0)
132                                 return log_oom();
133                         break;
134
135                 case ARG_MACHINE: {
136                         _cleanup_free_ char *e = NULL;
137                         char *a;
138
139                         e = bus_address_escape(optarg);
140                         if (!e)
141                                 return log_oom();
142
143 #ifdef ENABLE_KDBUS
144                         a = strjoin("x-machine-kernel:machine=", e, ";x-machine-unix:machine=", e, NULL);
145 #else
146                         a = strjoin("x-machine-unix:machine=", e, NULL);
147 #endif
148                         if (!a)
149                                 return log_oom();
150
151                         free(arg_address);
152                         arg_address = a;
153
154                         break;
155                 }
156
157                 case '?':
158                         return -EINVAL;
159
160                 default:
161                         assert_not_reached("Unhandled option");
162                 }
163
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
166          * explanatory */
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");
170                 return -EINVAL;
171         }
172
173         if (!arg_address) {
174                 arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
175                 if (!arg_address)
176                         return log_oom();
177         }
178
179         return 1;
180 }
181
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;
185         const char *comm;
186         char **cmdline;
187         uid_t uid;
188         pid_t pid;
189         int r;
190
191         assert(a);
192         assert(b);
193
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);
195         if (r < 0)
196                 return r;
197
198         r = sd_bus_creds_get_uid(creds, &uid);
199         if (r < 0)
200                 return r;
201
202         r = sd_bus_creds_get_pid(creds, &pid);
203         if (r < 0)
204                 return r;
205
206         r = sd_bus_creds_get_cmdline(creds, &cmdline);
207         if (r < 0)
208                 return r;
209
210         r = sd_bus_creds_get_comm(creds, &comm);
211         if (r < 0)
212                 return r;
213
214         name = uid_to_name(uid);
215         if (!name)
216                 return -ENOMEM;
217
218         p = strv_join(cmdline, " ");
219         if (!p)
220                 return -ENOMEM;
221
222         /* The status string gets the full command line ... */
223         sd_notifyf(false,
224                    "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)",
225                    pid, p,
226                    uid, name);
227
228         /* ... and the argv line only the short comm */
229         if (arg_command_line_buffer) {
230                 size_t m, w;
231
232                 m = strlen(arg_command_line_buffer);
233                 w = snprintf(arg_command_line_buffer, m,
234                              "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]",
235                              pid, comm,
236                              uid, name);
237
238                 if (m > w)
239                         memzero(arg_command_line_buffer + w, m - w);
240         }
241
242         log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s",
243                   pid, p,
244                   uid, name,
245                   a->unique_name);
246
247         return 0;
248 }
249
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);
253
254         return r;
255 }
256
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) {
258         int r;
259
260         assert(from);
261         assert(to);
262         assert(m);
263
264         if (!policy)
265                 return 0;
266
267         /*
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.
274          *
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..
279          */
280         if (m->reply_cookie > 0)
281                 return 0;
282
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;
288
289                 /* Driver messages are always OK */
290                 if (streq_ptr(m->sender, "org.freedesktop.DBus"))
291                         return 0;
292
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);
295
296                 (void) sd_bus_creds_get_uid(&m->creds, &sender_uid);
297                 (void) sd_bus_creds_get_gid(&m->creds, &sender_gid);
298
299                 if (sender_uid == UID_INVALID || sender_gid == GID_INVALID) {
300                         _cleanup_bus_creds_unref_ sd_bus_creds *sender_creds = NULL;
301
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
307                          * instead. */
308
309                         r = bus_get_name_creds_kdbus(from, m->sender, SD_BUS_CREDS_UID|SD_BUS_CREDS_GID, true, &sender_creds);
310                         if (r < 0)
311                                 return handle_policy_error(m, r);
312
313                         (void) sd_bus_creds_get_uid(sender_creds, &sender_uid);
314                         (void) sd_bus_creds_get_gid(sender_creds, &sender_gid);
315                 }
316
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))
320                                 granted = true;
321                 } else {
322                         Iterator i;
323                         char *n;
324
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)) {
327                                         granted = true;
328                                         break;
329                                 }
330                 }
331
332                 if (granted) {
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))
336                                         return 0;
337                         } else {
338                                 char **n;
339
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))
342                                                 return 0;
343                                 }
344                         }
345                 }
346
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.");
350
351                 /* Return 1, indicating that the message shall not be processed any further */
352                 return 1;
353         }
354
355         if (to->is_kernel) {
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;
362
363                 /* Driver messages are always OK */
364                 if (streq_ptr(m->destination, "org.freedesktop.DBus"))
365                         return 0;
366
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);
373                         if (r < 0)
374                                 return handle_policy_error(m, r);
375
376                         r = sd_bus_creds_get_unique_name(destination_creds, &destination_unique);
377                         if (r < 0)
378                                 return handle_policy_error(m, r);
379
380                         sd_bus_creds_get_well_known_names(destination_creds, &destination_names);
381
382                         (void) sd_bus_creds_get_uid(destination_creds, &destination_uid);
383                         (void) sd_bus_creds_get_gid(destination_creds, &destination_gid);
384                 }
385
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))
389                                 granted = true;
390                 } else {
391                         char **n;
392
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)) {
395
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
405                                            anymore. */
406
407                                         r = free_and_strdup(&m->destination_ptr, *n);
408                                         if (r < 0)
409                                                 return r;
410
411                                         r = bus_kernel_parse_unique_name(destination_unique, &m->verify_destination_id);
412                                         if (r < 0)
413                                                 break;
414
415                                         granted = true;
416                                         break;
417                                 }
418                         }
419                 }
420
421                 /* Then check if the recipient can receive from our name */
422                 if (granted) {
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. */
432                                 return 0;
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))
435                                         return 0;
436                         } else {
437                                 Iterator i;
438                                 char *n;
439
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))
442                                                 return 0;
443                         }
444                 }
445
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.");
449
450                 /* Return 1, indicating that the message shall not be processed any further */
451                 return 1;
452         }
453
454         return 0;
455 }
456
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;
459         bool is_hello;
460         int r;
461
462         assert(a);
463         assert(b);
464         assert(m);
465         assert(got_hello);
466
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. */
470
471         is_hello =
472                 sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "Hello") &&
473                 streq_ptr(m->destination, "org.freedesktop.DBus");
474
475         if (!is_hello) {
476
477                 if (*got_hello)
478                         return 0;
479
480                 log_error("First packet isn't hello (it's %s.%s), aborting.", m->interface, m->member);
481                 return -EIO;
482         }
483
484         if (*got_hello) {
485                 log_error("Got duplicate hello, aborting.");
486                 return -EIO;
487         }
488
489         *got_hello = true;
490
491         if (!a->is_kernel)
492                 return 0;
493
494         r = sd_bus_message_new_method_return(m, &n);
495         if (r < 0)
496                 return log_error_errno(r, "Failed to generate HELLO reply: %m");
497
498         r = sd_bus_message_append(n, "s", a->unique_name);
499         if (r < 0)
500                 return log_error_errno(r, "Failed to append unique name to HELLO reply: %m");
501
502         r = bus_message_append_sender(n, "org.freedesktop.DBus");
503         if (r < 0)
504                 return log_error_errno(r, "Failed to append sender to HELLO reply: %m");
505
506         r = bus_seal_synthetic_message(b, n);
507         if (r < 0)
508                 return log_error_errno(r, "Failed to seal HELLO reply: %m");
509
510         r = sd_bus_send(b, n, NULL);
511         if (r < 0)
512                 return log_error_errno(r, "Failed to send HELLO reply: %m");
513
514         n = sd_bus_message_unref(n);
515         r = sd_bus_message_new_signal(
516                         b,
517                         &n,
518                         "/org/freedesktop/DBus",
519                         "org.freedesktop.DBus",
520                         "NameAcquired");
521         if (r < 0)
522                 return log_error_errno(r, "Failed to allocate initial NameAcquired message: %m");
523
524         r = sd_bus_message_append(n, "s", a->unique_name);
525         if (r < 0)
526                 return log_error_errno(r, "Failed to append unique name to NameAcquired message: %m");
527
528         r = bus_message_append_sender(n, "org.freedesktop.DBus");
529         if (r < 0)
530                 return log_error_errno(r, "Failed to append sender to NameAcquired message: %m");
531
532         r = bus_seal_synthetic_message(b, n);
533         if (r < 0)
534                 return log_error_errno(r, "Failed to seal NameAcquired message: %m");
535
536         r = sd_bus_send(b, n, NULL);
537         if (r < 0)
538                 return log_error_errno(r, "Failed to send NameAcquired message: %m");
539
540         return 1;
541 }
542
543 static int patch_sender(sd_bus *a, sd_bus_message *m) {
544         char **well_known = NULL;
545         sd_bus_creds *c;
546         int r;
547
548         assert(a);
549         assert(m);
550
551         if (!a->is_kernel)
552                 return 0;
553
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. */
558
559         c = sd_bus_message_get_creds(m);
560         if (!c)
561                 return 0;
562
563         r = sd_bus_creds_get_well_known_names(c, &well_known);
564         if (r < 0)
565                 return r;
566
567         if (strv_contains(well_known, "org.freedesktop.DBus"))
568                 m->sender = "org.freedesktop.DBus";
569
570         return 0;
571 }
572
573 static int mac_smack_apply_label_and_drop_cap_mac_admin(pid_t its_pid, const char *new_label) {
574 #ifdef HAVE_SMACK
575         int r = 0, k;
576
577         if (!mac_smack_use())
578                 return 0;
579
580         if (new_label && its_pid > 0)
581                 r = mac_smack_apply_pid(its_pid, new_label);
582
583         k = drop_capability(CAP_MAC_ADMIN);
584         return r < 0 ? r : k;
585 #else
586         return 0;
587 #endif
588 }
589
590
591 int main(int argc, char *argv[]) {
592
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;
597         bool is_unix;
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;
602         uid_t original_uid;
603
604         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
605         log_parse_environment();
606         log_open();
607
608         r = parse_argv(argc, argv);
609         if (r <= 0)
610                 goto finish;
611
612         r = sd_listen_fds(0);
613         if (r == 0) {
614                 in_fd = STDIN_FILENO;
615                 out_fd = STDOUT_FILENO;
616         } else if (r == 1) {
617                 in_fd = SD_LISTEN_FDS_START;
618                 out_fd = SD_LISTEN_FDS_START;
619         } else {
620                 log_error("Illegal number of file descriptors passed");
621                 goto finish;
622         }
623
624         original_uid = getuid();
625
626         is_unix =
627                 sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
628                 sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
629
630         if (is_unix) {
631                 (void) getpeercred(in_fd, &ucred);
632                 (void) getpeersec(in_fd, &peersec);
633
634                 r = mac_smack_apply_label_and_drop_cap_mac_admin(getpid(), peersec);
635                 if (r < 0)
636                         log_warning_errno(r, "Failed to set SMACK label (%s) and drop CAP_MAC_ADMIN: %m", peersec);
637         }
638
639         if (arg_drop_privileges) {
640                 const char *user = "systemd-bus-proxy";
641                 uid_t uid;
642                 gid_t gid;
643
644                 r = get_user_creds(&user, &uid, &gid, NULL, NULL);
645                 if (r < 0) {
646                         log_error_errno(r, "Cannot resolve user name %s: %m", user);
647                         goto finish;
648                 }
649
650                 r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
651                 if (r < 0)
652                         goto finish;
653         }
654
655         owned_names = set_new(&string_hash_ops);
656         if (!owned_names) {
657                 log_oom();
658                 goto finish;
659         }
660
661         r = sd_bus_new(&a);
662         if (r < 0) {
663                 log_error_errno(r, "Failed to allocate bus: %m");
664                 goto finish;
665         }
666
667         r = sd_bus_set_description(a, "sd-proxy");
668         if (r < 0) {
669                 log_error_errno(r, "Failed to set bus name: %m");
670                 goto finish;
671         }
672
673         r = sd_bus_set_address(a, arg_address);
674         if (r < 0) {
675                 log_error_errno(r, "Failed to set address to connect to: %m");
676                 goto finish;
677         }
678
679         r = sd_bus_negotiate_fds(a, is_unix);
680         if (r < 0) {
681                 log_error_errno(r, "Failed to set FD negotiation: %m");
682                 goto finish;
683         }
684
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);
686         if (r < 0) {
687                 log_error_errno(r, "Failed to set credential negotiation: %m");
688                 goto finish;
689         }
690
691         if (ucred.pid > 0) {
692                 a->fake_pids.pid = ucred.pid;
693                 a->fake_pids_valid = true;
694
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;
704         }
705
706         if (peersec) {
707                 a->fake_label = peersec;
708                 peersec = NULL;
709         }
710
711         a->manual_peer_interface = true;
712
713         r = sd_bus_start(a);
714         if (r < 0) {
715                 log_error_errno(r, "Failed to start bus client: %m");
716                 goto finish;
717         }
718
719         r = sd_bus_get_bus_id(a, &server_id);
720         if (r < 0) {
721                 log_error_errno(r, "Failed to get server ID: %m");
722                 goto finish;
723         }
724
725         if (a->is_kernel) {
726                 if (!arg_configuration) {
727                         const char *scope;
728
729                         r = sd_bus_get_scope(a, &scope);
730                         if (r < 0) {
731                                 log_error_errno(r, "Couldn't determine bus scope: %m");
732                                 goto finish;
733                         }
734
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",
740                                                 NULL);
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",
746                                                 NULL);
747                         else {
748                                 log_error("Unknown scope %s, don't know which policy to load. Refusing.", scope);
749                                 goto finish;
750                         }
751
752                         if (!arg_configuration) {
753                                 r = log_oom();
754                                 goto finish;
755                         }
756                 }
757
758                 r = policy_load(&policy_buffer, arg_configuration);
759                 if (r < 0) {
760                         log_error_errno(r, "Failed to load policy: %m");
761                         goto finish;
762                 }
763
764                 policy = &policy_buffer;
765                 /* policy_dump(policy); */
766
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.");
771                 else {
772                         r = log_error_errno(EPERM, "Policy denied connection.");
773                         goto finish;
774                 }
775         }
776
777         r = sd_bus_new(&b);
778         if (r < 0) {
779                 log_error_errno(r, "Failed to allocate bus: %m");
780                 goto finish;
781         }
782
783         r = sd_bus_set_fd(b, in_fd, out_fd);
784         if (r < 0) {
785                 log_error_errno(r, "Failed to set fds: %m");
786                 goto finish;
787         }
788
789         r = sd_bus_set_server(b, 1, server_id);
790         if (r < 0) {
791                 log_error_errno(r, "Failed to set server mode: %m");
792                 goto finish;
793         }
794
795         r = sd_bus_negotiate_fds(b, is_unix);
796         if (r < 0) {
797                 log_error_errno(r, "Failed to set FD negotiation: %m");
798                 goto finish;
799         }
800
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);
802         if (r < 0) {
803                 log_error_errno(r, "Failed to set credential negotiation: %m");
804                 goto finish;
805         }
806
807         r = sd_bus_set_anonymous(b, true);
808         if (r < 0) {
809                 log_error_errno(r, "Failed to set anonymous authentication: %m");
810                 goto finish;
811         }
812
813         b->manual_peer_interface = true;
814
815         r = sd_bus_start(b);
816         if (r < 0) {
817                 log_error_errno(r, "Failed to start bus client: %m");
818                 goto finish;
819         }
820
821         r = rename_service(a, b);
822         if (r < 0)
823                 log_debug_errno(r, "Failed to rename process: %m");
824
825         if (a->is_kernel) {
826                 _cleanup_free_ char *match = NULL;
827                 const char *unique;
828
829                 r = sd_bus_get_unique_name(a, &unique);
830                 if (r < 0) {
831                         log_error_errno(r, "Failed to get unique name: %m");
832                         goto finish;
833                 }
834
835                 match = strjoin("type='signal',"
836                                 "sender='org.freedesktop.DBus',"
837                                 "path='/org/freedesktop/DBus',"
838                                 "interface='org.freedesktop.DBus',"
839                                 "member='NameOwnerChanged',"
840                                 "arg1='",
841                                 unique,
842                                 "'",
843                                 NULL);
844                 if (!match) {
845                         log_oom();
846                         goto finish;
847                 }
848
849                 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
850                 if (r < 0) {
851                         log_error_errno(r, "Failed to add match for NameLost: %m");
852                         goto finish;
853                 }
854
855                 free(match);
856                 match = strjoin("type='signal',"
857                                 "sender='org.freedesktop.DBus',"
858                                 "path='/org/freedesktop/DBus',"
859                                 "interface='org.freedesktop.DBus',"
860                                 "member='NameOwnerChanged',"
861                                 "arg2='",
862                                 unique,
863                                 "'",
864                                 NULL);
865                 if (!match) {
866                         log_oom();
867                         goto finish;
868                 }
869
870                 r = sd_bus_add_match(a, NULL, match, NULL, NULL);
871                 if (r < 0) {
872                         log_error_errno(r, "Failed to add match for NameAcquired: %m");
873                         goto finish;
874                 }
875         }
876
877         for (;;) {
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;
883                 int k;
884
885                 if (got_hello) {
886                         /* Read messages from bus, to pass them on to our client */
887
888                         r = sd_bus_process(a, &m);
889                         if (r < 0) {
890                                 /* treat 'connection reset by peer' as clean exit condition */
891                                 if (r == -ECONNRESET)
892                                         r = 0;
893                                 else
894                                         log_error_errno(r, "Failed to process bus a: %m");
895
896                                 goto finish;
897                         }
898
899                         if (m) {
900                                 bool processed = false;
901
902                                 /* We officially got EOF, let's quit */
903                                 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
904                                         r = 0;
905                                         goto finish;
906                                 }
907
908                                 k = synthesize_name_acquired(a, b, m);
909                                 if (k < 0) {
910                                         r = k;
911                                         log_error_errno(r, "Failed to synthesize message: %m");
912                                         goto finish;
913                                 }
914
915                                 patch_sender(a, m);
916
917                                 if (policy) {
918                                         k = process_policy(a, b, m, policy, &ucred, owned_names);
919                                         if (k < 0) {
920                                                 r = k;
921                                                 log_error_errno(r, "Failed to process policy: %m");
922                                                 goto finish;
923                                         } else if (k > 0) {
924                                                 r = 1;
925                                                 processed = true;
926                                         }
927                                 }
928
929                                 if (!processed) {
930                                         k = sd_bus_send(b, m, NULL);
931                                         if (k < 0) {
932                                                 if (k == -ECONNRESET) {
933                                                         r = 0;
934                                                         goto finish;
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. */
946                                                         r = 1;
947                                                 } else {
948                                                         r = k;
949                                                         log_error_errno(r, "Failed to send message to client: %m");
950                                                         goto finish;
951                                                 }
952                                         } else
953                                                 r = 1;
954                                 }
955                         }
956
957                         if (r > 0)
958                                 continue;
959                 }
960
961                 /* Read messages from our client, to pass them on to the bus */
962                 r = sd_bus_process(b, &m);
963                 if (r < 0) {
964                         /* treat 'connection reset by peer' as clean exit condition */
965                         if (r == -ECONNRESET)
966                                 r = 0;
967                         else
968                                 log_error_errno(r, "Failed to process bus b: %m");
969
970                         goto finish;
971                 }
972
973                 if (m) {
974                         bool processed = false;
975
976                         /* We officially got EOF, let's quit */
977                         if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
978                                 r = 0;
979                                 goto finish;
980                         }
981
982                         k = process_hello(a, b, m, &got_hello);
983                         if (k < 0) {
984                                 r = k;
985                                 log_error_errno(r, "Failed to process HELLO: %m");
986                                 goto finish;
987                         } else if (k > 0) {
988                                 processed = true;
989                                 r = 1;
990                         }
991
992                         if (!processed) {
993                                 k = bus_proxy_process_driver(a, b, m, policy, &ucred, owned_names);
994                                 if (k < 0) {
995                                         r = k;
996                                         log_error_errno(r, "Failed to process driver calls: %m");
997                                         goto finish;
998                                 } else if (k > 0) {
999                                         processed = true;
1000                                         r = 1;
1001                                 }
1002
1003                                 if (!processed) {
1004
1005                                         for (;;) {
1006                                                 if (policy) {
1007                                                         k = process_policy(b, a, m, policy, &ucred, owned_names);
1008                                                         if (k < 0) {
1009                                                                 r = k;
1010                                                                 log_error_errno(r, "Failed to process policy: %m");
1011                                                                 goto finish;
1012                                                         } else if (k > 0) {
1013                                                                 processed = true;
1014                                                                 r = 1;
1015                                                                 break;
1016                                                         }
1017                                                 }
1018
1019                                                 k = sd_bus_send(a, m, NULL);
1020                                                 if (k < 0) {
1021                                                         if (k == -EREMCHG) {
1022                                                                 /* The name database changed since the policy check, hence let's check again */
1023                                                                 continue;
1024                                                         } else if (k == -ECONNRESET) {
1025                                                                 r = 0;
1026                                                                 goto finish;
1027                                                         } else if (k == -EPERM && m->reply_cookie > 0) {
1028                                                                 /* see above why EPERM is ignored for replies */
1029                                                                 r = 1;
1030                                                         } else {
1031                                                                 r = k;
1032                                                                 log_error_errno(r, "Failed to send message to bus: %m");
1033                                                                 goto finish;
1034                                                         }
1035                                                 } else
1036                                                         r = 1;
1037
1038                                                 break;
1039                                         }
1040                                 }
1041                         }
1042                 }
1043
1044                 if (r > 0)
1045                         continue;
1046
1047                 fd = sd_bus_get_fd(a);
1048                 if (fd < 0) {
1049                         log_error_errno(r, "Failed to get fd: %m");
1050                         goto finish;
1051                 }
1052
1053                 events_a = sd_bus_get_events(a);
1054                 if (events_a < 0) {
1055                         log_error_errno(r, "Failed to get events mask: %m");
1056                         goto finish;
1057                 }
1058
1059                 r = sd_bus_get_timeout(a, &timeout_a);
1060                 if (r < 0) {
1061                         log_error_errno(r, "Failed to get timeout: %m");
1062                         goto finish;
1063                 }
1064
1065                 events_b = sd_bus_get_events(b);
1066                 if (events_b < 0) {
1067                         log_error_errno(r, "Failed to get events mask: %m");
1068                         goto finish;
1069                 }
1070
1071                 r = sd_bus_get_timeout(b, &timeout_b);
1072                 if (r < 0) {
1073                         log_error_errno(r, "Failed to get timeout: %m");
1074                         goto finish;
1075                 }
1076
1077                 t = timeout_a;
1078                 if (t == (uint64_t) -1 || (timeout_b != (uint64_t) -1 && timeout_b < timeout_a))
1079                         t = timeout_b;
1080
1081                 if (t == (uint64_t) -1)
1082                         ts = NULL;
1083                 else {
1084                         usec_t nw;
1085
1086                         nw = now(CLOCK_MONOTONIC);
1087                         if (t > nw)
1088                                 t -= nw;
1089                         else
1090                                 t = 0;
1091
1092                         ts = timespec_store(&_ts, t);
1093                 }
1094
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, }
1099                 };
1100
1101                 r = ppoll(pollfd, 3, ts, NULL);
1102                 if (r < 0) {
1103                         log_error_errno(errno, "ppoll() failed: %m");
1104                         goto finish;
1105                 }
1106         }
1107
1108 finish:
1109         sd_notify(false,
1110                   "STOPPING=1\n"
1111                   "STATUS=Shutting down.");
1112
1113         policy_free(&policy_buffer);
1114         strv_free(arg_configuration);
1115         free(arg_address);
1116
1117         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1118 }