chiark / gitweb /
bus: when the first char a server receives isn't the NUL byte immediately fail
[elogind.git] / src / libsystemd-bus / bus-socket.c
index cb1e942833b5b44e863ce5ddf0cbe5b29d9a505e..82e683a9578724bd9acd2e5f459afb804ea01734 100644 (file)
@@ -31,6 +31,7 @@
 #include "missing.h"
 #include "strv.h"
 #include "utf8.h"
 #include "missing.h"
 #include "strv.h"
 #include "utf8.h"
+#include "sd-daemon.h"
 
 #include "sd-bus.h"
 #include "bus-socket.h"
 
 #include "sd-bus.h"
 #include "bus-socket.h"
@@ -75,7 +76,6 @@ bool bus_socket_auth_needs_write(sd_bus *b) {
 }
 
 static int bus_socket_write_auth(sd_bus *b) {
 }
 
 static int bus_socket_write_auth(sd_bus *b) {
-        struct msghdr mh;
         ssize_t k;
 
         assert(b);
         ssize_t k;
 
         assert(b);
@@ -84,16 +84,26 @@ static int bus_socket_write_auth(sd_bus *b) {
         if (!bus_socket_auth_needs_write(b))
                 return 0;
 
         if (!bus_socket_auth_needs_write(b))
                 return 0;
 
-        zero(mh);
-        mh.msg_iov = b->auth_iovec + b->auth_index;
-        mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
+        if (b->prefer_writev)
+                k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
+        else {
+                struct msghdr mh;
+                zero(mh);
+
+                mh.msg_iov = b->auth_iovec + b->auth_index;
+                mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
+
+                k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
+                if (k < 0 && errno == ENOTSOCK) {
+                        b->prefer_writev = true;
+                        k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
+                }
+        }
 
 
-        k = sendmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
 
         iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
 
         iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
-
         return 1;
 }
 
         return 1;
 }
 
@@ -146,11 +156,11 @@ static int bus_socket_auth_verify_client(sd_bus *b) {
                 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
         }
 
                 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
         }
 
-        if (!sd_id128_equal(b->peer, SD_ID128_NULL) &&
-            !sd_id128_equal(b->peer, peer))
+        if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
+            !sd_id128_equal(b->server_id, peer))
                 return -EPERM;
 
                 return -EPERM;
 
-        b->peer = peer;
+        b->server_id = peer;
 
         /* And possibly check the second line, too */
 
 
         /* And possibly check the second line, too */
 
@@ -225,7 +235,7 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) {
          * the owner of this bus wanted authentication he should have
          * checked SO_PEERCRED before even creating the bus object. */
 
          * the owner of this bus wanted authentication he should have
          * checked SO_PEERCRED before even creating the bus object. */
 
-        if (!b->ucred_valid)
+        if (!b->anonymous_auth && !b->ucred_valid)
                 return 0;
 
         if (l <= 0)
                 return 0;
 
         if (l <= 0)
@@ -248,7 +258,9 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) {
         if (r < 0)
                 return 0;
 
         if (r < 0)
                 return 0;
 
-        if (u != b->ucred.uid)
+        /* We ignore the passed value if anonymous authentication is
+         * on anyway. */
+        if (!b->anonymous_auth && u != b->ucred.uid)
                 return 0;
 
         return 1;
                 return 0;
 
         return 1;
@@ -286,7 +298,7 @@ static int bus_socket_auth_write_ok(sd_bus *b) {
 
         assert(b);
 
 
         assert(b);
 
-        snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->peer));
+        snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
         char_array_0(t);
 
         return bus_socket_auth_write(b, t);
         char_array_0(t);
 
         return bus_socket_auth_write(b, t);
@@ -301,13 +313,16 @@ static int bus_socket_auth_verify_server(sd_bus *b) {
 
         assert(b);
 
 
         assert(b);
 
-        if (b->rbuffer_size < 3)
+        if (b->rbuffer_size < 1)
                 return 0;
 
         /* First char must be a NUL byte */
         if (*(char*) b->rbuffer != 0)
                 return -EIO;
 
                 return 0;
 
         /* First char must be a NUL byte */
         if (*(char*) b->rbuffer != 0)
                 return -EIO;
 
+        if (b->rbuffer_size < 3)
+                return 0;
+
         /* Begin with the first line */
         if (b->auth_rbegin <= 0)
                 b->auth_rbegin = 1;
         /* Begin with the first line */
         if (b->auth_rbegin <= 0)
                 b->auth_rbegin = 1;
@@ -431,6 +446,7 @@ static int bus_socket_read_auth(sd_bus *b) {
                             CMSG_SPACE(NAME_MAX)]; /*selinux label */
         } control;
         struct cmsghdr *cmsg;
                             CMSG_SPACE(NAME_MAX)]; /*selinux label */
         } control;
         struct cmsghdr *cmsg;
+        bool handle_cmsg = false;
 
         assert(b);
         assert(b->state == BUS_AUTHENTICATING);
 
         assert(b);
         assert(b->state == BUS_AUTHENTICATING);
@@ -457,13 +473,22 @@ static int bus_socket_read_auth(sd_bus *b) {
         iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
         iov.iov_len = n - b->rbuffer_size;
 
         iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
         iov.iov_len = n - b->rbuffer_size;
 
-        zero(mh);
-        mh.msg_iov = &iov;
-        mh.msg_iovlen = 1;
-        mh.msg_control = &control;
-        mh.msg_controllen = sizeof(control);
-
-        k = recvmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+        if (b->prefer_readv)
+                k = readv(b->input_fd, &iov, 1);
+        else {
+                zero(mh);
+                mh.msg_iov = &iov;
+                mh.msg_iovlen = 1;
+                mh.msg_control = &control;
+                mh.msg_controllen = sizeof(control);
+
+                k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+                if (k < 0 && errno == ENOTSOCK) {
+                        b->prefer_readv = true;
+                        k = readv(b->input_fd, &iov, 1);
+                } else
+                        handle_cmsg = true;
+        }
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
         if (k == 0)
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
         if (k == 0)
@@ -471,32 +496,34 @@ static int bus_socket_read_auth(sd_bus *b) {
 
         b->rbuffer_size += k;
 
 
         b->rbuffer_size += k;
 
-        for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
-                if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SCM_RIGHTS) {
-                        int j;
-
-                        /* Whut? We received fds during the auth
-                         * protocol? Somebody is playing games with
-                         * us. Close them all, and fail */
-                        j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-                        close_many((int*) CMSG_DATA(cmsg), j);
-                        return -EIO;
+        if (handle_cmsg) {
+                for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
+                        if (cmsg->cmsg_level == SOL_SOCKET &&
+                            cmsg->cmsg_type == SCM_RIGHTS) {
+                                int j;
+
+                                /* Whut? We received fds during the auth
+                                 * protocol? Somebody is playing games with
+                                 * us. Close them all, and fail */
+                                j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+                                close_many((int*) CMSG_DATA(cmsg), j);
+                                return -EIO;
 
 
-                } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SCM_CREDENTIALS &&
-                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
+                        } else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                   cmsg->cmsg_type == SCM_CREDENTIALS &&
+                                   cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
 
 
-                        memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
-                        b->ucred_valid = true;
+                                memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+                                b->ucred_valid = true;
 
 
-                } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                         cmsg->cmsg_type == SCM_SECURITY) {
+                        } else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                   cmsg->cmsg_type == SCM_SECURITY) {
 
 
-                        size_t l;
-                        l = cmsg->cmsg_len - CMSG_LEN(0);
-                        memcpy(&b->label, CMSG_DATA(cmsg), l);
-                        b->label[l] = 0;
+                                size_t l;
+                                l = cmsg->cmsg_len - CMSG_LEN(0);
+                                memcpy(&b->label, CMSG_DATA(cmsg), l);
+                                b->label[l] = 0;
+                        }
                 }
         }
 
                 }
         }
 
@@ -515,12 +542,12 @@ static int bus_socket_setup(sd_bus *b) {
         /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
          * socket, just in case. */
         enable = !b->bus_client;
         /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
          * socket, just in case. */
         enable = !b->bus_client;
-        setsockopt(b->fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
-        setsockopt(b->fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
+        setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
+        setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
 
         /* Increase the buffers to a MB */
 
         /* Increase the buffers to a MB */
-        fd_inc_rcvbuf(b->fd, 1024*1024);
-        fd_inc_sndbuf(b->fd, 1024*1024);
+        fd_inc_rcvbuf(b->input_fd, 1024*1024);
+        fd_inc_sndbuf(b->output_fd, 1024*1024);
 
         return 0;
 }
 
         return 0;
 }
@@ -568,22 +595,18 @@ static int bus_socket_start_auth_client(sd_bus *b) {
 }
 
 static int bus_socket_start_auth(sd_bus *b) {
 }
 
 static int bus_socket_start_auth(sd_bus *b) {
-        int domain = 0, r;
-        socklen_t sl;
-
         assert(b);
 
         b->state = BUS_AUTHENTICATING;
         b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
 
         assert(b);
 
         b->state = BUS_AUTHENTICATING;
         b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
 
-        sl = sizeof(domain);
-        r = getsockopt(b->fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
-        if (r < 0)
-                return -errno;
-
-        if (domain != AF_UNIX)
+        if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
                 b->negotiate_fds = false;
 
                 b->negotiate_fds = false;
 
+        if (b->output_fd != b->input_fd)
+                if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
+                        b->negotiate_fds = false;
+
         if (b->is_server)
                 return bus_socket_read_auth(b);
         else
         if (b->is_server)
                 return bus_socket_read_auth(b);
         else
@@ -594,18 +617,21 @@ int bus_socket_connect(sd_bus *b) {
         int r;
 
         assert(b);
         int r;
 
         assert(b);
-        assert(b->fd < 0);
+        assert(b->input_fd < 0);
+        assert(b->output_fd < 0);
         assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
 
         assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
 
-        b->fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
-        if (b->fd < 0)
+        b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+        if (b->input_fd < 0)
                 return -errno;
 
                 return -errno;
 
+        b->output_fd = b->input_fd;
+
         r = bus_socket_setup(b);
         if (r < 0)
                 return r;
 
         r = bus_socket_setup(b);
         if (r < 0)
                 return r;
 
-        r = connect(b->fd, &b->sockaddr.sa, b->sockaddr_size);
+        r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
         if (r < 0) {
                 if (errno == EINPROGRESS)
                         return 1;
         if (r < 0) {
                 if (errno == EINPROGRESS)
                         return 1;
@@ -617,15 +643,16 @@ int bus_socket_connect(sd_bus *b) {
 }
 
 int bus_socket_exec(sd_bus *b) {
 }
 
 int bus_socket_exec(sd_bus *b) {
-        int s[2];
+        int s[2], r;
         pid_t pid;
 
         assert(b);
         pid_t pid;
 
         assert(b);
-        assert(b->fd < 0);
+        assert(b->input_fd < 0);
+        assert(b->output_fd < 0);
         assert(b->exec_path);
 
         assert(b->exec_path);
 
-        b->fd = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
-        if (b->fd < 0)
+        r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
+        if (r < 0)
                 return -errno;
 
         pid = fork();
                 return -errno;
 
         pid = fork();
@@ -636,8 +663,9 @@ int bus_socket_exec(sd_bus *b) {
         if (pid == 0) {
                 /* Child */
 
         if (pid == 0) {
                 /* Child */
 
-                close_all_fds(s, 2);
-                close_nointr_nofail(s[0]);
+                reset_all_signal_handlers();
+
+                close_all_fds(s+1, 1);
 
                 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
                 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
 
                 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
                 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
@@ -661,7 +689,7 @@ int bus_socket_exec(sd_bus *b) {
         }
 
         close_nointr_nofail(s[1]);
         }
 
         close_nointr_nofail(s[1]);
-        b->fd = s[0];
+        b->output_fd = b->input_fd = s[0];
 
         return bus_socket_start_auth(b);
 }
 
         return bus_socket_start_auth(b);
 }
@@ -678,7 +706,6 @@ int bus_socket_take_fd(sd_bus *b) {
 }
 
 int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
 }
 
 int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
-        struct msghdr mh;
         struct iovec *iov;
         ssize_t k;
         size_t n;
         struct iovec *iov;
         ssize_t k;
         size_t n;
@@ -691,18 +718,6 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
 
         if (*idx >= m->size)
                 return 0;
 
         if (*idx >= m->size)
                 return 0;
-        zero(mh);
-
-        if (m->n_fds > 0) {
-                struct cmsghdr *control;
-                control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
-
-                mh.msg_control = control;
-                control->cmsg_level = SOL_SOCKET;
-                control->cmsg_type = SCM_RIGHTS;
-                mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
-                memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
-        }
 
         n = m->n_iovec * sizeof(struct iovec);
         iov = alloca(n);
 
         n = m->n_iovec * sizeof(struct iovec);
         iov = alloca(n);
@@ -711,10 +726,33 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
         j = 0;
         iovec_advance(iov, &j, *idx);
 
         j = 0;
         iovec_advance(iov, &j, *idx);
 
-        mh.msg_iov = iov;
-        mh.msg_iovlen = m->n_iovec;
+        if (bus->prefer_writev)
+                k = writev(bus->output_fd, iov, m->n_iovec);
+        else {
+                struct msghdr mh;
+                zero(mh);
+
+                if (m->n_fds > 0) {
+                        struct cmsghdr *control;
+                        control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
+
+                        mh.msg_control = control;
+                        control->cmsg_level = SOL_SOCKET;
+                        control->cmsg_type = SCM_RIGHTS;
+                        mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
+                        memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
+                }
+
+                mh.msg_iov = iov;
+                mh.msg_iovlen = m->n_iovec;
+
+                k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
+                if (k < 0 && errno == ENOTSOCK) {
+                        bus->prefer_writev = true;
+                        k = writev(bus->output_fd, iov, m->n_iovec);
+                }
+        }
 
 
-        k = sendmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
 
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
 
@@ -826,6 +864,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
                             CMSG_SPACE(NAME_MAX)]; /*selinux label */
         } control;
         struct cmsghdr *cmsg;
                             CMSG_SPACE(NAME_MAX)]; /*selinux label */
         } control;
         struct cmsghdr *cmsg;
+        bool handle_cmsg;
 
         assert(bus);
         assert(m);
 
         assert(bus);
         assert(m);
@@ -848,13 +887,22 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
         iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
         iov.iov_len = need - bus->rbuffer_size;
 
         iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
         iov.iov_len = need - bus->rbuffer_size;
 
-        zero(mh);
-        mh.msg_iov = &iov;
-        mh.msg_iovlen = 1;
-        mh.msg_control = &control;
-        mh.msg_controllen = sizeof(control);
-
-        k = recvmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+        if (bus->prefer_readv)
+                k = readv(bus->input_fd, &iov, 1);
+        else {
+                zero(mh);
+                mh.msg_iov = &iov;
+                mh.msg_iovlen = 1;
+                mh.msg_control = &control;
+                mh.msg_controllen = sizeof(control);
+
+                k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+                if (k < 0 && errno == ENOTSOCK) {
+                        bus->prefer_readv = true;
+                        k = readv(bus->input_fd, &iov, 1);
+                } else
+                        handle_cmsg = true;
+        }
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
         if (k == 0)
         if (k < 0)
                 return errno == EAGAIN ? 0 : -errno;
         if (k == 0)
@@ -862,45 +910,47 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
 
         bus->rbuffer_size += k;
 
 
         bus->rbuffer_size += k;
 
-        for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
-                if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SCM_RIGHTS) {
-                        int n, *f;
-
-                        n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-
-                        if (!bus->can_fds) {
-                                /* Whut? We received fds but this
-                                 * isn't actually enabled? Close them,
-                                 * and fail */
-
-                                close_many((int*) CMSG_DATA(cmsg), n);
-                                return -EIO;
+        if (handle_cmsg) {
+                for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
+                        if (cmsg->cmsg_level == SOL_SOCKET &&
+                            cmsg->cmsg_type == SCM_RIGHTS) {
+                                int n, *f;
+
+                                n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+
+                                if (!bus->can_fds) {
+                                        /* Whut? We received fds but this
+                                         * isn't actually enabled? Close them,
+                                         * and fail */
+
+                                        close_many((int*) CMSG_DATA(cmsg), n);
+                                        return -EIO;
+                                }
+
+                                f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
+                                if (!f) {
+                                        close_many((int*) CMSG_DATA(cmsg), n);
+                                        return -ENOMEM;
+                                }
+
+                                memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
+                                bus->fds = f;
+                                bus->n_fds += n;
+                        } else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                   cmsg->cmsg_type == SCM_CREDENTIALS &&
+                                   cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
+
+                                memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
+                                bus->ucred_valid = true;
+
+                        } else if (cmsg->cmsg_level == SOL_SOCKET &&
+                                   cmsg->cmsg_type == SCM_SECURITY) {
+
+                                size_t l;
+                                l = cmsg->cmsg_len - CMSG_LEN(0);
+                                memcpy(&bus->label, CMSG_DATA(cmsg), l);
+                                bus->label[l] = 0;
                         }
                         }
-
-                        f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
-                        if (!f) {
-                                close_many((int*) CMSG_DATA(cmsg), n);
-                                return -ENOMEM;
-                        }
-
-                        memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
-                        bus->fds = f;
-                        bus->n_fds += n;
-                } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                    cmsg->cmsg_type == SCM_CREDENTIALS &&
-                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
-
-                        memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
-                        bus->ucred_valid = true;
-
-                } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                         cmsg->cmsg_type == SCM_SECURITY) {
-
-                        size_t l;
-                        l = cmsg->cmsg_len - CMSG_LEN(0);
-                        memcpy(&bus->label, CMSG_DATA(cmsg), l);
-                        bus->label[l] = 0;
                 }
         }
 
                 }
         }
 
@@ -924,7 +974,7 @@ int bus_socket_process_opening(sd_bus *b) {
         assert(b->state == BUS_OPENING);
 
         zero(p);
         assert(b->state == BUS_OPENING);
 
         zero(p);
-        p.fd = b->fd;
+        p.fd = b->output_fd;
         p.events = POLLOUT;
 
         r = poll(&p, 1, 0);
         p.events = POLLOUT;
 
         r = poll(&p, 1, 0);
@@ -934,7 +984,7 @@ int bus_socket_process_opening(sd_bus *b) {
         if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
                 return 0;
 
         if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
                 return 0;
 
-        r = getsockopt(b->fd, SOL_SOCKET, SO_ERROR, &error, &slen);
+        r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
         if (r < 0)
                 b->last_connect_error = errno;
         else if (error != 0)
         if (r < 0)
                 b->last_connect_error = errno;
         else if (error != 0)