summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-bus/bus-container.c46
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c23
-rw-r--r--src/libsystemd/sd-login/sd-login.c6
-rw-r--r--src/libsystemd/sd-login/test-login.c26
4 files changed, 71 insertions, 30 deletions
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 101e4af18d..56dc086ae2 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -125,15 +125,22 @@ int bus_container_connect_kernel(sd_bus *b) {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
+ int error_buf = 0;
+ struct iovec iov = {
+ .iov_base = &error_buf,
+ .iov_len = sizeof(error_buf),
+ };
struct msghdr mh = {
.msg_control = &control,
.msg_controllen = sizeof(control),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
};
struct cmsghdr *cmsg;
pid_t child;
siginfo_t si;
- int r;
- _cleanup_close_ int fd = -1;
+ int r, fd = -1;
+ ssize_t n;
assert(b);
assert(b->input_fd < 0);
@@ -178,10 +185,13 @@ int bus_container_connect_kernel(sd_bus *b) {
_exit(EXIT_FAILURE);
if (grandchild == 0) {
-
fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
+ if (fd < 0) {
+ /* Try to send error up */
+ error_buf = errno;
+ (void) write(pair[1], &error_buf, sizeof(error_buf));
_exit(EXIT_FAILURE);
+ }
cmsg = CMSG_FIRSTHDR(&mh);
cmsg->cmsg_level = SOL_SOCKET;
@@ -213,20 +223,17 @@ int bus_container_connect_kernel(sd_bus *b) {
if (r < 0)
return r;
- if (si.si_code != CLD_EXITED)
- return -EIO;
-
- if (si.si_status != EXIT_SUCCESS)
- return -EIO;
-
- if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
+ n = recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+ if (n < 0)
return -errno;
- CMSG_FOREACH(cmsg, &mh)
+ CMSG_FOREACH(cmsg, &mh) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
int *fds;
unsigned n_fds;
+ assert(fd < 0);
+
fds = (int*) CMSG_DATA(cmsg);
n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
@@ -237,9 +244,18 @@ int bus_container_connect_kernel(sd_bus *b) {
fd = fds[0];
}
+ }
+
+ /* If there's an fd passed, we are good. */
+ if (fd >= 0) {
+ b->input_fd = b->output_fd = fd;
+ return bus_kernel_take_fd(b);
+ }
- b->input_fd = b->output_fd = fd;
- fd = -1;
+ /* If there's an error passed, use it */
+ if (n == sizeof(error_buf) && error_buf > 0)
+ return -error_buf;
- return bus_kernel_take_fd(b);
+ /* Otherwise, we have no clue */
+ return -EIO;
}
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 5285278d92..4ed508427e 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1025,19 +1025,30 @@ static int bus_start_address(sd_bus *b) {
if (b->exec_path)
r = bus_socket_exec(b);
+
else if ((b->nspid > 0 || b->machine) && b->kernel) {
r = bus_container_connect_kernel(b);
if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT))
container_kdbus_available = true;
- } else if (!container_kdbus_available && (b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
- r = bus_container_connect_socket(b);
- else if (b->kernel) {
+
+ } else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC) {
+ if (!container_kdbus_available)
+ r = bus_container_connect_socket(b);
+ else
+ skipped = true;
+
+ } else if (b->kernel) {
r = bus_kernel_connect(b);
if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT))
kdbus_available = true;
- } else if (!kdbus_available && b->sockaddr.sa.sa_family != AF_UNSPEC)
- r = bus_socket_connect(b);
- else
+
+ } else if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
+ if (!kdbus_available)
+ r = bus_socket_connect(b);
+ else
+ skipped = true;
+
+ } else
skipped = true;
if (!skipped) {
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 0eadc8c747..7d6a4b78cf 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -237,11 +237,13 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) {
return r;
r = parse_env_file(p, NEWLINE, "DISPLAY", &s, NULL);
+ if (r == -ENOENT)
+ return -ENXIO;
if (r < 0)
return r;
if (isempty(s))
- return -ENOENT;
+ return -ENXIO;
*session = s;
s = NULL;
@@ -465,7 +467,7 @@ static int session_get_string(const char *session, const char *field, char **val
return r;
if (isempty(s))
- return -ENOENT;
+ return -ENXIO;
*value = s;
s = NULL;
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 05affa442d..ddea7ffa14 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -33,7 +33,7 @@ static void test_login(void) {
_cleanup_free_ char *pp = NULL, *qq = NULL;
int r, k;
uid_t u, u2;
- char *seat, *type, *class, *display, *remote_user, *remote_host;
+ char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session;
char *session;
char *state;
char *session2;
@@ -50,6 +50,12 @@ static void test_login(void) {
assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
printf("user = "UID_FMT"\n", u2);
+ display_session = NULL;
+ r = sd_uid_get_display(u2, &display_session);
+ assert_se(r >= 0 || r == -ENXIO);
+ printf("user's display session = %s\n", strna(display_session));
+ free(display_session);
+
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
sd_peer_get_session(pair[0], &pp);
sd_peer_get_session(pair[1], &qq);
@@ -100,16 +106,22 @@ static void test_login(void) {
printf("class = %s\n", class);
free(class);
- assert_se(sd_session_get_display(session, &display) >= 0);
- printf("display = %s\n", display);
+ display = NULL;
+ r = sd_session_get_display(session, &display);
+ assert_se(r >= 0 || r == -ENXIO);
+ printf("display = %s\n", strna(display));
free(display);
- assert_se(sd_session_get_remote_user(session, &remote_user) >= 0);
- printf("remote_user = %s\n", remote_user);
+ remote_user = NULL;
+ r = sd_session_get_remote_user(session, &remote_user);
+ assert_se(r >= 0 || r == -ENXIO);
+ printf("remote_user = %s\n", strna(remote_user));
free(remote_user);
- assert_se(sd_session_get_remote_host(session, &remote_host) >= 0);
- printf("remote_host = %s\n", remote_host);
+ remote_host = NULL;
+ r = sd_session_get_remote_host(session, &remote_host);
+ assert_se(r >= 0 || r == -ENXIO);
+ printf("remote_host = %s\n", strna(remote_host));
free(remote_host);
assert_se(sd_session_get_seat(session, &seat) >= 0);