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