+static int bus_new_destination(sd_bus **out, struct ucred *ucred, const char *peersec, bool negotiate_fds) {
+ _cleanup_bus_close_unref_ sd_bus *a = NULL;
+ int r;
+
+ r = sd_bus_new(&a);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate bus: %m");
+
+ r = sd_bus_set_description(a, "sd-proxy");
+ if (r < 0)
+ return log_error_errno(r, "Failed to set bus name: %m");
+
+ r = sd_bus_set_address(a, arg_address);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set address to connect to: %m");
+
+ r = sd_bus_negotiate_fds(a, negotiate_fds);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set FD negotiation: %m");
+
+ r = sd_bus_negotiate_creds(a, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set credential negotiation: %m");
+
+ if (ucred->pid > 0) {
+ a->fake_pids.pid = ucred->pid;
+ a->fake_pids_valid = true;
+
+ a->fake_creds.uid = ucred->uid;
+ a->fake_creds.euid = UID_INVALID;
+ a->fake_creds.suid = UID_INVALID;
+ a->fake_creds.fsuid = UID_INVALID;
+ a->fake_creds.gid = ucred->gid;
+ a->fake_creds.egid = GID_INVALID;
+ a->fake_creds.sgid = GID_INVALID;
+ a->fake_creds.fsgid = GID_INVALID;
+ a->fake_creds_valid = true;
+ }
+
+ if (peersec) {
+ a->fake_label = strdup(peersec);
+ if (!a->fake_label)
+ return log_oom();
+ }
+
+ a->manual_peer_interface = true;
+
+ r = sd_bus_start(a);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start bus client: %m");
+
+ *out = a;
+ a = NULL;
+ return 0;
+}
+
+static int bus_new_local(sd_bus **out, sd_bus *dest, int in_fd, int out_fd, bool negotiate_fds) {
+ _cleanup_bus_close_unref_ sd_bus *b = NULL;
+ sd_id128_t server_id;
+ int r;
+
+ r = sd_bus_new(&b);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate bus: %m");
+
+ r = sd_bus_set_fd(b, in_fd, out_fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set fds: %m");
+
+ r = sd_bus_get_bus_id(dest, &server_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get server ID: %m");
+
+ r = sd_bus_set_server(b, 1, server_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set server mode: %m");
+
+ r = sd_bus_negotiate_fds(b, negotiate_fds);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set FD negotiation: %m");
+
+ r = sd_bus_negotiate_creds(b, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_GID|SD_BUS_CREDS_SELINUX_CONTEXT);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set credential negotiation: %m");
+
+ r = sd_bus_set_anonymous(b, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set anonymous authentication: %m");
+
+ b->manual_peer_interface = true;
+
+ r = sd_bus_start(b);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start bus client: %m");
+
+ *out = b;
+ b = NULL;
+ return 0;
+}
+