]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-container.c
2 This file is part of systemd.
4 Copyright 2013 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "bus-container.h"
24 #include "bus-internal.h"
25 #include "bus-socket.h"
27 #include "process-util.h"
30 int bus_container_connect_socket(sd_bus
*b
) {
31 _cleanup_close_pair_
int pair
[2] = { -1, -1 };
32 _cleanup_close_
int pidnsfd
= -1, mntnsfd
= -1, usernsfd
= -1, rootfd
= -1;
39 assert(b
->input_fd
< 0);
40 assert(b
->output_fd
< 0);
41 assert(b
->nspid
> 0 || b
->machine
);
44 r
= container_get_leader(b
->machine
, &b
->nspid
);
49 r
= namespace_open(b
->nspid
, &pidnsfd
, &mntnsfd
, NULL
, &usernsfd
, &rootfd
);
53 b
->input_fd
= socket(b
->sockaddr
.sa
.sa_family
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
57 b
->output_fd
= b
->input_fd
;
61 if (socketpair(AF_UNIX
, SOCK_SEQPACKET
, 0, pair
) < 0)
71 pair
[0] = safe_close(pair
[0]);
73 r
= namespace_enter(pidnsfd
, mntnsfd
, -1, usernsfd
, rootfd
);
77 /* We just changed PID namespace, however it will only
78 * take effect on the children we now fork. Hence,
79 * let's fork another time, and connect from this
80 * grandchild, so that SO_PEERCRED of our connection
81 * comes from a process from within the container, and
82 * not outside of it */
88 if (grandchild
== 0) {
90 r
= connect(b
->input_fd
, &b
->sockaddr
.sa
, b
->sockaddr_size
);
92 /* Try to send error up */
94 (void) write(pair
[1], &error_buf
, sizeof(error_buf
));
101 r
= wait_for_terminate(grandchild
, &si
);
105 if (si
.si_code
!= CLD_EXITED
)
111 pair
[1] = safe_close(pair
[1]);
113 r
= wait_for_terminate(child
, &si
);
117 n
= read(pair
[0], &error_buf
, sizeof(error_buf
));
122 if (n
!= sizeof(error_buf
))
128 if (error_buf
== EINPROGRESS
)
135 if (si
.si_code
!= CLD_EXITED
)
138 if (si
.si_status
!= EXIT_SUCCESS
)
141 return bus_socket_start_auth(b
);