chiark / gitweb /
216c9c1d0d07c75586adb791159b1fef19bd84a1
[elogind.git] / src / machine / machine-dbus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <string.h>
24 #include <arpa/inet.h>
25 #include <sys/mount.h>
26
27 /* When we include libgen.h because we need dirname() we immediately
28  * undefine basename() since libgen.h defines it as a macro to the XDG
29  * version which is really broken. */
30 #include <libgen.h>
31 #undef basename
32
33 #include "bus-util.h"
34 #include "bus-label.h"
35 #include "strv.h"
36 #include "bus-common-errors.h"
37 #include "copy.h"
38 #include "fileio.h"
39 #include "in-addr-util.h"
40 #include "local-addresses.h"
41 #include "path-util.h"
42 #include "mkdir.h"
43 #include "bus-internal.h"
44 #include "machine.h"
45 #include "machine-dbus.h"
46
47 static int property_get_id(
48                 sd_bus *bus,
49                 const char *path,
50                 const char *interface,
51                 const char *property,
52                 sd_bus_message *reply,
53                 void *userdata,
54                 sd_bus_error *error) {
55
56         Machine *m = userdata;
57         int r;
58
59         assert(bus);
60         assert(reply);
61         assert(m);
62
63         r = sd_bus_message_append_array(reply, 'y', &m->id, 16);
64         if (r < 0)
65                 return r;
66
67         return 1;
68 }
69
70 static int property_get_state(
71                 sd_bus *bus,
72                 const char *path,
73                 const char *interface,
74                 const char *property,
75                 sd_bus_message *reply,
76                 void *userdata,
77                 sd_bus_error *error) {
78
79         Machine *m = userdata;
80         const char *state;
81         int r;
82
83         assert(bus);
84         assert(reply);
85         assert(m);
86
87         state = machine_state_to_string(machine_get_state(m));
88
89         r = sd_bus_message_append_basic(reply, 's', state);
90         if (r < 0)
91                 return r;
92
93         return 1;
94 }
95
96 static int property_get_netif(
97                 sd_bus *bus,
98                 const char *path,
99                 const char *interface,
100                 const char *property,
101                 sd_bus_message *reply,
102                 void *userdata,
103                 sd_bus_error *error) {
104
105         Machine *m = userdata;
106         int r;
107
108         assert(bus);
109         assert(reply);
110         assert(m);
111
112         assert_cc(sizeof(int) == sizeof(int32_t));
113
114         r = sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
115         if (r < 0)
116                 return r;
117
118         return 1;
119 }
120
121 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
122
123 int bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
124         Machine *m = userdata;
125         int r;
126
127         assert(bus);
128         assert(message);
129         assert(m);
130
131         r = machine_stop(m);
132         if (r < 0)
133                 return r;
134
135         return sd_bus_reply_method_return(message, NULL);
136 }
137
138 int bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
139         Machine *m = userdata;
140         const char *swho;
141         int32_t signo;
142         KillWho who;
143         int r;
144
145         assert(bus);
146         assert(message);
147         assert(m);
148
149         r = sd_bus_message_read(message, "si", &swho, &signo);
150         if (r < 0)
151                 return r;
152
153         if (isempty(swho))
154                 who = KILL_ALL;
155         else {
156                 who = kill_who_from_string(swho);
157                 if (who < 0)
158                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
159         }
160
161         if (signo <= 0 || signo >= _NSIG)
162                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
163
164         r = machine_kill(m, who, signo);
165         if (r < 0)
166                 return r;
167
168         return sd_bus_reply_method_return(message, NULL);
169 }
170
171 int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
172         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
173         _cleanup_close_pair_ int pair[2] = { -1, -1 };
174         _cleanup_free_ char *us = NULL, *them = NULL;
175         _cleanup_close_ int netns_fd = -1;
176         Machine *m = userdata;
177         const char *p;
178         siginfo_t si;
179         pid_t child;
180         int r;
181
182         assert(bus);
183         assert(message);
184         assert(m);
185
186         if (m->class != MACHINE_CONTAINER)
187                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting IP address data is only supported on container machines.");
188
189         r = readlink_malloc("/proc/self/ns/net", &us);
190         if (r < 0)
191                 return r;
192
193         p = procfs_file_alloca(m->leader, "ns/net");
194         r = readlink_malloc(p, &them);
195         if (r < 0)
196                 return r;
197
198         if (streq(us, them))
199                 return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
200
201         r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL);
202         if (r < 0)
203                 return r;
204
205         if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
206                 return -errno;
207
208         child = fork();
209         if (child < 0)
210                 return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
211
212         if (child == 0) {
213                 _cleanup_free_ struct local_address *addresses = NULL;
214                 struct local_address *a;
215                 int i, n;
216
217                 pair[0] = safe_close(pair[0]);
218
219                 r = namespace_enter(-1, -1, netns_fd, -1);
220                 if (r < 0)
221                         _exit(EXIT_FAILURE);
222
223                 n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
224                 if (n < 0)
225                         _exit(EXIT_FAILURE);
226
227                 for (a = addresses, i = 0; i < n; a++, i++) {
228                         struct iovec iov[2] = {
229                                 { .iov_base = &a->family, .iov_len = sizeof(a->family) },
230                                 { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) },
231                         };
232
233                         r = writev(pair[1], iov, 2);
234                         if (r < 0)
235                                 _exit(EXIT_FAILURE);
236                 }
237
238                 pair[1] = safe_close(pair[1]);
239
240                 _exit(EXIT_SUCCESS);
241         }
242
243         pair[1] = safe_close(pair[1]);
244
245         r = sd_bus_message_new_method_return(message, &reply);
246         if (r < 0)
247                 return r;
248
249         r = sd_bus_message_open_container(reply, 'a', "(iay)");
250         if (r < 0)
251                 return r;
252
253         for (;;) {
254                 int family;
255                 ssize_t n;
256                 union in_addr_union in_addr;
257                 struct iovec iov[2];
258                 struct msghdr mh = {
259                         .msg_iov = iov,
260                         .msg_iovlen = 2,
261                 };
262
263                 iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
264                 iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
265
266                 n = recvmsg(pair[0], &mh, 0);
267                 if (n < 0)
268                         return -errno;
269                 if ((size_t) n < sizeof(family))
270                         break;
271
272                 r = sd_bus_message_open_container(reply, 'r', "iay");
273                 if (r < 0)
274                         return r;
275
276                 r = sd_bus_message_append(reply, "i", family);
277                 if (r < 0)
278                         return r;
279
280                 switch (family) {
281
282                 case AF_INET:
283                         if (n != sizeof(struct in_addr) + sizeof(family))
284                                 return -EIO;
285
286                         r = sd_bus_message_append_array(reply, 'y', &in_addr.in, sizeof(in_addr.in));
287                         break;
288
289                 case AF_INET6:
290                         if (n != sizeof(struct in6_addr) + sizeof(family))
291                                 return -EIO;
292
293                         r = sd_bus_message_append_array(reply, 'y', &in_addr.in6, sizeof(in_addr.in6));
294                         break;
295                 }
296                 if (r < 0)
297                         return r;
298
299                 r = sd_bus_message_close_container(reply);
300                 if (r < 0)
301                         return r;
302         }
303
304         r = wait_for_terminate(child, &si);
305         if (r < 0)
306                 return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
307         if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
308                 return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
309
310         r = sd_bus_message_close_container(reply);
311         if (r < 0)
312                 return r;
313
314         return sd_bus_send(bus, reply, NULL);
315 }
316
317 int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
318         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
319         _cleanup_close_ int mntns_fd = -1, root_fd = -1;
320         _cleanup_close_pair_ int pair[2] = { -1, -1 };
321         _cleanup_strv_free_ char **l = NULL;
322         _cleanup_fclose_ FILE *f = NULL;
323         Machine *m = userdata;
324         char **k, **v;
325         siginfo_t si;
326         pid_t child;
327         int r;
328
329         assert(bus);
330         assert(message);
331         assert(m);
332
333         if (m->class != MACHINE_CONTAINER)
334                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines.");
335
336         r = namespace_open(m->leader, NULL, &mntns_fd, NULL, &root_fd);
337         if (r < 0)
338                 return r;
339
340         if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
341                 return -errno;
342
343         child = fork();
344         if (child < 0)
345                 return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
346
347         if (child == 0) {
348                 _cleanup_close_ int fd = -1;
349
350                 pair[0] = safe_close(pair[0]);
351
352                 r = namespace_enter(-1, mntns_fd, -1, root_fd);
353                 if (r < 0)
354                         _exit(EXIT_FAILURE);
355
356                 fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
357                 if (fd < 0) {
358                         fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
359                         if (fd < 0)
360                                 _exit(EXIT_FAILURE);
361                 }
362
363                 r = copy_bytes(fd, pair[1], (off_t) -1, false);
364                 if (r < 0)
365                         _exit(EXIT_FAILURE);
366
367                 _exit(EXIT_SUCCESS);
368         }
369
370         pair[1] = safe_close(pair[1]);
371
372         f = fdopen(pair[0], "re");
373         if (!f)
374                 return -errno;
375
376         pair[0] = -1;
377
378         r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
379         if (r < 0)
380                 return r;
381
382         r = wait_for_terminate(child, &si);
383         if (r < 0)
384                 return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
385         if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
386                 return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
387
388         r = sd_bus_message_new_method_return(message, &reply);
389         if (r < 0)
390                 return r;
391
392         r = sd_bus_message_open_container(reply, 'a', "{ss}");
393         if (r < 0)
394                 return r;
395
396         STRV_FOREACH_PAIR(k, v, l) {
397                 r = sd_bus_message_append(reply, "{ss}", *k, *v);
398                 if (r < 0)
399                         return r;
400         }
401
402         r = sd_bus_message_close_container(reply);
403         if (r < 0)
404                 return r;
405
406         return sd_bus_send(bus, reply, NULL);
407 }
408
409 int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
410         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
411         _cleanup_free_ char *pty_name = NULL;
412         _cleanup_close_ int master = -1;
413         Machine *m = userdata;
414         int r;
415
416         assert(bus);
417         assert(message);
418         assert(m);
419
420         if (m->class != MACHINE_CONTAINER)
421                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening pseudo TTYs is only supported on container machines.");
422
423         master = openpt_in_namespace(m->leader, O_RDWR|O_NOCTTY|O_CLOEXEC);
424         if (master < 0)
425                 return master;
426
427         r = ptsname_malloc(master, &pty_name);
428         if (r < 0)
429                 return r;
430
431         r = sd_bus_message_new_method_return(message, &reply);
432         if (r < 0)
433                 return r;
434
435         r = sd_bus_message_append(reply, "hs", master, pty_name);
436         if (r < 0)
437                 return r;
438
439         return sd_bus_send(bus, reply, NULL);
440 }
441
442 int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
443         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
444         _cleanup_free_ char *pty_name = NULL, *getty = NULL;
445         _cleanup_bus_unref_ sd_bus *container_bus = NULL;
446         _cleanup_close_ int master = -1;
447         Machine *m = userdata;
448         const char *p;
449         int r;
450
451         if (m->class != MACHINE_CONTAINER)
452                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening logins is only supported on container machines.");
453
454         r = bus_verify_polkit_async(
455                         message,
456                         CAP_SYS_ADMIN,
457                         "org.freedesktop.machine1.login",
458                         false,
459                         &m->manager->polkit_registry,
460                         error);
461         if (r < 0)
462                 return r;
463         if (r == 0)
464                 return 1; /* Will call us back */
465
466         master = openpt_in_namespace(m->leader, O_RDWR|O_NOCTTY|O_CLOEXEC);
467         if (master < 0)
468                 return master;
469
470         r = ptsname_malloc(master, &pty_name);
471         if (r < 0)
472                 return r;
473
474         p = path_startswith(pty_name, "/dev/pts/");
475         if (!p)
476                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
477
478         if (unlockpt(master) < 0)
479                 return -errno;
480
481         r = sd_bus_new(&container_bus);
482         if (r < 0)
483                 return r;
484
485 #ifdef ENABLE_KDBUS
486         asprintf(&container_bus->address, "x-machine-kernel:pid=" PID_FMT ";x-machine-unix:pid=" PID_FMT, m->leader, m->leader);
487 #else
488         asprintf(&container_bus->address, "x-machine-kernel:pid=" PID_FMT, m->leader);
489 #endif
490         if (!container_bus->address)
491                 return log_oom();
492
493         container_bus->bus_client = true;
494         container_bus->trusted = false;
495         container_bus->is_system = true;
496
497         r = sd_bus_start(container_bus);
498         if (r < 0)
499                 return r;
500
501         getty = strjoin("container-getty@", p, ".service", NULL);
502         if (!getty)
503                 return log_oom();
504
505         r = sd_bus_call_method(
506                         container_bus,
507                         "org.freedesktop.systemd1",
508                         "/org/freedesktop/systemd1",
509                         "org.freedesktop.systemd1.Manager",
510                         "StartUnit",
511                         error, NULL,
512                         "ss", getty, "replace");
513         if (r < 0)
514                 return r;
515
516         container_bus = sd_bus_unref(container_bus);
517
518         r = sd_bus_message_new_method_return(message, &reply);
519         if (r < 0)
520                 return r;
521
522         r = sd_bus_message_append(reply, "hs", master, pty_name);
523         if (r < 0)
524                 return r;
525
526         return sd_bus_send(bus, reply, NULL);
527 }
528
529 int bus_machine_method_bind_mount(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
530         _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
531         char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
532         bool mount_slave_created = false, mount_slave_mounted = false,
533                 mount_tmp_created = false, mount_tmp_mounted = false,
534                 mount_outside_created = false, mount_outside_mounted = false;
535         const char *dest, *src;
536         Machine *m = userdata;
537         int read_only, make_directory;
538         pid_t child;
539         siginfo_t si;
540         int r;
541
542         if (m->class != MACHINE_CONTAINER)
543                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Bind mounting is only supported on container machines.");
544
545         r = sd_bus_message_read(message, "ssbb", &src, &dest, &read_only, &make_directory);
546         if (r < 0)
547                 return r;
548
549         if (!path_is_absolute(src) || !path_is_safe(src))
550                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
551
552         if (isempty(dest))
553                 dest = src;
554         else if (!path_is_absolute(dest) || !path_is_safe(dest))
555                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
556
557         /* One day, when bind mounting /proc/self/fd/n works across
558          * namespace boundaries we should rework this logic to make
559          * use of it... */
560
561         p = strjoina("/run/systemd/nspawn/propagate/", m->name, "/");
562         if (laccess(p, F_OK) < 0)
563                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
564
565         /* Our goal is to install a new bind mount into the container,
566            possibly read-only. This is irritatingly complex
567            unfortunately, currently.
568
569            First, we start by creating a private playground in /tmp,
570            that we can mount MS_SLAVE. (Which is necessary, since
571            MS_MOUNT cannot be applied to mounts with MS_SHARED parent
572            mounts.) */
573
574         if (!mkdtemp(mount_slave))
575                 return sd_bus_error_set_errnof(error, errno, "Failed to create playground %s: %m", mount_slave);
576
577         mount_slave_created = true;
578
579         if (mount(mount_slave, mount_slave, NULL, MS_BIND, NULL) < 0) {
580                 r = sd_bus_error_set_errnof(error, errno, "Failed to make bind mount %s: %m", mount_slave);
581                 goto finish;
582         }
583
584         mount_slave_mounted = true;
585
586         if (mount(NULL, mount_slave, NULL, MS_SLAVE, NULL) < 0) {
587                 r = sd_bus_error_set_errnof(error, errno, "Failed to remount slave %s: %m", mount_slave);
588                 goto finish;
589         }
590
591         /* Second, we mount the source directory to a directory inside
592            of our MS_SLAVE playground. */
593         mount_tmp = strjoina(mount_slave, "/mount");
594         if (mkdir(mount_tmp, 0700) < 0) {
595                 r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
596                 goto finish;
597         }
598
599         mount_tmp_created = true;
600
601         if (mount(src, mount_tmp, NULL, MS_BIND, NULL) < 0) {
602                 r = sd_bus_error_set_errnof(error, errno, "Failed to overmount %s: %m", mount_tmp);
603                 goto finish;
604         }
605
606         mount_tmp_mounted = true;
607
608         /* Third, we remount the new bind mount read-only if requested. */
609         if (read_only)
610                 if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
611                         r = sd_bus_error_set_errnof(error, errno, "Failed to remount read-only %s: %m", mount_tmp);
612                         goto finish;
613                 }
614
615         /* Fourth, we move the new bind mount into the propagation
616          * directory. This way it will appear there read-only
617          * right-away. */
618
619         mount_outside = strjoina("/run/systemd/nspawn/propagate/", m->name, "/XXXXXX");
620         if (!mkdtemp(mount_outside)) {
621                 r = sd_bus_error_set_errnof(error, errno, "Cannot create propagation directory %s: %m", mount_outside);
622                 goto finish;
623         }
624
625         mount_outside_created = true;
626
627         if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
628                 r = sd_bus_error_set_errnof(error, errno, "Failed to move %s to %s: %m", mount_tmp, mount_outside);
629                 goto finish;
630         }
631
632         mount_outside_mounted = true;
633         mount_tmp_mounted = false;
634
635         (void) rmdir(mount_tmp);
636         mount_tmp_created = false;
637
638         (void) umount(mount_slave);
639         mount_slave_mounted = false;
640
641         (void) rmdir(mount_slave);
642         mount_slave_created = false;
643
644         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) {
645                 r = sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
646                 goto finish;
647         }
648
649         child = fork();
650         if (child < 0) {
651                 r = sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
652                 goto finish;
653         }
654
655         if (child == 0) {
656                 const char *mount_inside;
657                 int mntfd;
658                 const char *q;
659
660                 errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
661
662                 q = procfs_file_alloca(m->leader, "ns/mnt");
663                 mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
664                 if (mntfd < 0) {
665                         r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
666                         goto child_fail;
667                 }
668
669                 if (setns(mntfd, CLONE_NEWNS) < 0) {
670                         r = log_error_errno(errno, "Failed to join namespace of leader: %m");
671                         goto child_fail;
672                 }
673
674                 if (make_directory)
675                         (void) mkdir_p(dest, 0755);
676
677                 /* Fifth, move the mount to the right place inside */
678                 mount_inside = strjoina("/run/systemd/nspawn/incoming/", basename(mount_outside));
679                 if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
680                         r = log_error_errno(errno, "Failed to mount: %m");
681                         goto child_fail;
682                 }
683
684                 _exit(EXIT_SUCCESS);
685
686         child_fail:
687                 (void) write(errno_pipe_fd[1], &r, sizeof(r));
688                 errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
689
690                 _exit(EXIT_FAILURE);
691         }
692
693         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
694
695         r = wait_for_terminate(child, &si);
696         if (r < 0) {
697                 r = sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
698                 goto finish;
699         }
700         if (si.si_code != CLD_EXITED) {
701                 r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
702                 goto finish;
703         }
704         if (si.si_status != EXIT_SUCCESS) {
705
706                 if (read(errno_pipe_fd[0], &r, sizeof(r)) == sizeof(r))
707                         r = sd_bus_error_set_errnof(error, r, "Failed to mount: %m");
708                 else
709                         r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client failed.");
710                 goto finish;
711         }
712
713         r = sd_bus_reply_method_return(message, NULL);
714
715 finish:
716         if (mount_outside_mounted)
717                 umount(mount_outside);
718         if (mount_outside_created)
719                 rmdir(mount_outside);
720
721         if (mount_tmp_mounted)
722                 umount(mount_tmp);
723         if (mount_tmp_created)
724                 rmdir(mount_tmp);
725
726         if (mount_slave_mounted)
727                 umount(mount_slave);
728         if (mount_slave_created)
729                 rmdir(mount_slave);
730
731         return r;
732 }
733
734 static int machine_operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
735         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
736         MachineOperation *o = userdata;
737         int r;
738
739         assert(o);
740         assert(si);
741
742         o->pid = 0;
743
744         if (si->si_code != CLD_EXITED) {
745                 r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
746                 goto fail;
747         }
748
749         if (si->si_status != EXIT_SUCCESS) {
750                 if (read(o->errno_fd, &r, sizeof(r)) == sizeof(r))
751                         r = sd_bus_error_set_errnof(&error, r, "%m");
752                 else
753                         r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client failed.");
754
755                 goto fail;
756         }
757
758         r = sd_bus_reply_method_return(o->message, NULL);
759         if (r < 0)
760                 log_error_errno(r, "Failed to reply to message: %m");
761
762         machine_operation_unref(o);
763         return 0;
764
765 fail:
766         r = sd_bus_reply_method_error(o->message, &error);
767         if (r < 0)
768                 log_error_errno(r, "Failed to reply to message: %m");
769
770         machine_operation_unref(o);
771         return 0;
772 }
773
774 int bus_machine_method_copy(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
775         const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
776         _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
777         _cleanup_close_ int hostfd = -1;
778         Machine *m = userdata;
779         MachineOperation *o;
780         bool copy_from;
781         pid_t child;
782         char *t;
783         int r;
784
785         if (m->n_operations >= MACHINE_OPERATIONS_MAX)
786                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing copies.");
787
788         if (m->class != MACHINE_CONTAINER)
789                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Copying files is only supported on container machines.");
790
791         r = sd_bus_message_read(message, "ss", &src, &dest);
792         if (r < 0)
793                 return r;
794
795         if (!path_is_absolute(src) || !path_is_safe(src))
796                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
797
798         if (isempty(dest))
799                 dest = src;
800         else if (!path_is_absolute(dest) || !path_is_safe(dest))
801                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
802
803         copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
804
805         if (copy_from) {
806                 container_path = src;
807                 host_path = dest;
808         } else {
809                 host_path = src;
810                 container_path = dest;
811         }
812
813         host_basename = basename(host_path);
814         t = strdupa(host_path);
815         host_dirname = dirname(t);
816
817         container_basename = basename(container_path);
818         t = strdupa(container_path);
819         container_dirname = dirname(t);
820
821         hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
822         if (r < 0)
823                 return sd_bus_error_set_errnof(error, errno, "Failed to open host directory %s: %m", host_dirname);
824
825         if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
826                 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
827
828         child = fork();
829         if (child < 0)
830                 return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
831
832         if (child == 0) {
833                 int containerfd;
834                 const char *q;
835                 int mntfd;
836
837                 errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
838
839                 q = procfs_file_alloca(m->leader, "ns/mnt");
840                 mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
841                 if (mntfd < 0) {
842                         r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
843                         goto child_fail;
844                 }
845
846                 if (setns(mntfd, CLONE_NEWNS) < 0) {
847                         r = log_error_errno(errno, "Failed to join namespace of leader: %m");
848                         goto child_fail;
849                 }
850
851                 containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
852                 if (containerfd < 0) {
853                         r = log_error_errno(errno, "Failed top open destination directory: %m");
854                         goto child_fail;
855                 }
856
857                 if (copy_from)
858                         r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
859                 else
860                         r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
861
862                 hostfd = safe_close(hostfd);
863                 containerfd = safe_close(containerfd);
864
865                 if (r < 0) {
866                         r = log_error_errno(r, "Failed to copy tree: %m");
867                         goto child_fail;
868                 }
869
870                 _exit(EXIT_SUCCESS);
871
872         child_fail:
873                 (void) write(errno_pipe_fd[1], &r, sizeof(r));
874                 errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
875
876                 _exit(EXIT_FAILURE);
877         }
878
879         errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
880
881         /* Copying might take a while, hence install a watch the
882          * child, and return */
883
884         o = new0(MachineOperation, 1);
885         if (!o)
886                 return log_oom();
887
888         o->pid = child;
889         o->message = sd_bus_message_ref(message);
890         o->errno_fd = errno_pipe_fd[0];
891         errno_pipe_fd[0] = -1;
892
893         r = sd_event_add_child(m->manager->event, &o->event_source, child, WEXITED, machine_operation_done, o);
894         if (r < 0) {
895                 machine_operation_unref(o);
896                 return log_oom();
897         }
898
899         LIST_PREPEND(operations, m->operations, o);
900         m->n_operations++;
901         o->machine = m;
902
903         return 1;
904 }
905
906 const sd_bus_vtable machine_vtable[] = {
907         SD_BUS_VTABLE_START(0),
908         SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
909         SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, SD_BUS_VTABLE_PROPERTY_CONST),
910         BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Machine, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
911         SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
912         SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
913         SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
914         SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
915         SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
916         SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
917         SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
918         SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
919         SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
920         SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
921         SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
922         SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
923         SD_BUS_METHOD("OpenPTY", NULL, "hs", bus_machine_method_open_pty, 0),
924         SD_BUS_METHOD("OpenLogin", NULL, "hs", bus_machine_method_open_login, SD_BUS_VTABLE_UNPRIVILEGED),
925         SD_BUS_METHOD("BindMount", "ssbb", NULL, bus_machine_method_bind_mount, 0),
926         SD_BUS_METHOD("CopyFrom", "ss", NULL, bus_machine_method_copy, 0),
927         SD_BUS_METHOD("CopyTo", "ss", NULL, bus_machine_method_copy, 0),
928         SD_BUS_VTABLE_END
929 };
930
931 int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
932         Manager *m = userdata;
933         Machine *machine;
934         int r;
935
936         assert(bus);
937         assert(path);
938         assert(interface);
939         assert(found);
940         assert(m);
941
942         if (streq(path, "/org/freedesktop/machine1/machine/self")) {
943                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
944                 sd_bus_message *message;
945                 pid_t pid;
946
947                 message = sd_bus_get_current_message(bus);
948                 if (!message)
949                         return 0;
950
951                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
952                 if (r < 0)
953                         return r;
954
955                 r = sd_bus_creds_get_pid(creds, &pid);
956                 if (r < 0)
957                         return r;
958
959                 r = manager_get_machine_by_pid(m, pid, &machine);
960                 if (r <= 0)
961                         return 0;
962         } else {
963                 _cleanup_free_ char *e = NULL;
964                 const char *p;
965
966                 p = startswith(path, "/org/freedesktop/machine1/machine/");
967                 if (!p)
968                         return 0;
969
970                 e = bus_label_unescape(p);
971                 if (!e)
972                         return -ENOMEM;
973
974                 machine = hashmap_get(m->machines, e);
975                 if (!machine)
976                         return 0;
977         }
978
979         *found = machine;
980         return 1;
981 }
982
983 char *machine_bus_path(Machine *m) {
984         _cleanup_free_ char *e = NULL;
985
986         assert(m);
987
988         e = bus_label_escape(m->name);
989         if (!e)
990                 return NULL;
991
992         return strappend("/org/freedesktop/machine1/machine/", e);
993 }
994
995 int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
996         _cleanup_strv_free_ char **l = NULL;
997         Machine *machine = NULL;
998         Manager *m = userdata;
999         Iterator i;
1000         int r;
1001
1002         assert(bus);
1003         assert(path);
1004         assert(nodes);
1005
1006         HASHMAP_FOREACH(machine, m->machines, i) {
1007                 char *p;
1008
1009                 p = machine_bus_path(machine);
1010                 if (!p)
1011                         return -ENOMEM;
1012
1013                 r = strv_consume(&l, p);
1014                 if (r < 0)
1015                         return r;
1016         }
1017
1018         *nodes = l;
1019         l = NULL;
1020
1021         return 1;
1022 }
1023
1024 int machine_send_signal(Machine *m, bool new_machine) {
1025         _cleanup_free_ char *p = NULL;
1026
1027         assert(m);
1028
1029         p = machine_bus_path(m);
1030         if (!p)
1031                 return -ENOMEM;
1032
1033         return sd_bus_emit_signal(
1034                         m->manager->bus,
1035                         "/org/freedesktop/machine1",
1036                         "org.freedesktop.machine1.Manager",
1037                         new_machine ? "MachineNew" : "MachineRemoved",
1038                         "so", m->name, p);
1039 }
1040
1041 int machine_send_create_reply(Machine *m, sd_bus_error *error) {
1042         _cleanup_bus_message_unref_ sd_bus_message *c = NULL;
1043         _cleanup_free_ char *p = NULL;
1044
1045         assert(m);
1046
1047         if (!m->create_message)
1048                 return 0;
1049
1050         c = m->create_message;
1051         m->create_message = NULL;
1052
1053         if (error)
1054                 return sd_bus_reply_method_error(c, error);
1055
1056         /* Update the machine state file before we notify the client
1057          * about the result. */
1058         machine_save(m);
1059
1060         p = machine_bus_path(m);
1061         if (!p)
1062                 return -ENOMEM;
1063
1064         return sd_bus_reply_method_return(c, "o", p);
1065 }