]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-container.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
11 #include "bus-container.h"
12 #include "bus-internal.h"
13 #include "bus-socket.h"
15 #include "process-util.h"
18 int bus_container_connect_socket(sd_bus
*b
) {
19 _cleanup_close_pair_
int pair
[2] = { -1, -1 };
20 _cleanup_close_
int pidnsfd
= -1, mntnsfd
= -1, usernsfd
= -1, rootfd
= -1;
26 assert(b
->input_fd
< 0);
27 assert(b
->output_fd
< 0);
28 assert(b
->nspid
> 0 || b
->machine
);
31 r
= container_get_leader(b
->machine
, &b
->nspid
);
36 r
= namespace_open(b
->nspid
, &pidnsfd
, &mntnsfd
, NULL
, &usernsfd
, &rootfd
);
40 b
->input_fd
= socket(b
->sockaddr
.sa
.sa_family
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
44 b
->input_fd
= fd_move_above_stdio(b
->input_fd
);
46 b
->output_fd
= b
->input_fd
;
50 if (socketpair(AF_UNIX
, SOCK_SEQPACKET
, 0, pair
) < 0)
53 r
= safe_fork("(sd-buscntr)", FORK_RESET_SIGNALS
|FORK_DEATHSIG
, &child
);
59 pair
[0] = safe_close(pair
[0]);
61 r
= namespace_enter(pidnsfd
, mntnsfd
, -1, usernsfd
, rootfd
);
65 /* We just changed PID namespace, however it will only
66 * take effect on the children we now fork. Hence,
67 * let's fork another time, and connect from this
68 * grandchild, so that SO_PEERCRED of our connection
69 * comes from a process from within the container, and
70 * not outside of it */
72 r
= safe_fork("(sd-buscntr2)", FORK_RESET_SIGNALS
|FORK_DEATHSIG
, &grandchild
);
77 r
= connect(b
->input_fd
, &b
->sockaddr
.sa
, b
->sockaddr_size
);
79 /* Try to send error up */
81 (void) write(pair
[1], &error_buf
, sizeof(error_buf
));
88 r
= wait_for_terminate_and_check("(sd-buscntr2)", grandchild
, 0);
95 pair
[1] = safe_close(pair
[1]);
97 r
= wait_for_terminate_and_check("(sd-buscntr)", child
, 0);
100 if (r
!= EXIT_SUCCESS
)
103 n
= read(pair
[0], &error_buf
, sizeof(error_buf
));
108 if (n
!= sizeof(error_buf
))
114 if (error_buf
== EINPROGRESS
)
121 return bus_socket_start_auth(b
);