]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/machine/machined-dbus.c
Merge pull request #8341 from yuwata/test-execute-ambient
[thirdparty/systemd.git] / src / machine / machined-dbus.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2011 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "sd-id128.h"
26
27 #include "alloc-util.h"
28 #include "btrfs-util.h"
29 #include "bus-common-errors.h"
30 #include "bus-util.h"
31 #include "cgroup-util.h"
32 #include "fd-util.h"
33 #include "fileio.h"
34 #include "format-util.h"
35 #include "hostname-util.h"
36 #include "image-dbus.h"
37 #include "io-util.h"
38 #include "machine-dbus.h"
39 #include "machine-image.h"
40 #include "machine-pool.h"
41 #include "machined.h"
42 #include "path-util.h"
43 #include "process-util.h"
44 #include "stdio-util.h"
45 #include "strv.h"
46 #include "unit-name.h"
47 #include "user-util.h"
48
49 static int property_get_pool_path(
50 sd_bus *bus,
51 const char *path,
52 const char *interface,
53 const char *property,
54 sd_bus_message *reply,
55 void *userdata,
56 sd_bus_error *error) {
57
58 assert(bus);
59 assert(reply);
60
61 return sd_bus_message_append(reply, "s", "/var/lib/machines");
62 }
63
64 static int property_get_pool_usage(
65 sd_bus *bus,
66 const char *path,
67 const char *interface,
68 const char *property,
69 sd_bus_message *reply,
70 void *userdata,
71 sd_bus_error *error) {
72
73 _cleanup_close_ int fd = -1;
74 uint64_t usage = (uint64_t) -1;
75 struct stat st;
76
77 assert(bus);
78 assert(reply);
79
80 /* We try to read the quota info from /var/lib/machines, as
81 * well as the usage of the loopback file
82 * /var/lib/machines.raw, and pick the larger value. */
83
84 fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
85 if (fd >= 0) {
86 BtrfsQuotaInfo q;
87
88 if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
89 usage = q.referenced;
90 }
91
92 if (stat("/var/lib/machines.raw", &st) >= 0) {
93 if (usage == (uint64_t) -1 || st.st_blocks * 512ULL > usage)
94 usage = st.st_blocks * 512ULL;
95 }
96
97 return sd_bus_message_append(reply, "t", usage);
98 }
99
100 static int property_get_pool_limit(
101 sd_bus *bus,
102 const char *path,
103 const char *interface,
104 const char *property,
105 sd_bus_message *reply,
106 void *userdata,
107 sd_bus_error *error) {
108
109 _cleanup_close_ int fd = -1;
110 uint64_t size = (uint64_t) -1;
111 struct stat st;
112
113 assert(bus);
114 assert(reply);
115
116 /* We try to read the quota limit from /var/lib/machines, as
117 * well as the size of the loopback file
118 * /var/lib/machines.raw, and pick the smaller value. */
119
120 fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
121 if (fd >= 0) {
122 BtrfsQuotaInfo q;
123
124 if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
125 size = q.referenced_max;
126 }
127
128 if (stat("/var/lib/machines.raw", &st) >= 0) {
129 if (size == (uint64_t) -1 || (uint64_t) st.st_size < size)
130 size = st.st_size;
131 }
132
133 return sd_bus_message_append(reply, "t", size);
134 }
135
136 static int method_get_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
137 _cleanup_free_ char *p = NULL;
138 Manager *m = userdata;
139 Machine *machine;
140 const char *name;
141 int r;
142
143 assert(message);
144 assert(m);
145
146 r = sd_bus_message_read(message, "s", &name);
147 if (r < 0)
148 return r;
149
150 machine = hashmap_get(m->machines, name);
151 if (!machine)
152 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
153
154 p = machine_bus_path(machine);
155 if (!p)
156 return -ENOMEM;
157
158 return sd_bus_reply_method_return(message, "o", p);
159 }
160
161 static int method_get_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
162 _cleanup_free_ char *p = NULL;
163 Manager *m = userdata;
164 const char *name;
165 int r;
166
167 assert(message);
168 assert(m);
169
170 r = sd_bus_message_read(message, "s", &name);
171 if (r < 0)
172 return r;
173
174 r = image_find(name, NULL);
175 if (r == 0)
176 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
177 if (r < 0)
178 return r;
179
180 p = image_bus_path(name);
181 if (!p)
182 return -ENOMEM;
183
184 return sd_bus_reply_method_return(message, "o", p);
185 }
186
187 static int method_get_machine_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
188 _cleanup_free_ char *p = NULL;
189 Manager *m = userdata;
190 Machine *machine = NULL;
191 pid_t pid;
192 int r;
193
194 assert(message);
195 assert(m);
196
197 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
198
199 r = sd_bus_message_read(message, "u", &pid);
200 if (r < 0)
201 return r;
202
203 if (pid < 0)
204 return -EINVAL;
205
206 if (pid == 0) {
207 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
208
209 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
210 if (r < 0)
211 return r;
212
213 r = sd_bus_creds_get_pid(creds, &pid);
214 if (r < 0)
215 return r;
216 }
217
218 r = manager_get_machine_by_pid(m, pid, &machine);
219 if (r < 0)
220 return r;
221 if (!machine)
222 return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
223
224 p = machine_bus_path(machine);
225 if (!p)
226 return -ENOMEM;
227
228 return sd_bus_reply_method_return(message, "o", p);
229 }
230
231 static int method_list_machines(sd_bus_message *message, void *userdata, sd_bus_error *error) {
232 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
233 Manager *m = userdata;
234 Machine *machine;
235 Iterator i;
236 int r;
237
238 assert(message);
239 assert(m);
240
241 r = sd_bus_message_new_method_return(message, &reply);
242 if (r < 0)
243 return sd_bus_error_set_errno(error, r);
244
245 r = sd_bus_message_open_container(reply, 'a', "(ssso)");
246 if (r < 0)
247 return sd_bus_error_set_errno(error, r);
248
249 HASHMAP_FOREACH(machine, m->machines, i) {
250 _cleanup_free_ char *p = NULL;
251
252 p = machine_bus_path(machine);
253 if (!p)
254 return -ENOMEM;
255
256 r = sd_bus_message_append(reply, "(ssso)",
257 machine->name,
258 strempty(machine_class_to_string(machine->class)),
259 machine->service,
260 p);
261 if (r < 0)
262 return sd_bus_error_set_errno(error, r);
263 }
264
265 r = sd_bus_message_close_container(reply);
266 if (r < 0)
267 return sd_bus_error_set_errno(error, r);
268
269 return sd_bus_send(NULL, reply, NULL);
270 }
271
272 static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
273 const char *name, *service, *class, *root_directory;
274 const int32_t *netif = NULL;
275 MachineClass c;
276 uint32_t leader;
277 sd_id128_t id;
278 const void *v;
279 Machine *m;
280 size_t n, n_netif = 0;
281 int r;
282
283 assert(manager);
284 assert(message);
285 assert(_m);
286
287 r = sd_bus_message_read(message, "s", &name);
288 if (r < 0)
289 return r;
290 if (!machine_name_is_valid(name))
291 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine name");
292
293 r = sd_bus_message_read_array(message, 'y', &v, &n);
294 if (r < 0)
295 return r;
296 if (n == 0)
297 id = SD_ID128_NULL;
298 else if (n == 16)
299 memcpy(&id, v, n);
300 else
301 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine ID parameter");
302
303 r = sd_bus_message_read(message, "ssus", &service, &class, &leader, &root_directory);
304 if (r < 0)
305 return r;
306
307 if (read_network) {
308 size_t i;
309
310 r = sd_bus_message_read_array(message, 'i', (const void**) &netif, &n_netif);
311 if (r < 0)
312 return r;
313
314 n_netif /= sizeof(int32_t);
315
316 for (i = 0; i < n_netif; i++) {
317 if (netif[i] <= 0)
318 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
319 }
320 }
321
322 if (isempty(class))
323 c = _MACHINE_CLASS_INVALID;
324 else {
325 c = machine_class_from_string(class);
326 if (c < 0)
327 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid machine class parameter");
328 }
329
330 if (leader == 1)
331 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid leader PID");
332
333 if (!isempty(root_directory) && !path_is_absolute(root_directory))
334 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
335
336 if (leader == 0) {
337 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
338
339 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
340 if (r < 0)
341 return r;
342
343 assert_cc(sizeof(uint32_t) == sizeof(pid_t));
344
345 r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
346 if (r < 0)
347 return r;
348 }
349
350 if (hashmap_get(manager->machines, name))
351 return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
352
353 r = manager_add_machine(manager, name, &m);
354 if (r < 0)
355 return r;
356
357 m->leader = leader;
358 m->class = c;
359 m->id = id;
360
361 if (!isempty(service)) {
362 m->service = strdup(service);
363 if (!m->service) {
364 r = -ENOMEM;
365 goto fail;
366 }
367 }
368
369 if (!isempty(root_directory)) {
370 m->root_directory = strdup(root_directory);
371 if (!m->root_directory) {
372 r = -ENOMEM;
373 goto fail;
374 }
375 }
376
377 if (n_netif > 0) {
378 assert_cc(sizeof(int32_t) == sizeof(int));
379 m->netif = memdup(netif, sizeof(int32_t) * n_netif);
380 if (!m->netif) {
381 r = -ENOMEM;
382 goto fail;
383 }
384
385 m->n_netif = n_netif;
386 }
387
388 *_m = m;
389
390 return 1;
391
392 fail:
393 machine_add_to_gc_queue(m);
394 return r;
395 }
396
397 static int method_create_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
398 Manager *manager = userdata;
399 Machine *m = NULL;
400 int r;
401
402 assert(message);
403 assert(manager);
404
405 r = method_create_or_register_machine(manager, message, read_network, &m, error);
406 if (r < 0)
407 return r;
408
409 r = sd_bus_message_enter_container(message, 'a', "(sv)");
410 if (r < 0)
411 goto fail;
412
413 r = machine_start(m, message, error);
414 if (r < 0)
415 goto fail;
416
417 m->create_message = sd_bus_message_ref(message);
418 return 1;
419
420 fail:
421 machine_add_to_gc_queue(m);
422 return r;
423 }
424
425 static int method_create_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
426 return method_create_machine_internal(message, true, userdata, error);
427 }
428
429 static int method_create_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
430 return method_create_machine_internal(message, false, userdata, error);
431 }
432
433 static int method_register_machine_internal(sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
434 Manager *manager = userdata;
435 _cleanup_free_ char *p = NULL;
436 Machine *m = NULL;
437 int r;
438
439 assert(message);
440 assert(manager);
441
442 r = method_create_or_register_machine(manager, message, read_network, &m, error);
443 if (r < 0)
444 return r;
445
446 r = cg_pid_get_unit(m->leader, &m->unit);
447 if (r < 0) {
448 r = sd_bus_error_set_errnof(error, r,
449 "Failed to determine unit of process "PID_FMT" : %m",
450 m->leader);
451 goto fail;
452 }
453
454 r = machine_start(m, NULL, error);
455 if (r < 0)
456 goto fail;
457
458 p = machine_bus_path(m);
459 if (!p) {
460 r = -ENOMEM;
461 goto fail;
462 }
463
464 return sd_bus_reply_method_return(message, "o", p);
465
466 fail:
467 machine_add_to_gc_queue(m);
468 return r;
469 }
470
471 static int method_register_machine_with_network(sd_bus_message *message, void *userdata, sd_bus_error *error) {
472 return method_register_machine_internal(message, true, userdata, error);
473 }
474
475 static int method_register_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
476 return method_register_machine_internal(message, false, userdata, error);
477 }
478
479 static int method_terminate_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
480 Manager *m = userdata;
481 Machine *machine;
482 const char *name;
483 int r;
484
485 assert(message);
486 assert(m);
487
488 r = sd_bus_message_read(message, "s", &name);
489 if (r < 0)
490 return sd_bus_error_set_errno(error, r);
491
492 machine = hashmap_get(m->machines, name);
493 if (!machine)
494 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
495
496 return bus_machine_method_terminate(message, machine, error);
497 }
498
499 static int method_kill_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
500 Manager *m = userdata;
501 Machine *machine;
502 const char *name;
503 int r;
504
505 assert(message);
506 assert(m);
507
508 r = sd_bus_message_read(message, "s", &name);
509 if (r < 0)
510 return sd_bus_error_set_errno(error, r);
511
512 machine = hashmap_get(m->machines, name);
513 if (!machine)
514 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
515
516 return bus_machine_method_kill(message, machine, error);
517 }
518
519 static int method_get_machine_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) {
520 Manager *m = userdata;
521 Machine *machine;
522 const char *name;
523 int r;
524
525 assert(message);
526 assert(m);
527
528 r = sd_bus_message_read(message, "s", &name);
529 if (r < 0)
530 return sd_bus_error_set_errno(error, r);
531
532 machine = hashmap_get(m->machines, name);
533 if (!machine)
534 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
535
536 return bus_machine_method_get_addresses(message, machine, error);
537 }
538
539 static int method_get_machine_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
540 Manager *m = userdata;
541 Machine *machine;
542 const char *name;
543 int r;
544
545 assert(message);
546 assert(m);
547
548 r = sd_bus_message_read(message, "s", &name);
549 if (r < 0)
550 return sd_bus_error_set_errno(error, r);
551
552 machine = hashmap_get(m->machines, name);
553 if (!machine)
554 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
555
556 return bus_machine_method_get_os_release(message, machine, error);
557 }
558
559 static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
561 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
562 Manager *m = userdata;
563 Image *image;
564 Iterator i;
565 int r;
566
567 assert(message);
568 assert(m);
569
570 images = hashmap_new(&string_hash_ops);
571 if (!images)
572 return -ENOMEM;
573
574 r = image_discover(images);
575 if (r < 0)
576 return r;
577
578 r = sd_bus_message_new_method_return(message, &reply);
579 if (r < 0)
580 return r;
581
582 r = sd_bus_message_open_container(reply, 'a', "(ssbttto)");
583 if (r < 0)
584 return r;
585
586 HASHMAP_FOREACH(image, images, i) {
587 _cleanup_free_ char *p = NULL;
588
589 p = image_bus_path(image->name);
590 if (!p)
591 return -ENOMEM;
592
593 r = sd_bus_message_append(reply, "(ssbttto)",
594 image->name,
595 image_type_to_string(image->type),
596 image->read_only,
597 image->crtime,
598 image->mtime,
599 image->usage,
600 p);
601 if (r < 0)
602 return r;
603 }
604
605 r = sd_bus_message_close_container(reply);
606 if (r < 0)
607 return r;
608
609 return sd_bus_send(NULL, reply, NULL);
610 }
611
612 static int method_open_machine_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
613 Manager *m = userdata;
614 Machine *machine;
615 const char *name;
616 int r;
617
618 assert(message);
619 assert(m);
620
621 r = sd_bus_message_read(message, "s", &name);
622 if (r < 0)
623 return sd_bus_error_set_errno(error, r);
624
625 machine = hashmap_get(m->machines, name);
626 if (!machine)
627 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
628
629 return bus_machine_method_open_pty(message, machine, error);
630 }
631
632 static int method_open_machine_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
633 Manager *m = userdata;
634 Machine *machine;
635 const char *name;
636 int r;
637
638 assert(message);
639 assert(m);
640
641 r = sd_bus_message_read(message, "s", &name);
642 if (r < 0)
643 return r;
644
645 machine = hashmap_get(m->machines, name);
646 if (!machine)
647 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
648
649 return bus_machine_method_open_login(message, machine, error);
650 }
651
652 static int method_open_machine_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
653 Manager *m = userdata;
654 Machine *machine;
655 const char *name;
656
657 int r;
658
659 assert(message);
660 assert(m);
661
662 r = sd_bus_message_read(message, "s", &name);
663 if (r < 0)
664 return r;
665
666 machine = hashmap_get(m->machines, name);
667 if (!machine)
668 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
669
670 return bus_machine_method_open_shell(message, machine, error);
671 }
672
673 static int method_bind_mount_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
674 Manager *m = userdata;
675 Machine *machine;
676 const char *name;
677 int r;
678
679 assert(message);
680 assert(m);
681
682 r = sd_bus_message_read(message, "s", &name);
683 if (r < 0)
684 return r;
685
686 machine = hashmap_get(m->machines, name);
687 if (!machine)
688 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
689
690 return bus_machine_method_bind_mount(message, machine, error);
691 }
692
693 static int method_copy_machine(sd_bus_message *message, void *userdata, sd_bus_error *error) {
694 Manager *m = userdata;
695 Machine *machine;
696 const char *name;
697 int r;
698
699 assert(message);
700 assert(m);
701
702 r = sd_bus_message_read(message, "s", &name);
703 if (r < 0)
704 return r;
705
706 machine = hashmap_get(m->machines, name);
707 if (!machine)
708 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
709
710 return bus_machine_method_copy(message, machine, error);
711 }
712
713 static int method_open_machine_root_directory(sd_bus_message *message, void *userdata, sd_bus_error *error) {
714 Manager *m = userdata;
715 Machine *machine;
716 const char *name;
717 int r;
718
719 assert(message);
720 assert(m);
721
722 r = sd_bus_message_read(message, "s", &name);
723 if (r < 0)
724 return r;
725
726 machine = hashmap_get(m->machines, name);
727 if (!machine)
728 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
729
730 return bus_machine_method_open_root_directory(message, machine, error);
731 }
732
733 static int method_get_machine_uid_shift(sd_bus_message *message, void *userdata, sd_bus_error *error) {
734 Manager *m = userdata;
735 Machine *machine;
736 const char *name;
737 int r;
738
739 assert(message);
740 assert(m);
741
742 r = sd_bus_message_read(message, "s", &name);
743 if (r < 0)
744 return r;
745
746 machine = hashmap_get(m->machines, name);
747 if (!machine)
748 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
749
750 return bus_machine_method_get_uid_shift(message, machine, error);
751 }
752
753 static int method_remove_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
754 _cleanup_(image_unrefp) Image* i = NULL;
755 const char *name;
756 int r;
757
758 assert(message);
759
760 r = sd_bus_message_read(message, "s", &name);
761 if (r < 0)
762 return r;
763
764 if (!image_name_is_valid(name))
765 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
766
767 r = image_find(name, &i);
768 if (r < 0)
769 return r;
770 if (r == 0)
771 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
772
773 i->userdata = userdata;
774 return bus_image_method_remove(message, i, error);
775 }
776
777 static int method_rename_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
778 _cleanup_(image_unrefp) Image* i = NULL;
779 const char *old_name;
780 int r;
781
782 assert(message);
783
784 r = sd_bus_message_read(message, "s", &old_name);
785 if (r < 0)
786 return r;
787
788 if (!image_name_is_valid(old_name))
789 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
790
791 r = image_find(old_name, &i);
792 if (r < 0)
793 return r;
794 if (r == 0)
795 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
796
797 i->userdata = userdata;
798 return bus_image_method_rename(message, i, error);
799 }
800
801 static int method_clone_image(sd_bus_message *message, void *userdata, sd_bus_error *error) {
802 _cleanup_(image_unrefp) Image *i = NULL;
803 const char *old_name;
804 int r;
805
806 assert(message);
807
808 r = sd_bus_message_read(message, "s", &old_name);
809 if (r < 0)
810 return r;
811
812 if (!image_name_is_valid(old_name))
813 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
814
815 r = image_find(old_name, &i);
816 if (r < 0)
817 return r;
818 if (r == 0)
819 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", old_name);
820
821 i->userdata = userdata;
822 return bus_image_method_clone(message, i, error);
823 }
824
825 static int method_mark_image_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error) {
826 _cleanup_(image_unrefp) Image *i = NULL;
827 const char *name;
828 int r;
829
830 assert(message);
831
832 r = sd_bus_message_read(message, "s", &name);
833 if (r < 0)
834 return r;
835
836 if (!image_name_is_valid(name))
837 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
838
839 r = image_find(name, &i);
840 if (r < 0)
841 return r;
842 if (r == 0)
843 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
844
845 i->userdata = userdata;
846 return bus_image_method_mark_read_only(message, i, error);
847 }
848
849 static int method_get_image_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
850 _cleanup_(image_unrefp) Image *i = NULL;
851 const char *name;
852 int r;
853
854 assert(message);
855
856 r = sd_bus_message_read(message, "s", &name);
857 if (r < 0)
858 return r;
859
860 if (!image_name_is_valid(name))
861 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
862
863 r = image_find(name, &i);
864 if (r < 0)
865 return r;
866 if (r == 0)
867 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
868
869 i->userdata = userdata;
870 return bus_image_method_get_hostname(message, i, error);
871 }
872
873 static int method_get_image_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
874 _cleanup_(image_unrefp) Image *i = NULL;
875 const char *name;
876 int r;
877
878 assert(message);
879
880 r = sd_bus_message_read(message, "s", &name);
881 if (r < 0)
882 return r;
883
884 if (!image_name_is_valid(name))
885 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
886
887 r = image_find(name, &i);
888 if (r < 0)
889 return r;
890 if (r == 0)
891 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
892
893 i->userdata = userdata;
894 return bus_image_method_get_machine_id(message, i, error);
895 }
896
897 static int method_get_image_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
898 _cleanup_(image_unrefp) Image *i = NULL;
899 const char *name;
900 int r;
901
902 assert(message);
903
904 r = sd_bus_message_read(message, "s", &name);
905 if (r < 0)
906 return r;
907
908 if (!image_name_is_valid(name))
909 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
910
911 r = image_find(name, &i);
912 if (r < 0)
913 return r;
914 if (r == 0)
915 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
916
917 i->userdata = userdata;
918 return bus_image_method_get_machine_info(message, i, error);
919 }
920
921 static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
922 _cleanup_(image_unrefp) Image *i = NULL;
923 const char *name;
924 int r;
925
926 assert(message);
927
928 r = sd_bus_message_read(message, "s", &name);
929 if (r < 0)
930 return r;
931
932 if (!image_name_is_valid(name))
933 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
934
935 r = image_find(name, &i);
936 if (r < 0)
937 return r;
938 if (r == 0)
939 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
940
941 i->userdata = userdata;
942 return bus_image_method_get_os_release(message, i, error);
943 }
944
945 static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
946 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
947 _cleanup_fclose_ FILE *f = NULL;
948 bool success;
949 size_t n;
950 int r;
951
952 assert(operation);
953 assert(operation->extra_fd >= 0);
954
955 if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
956 return -errno;
957
958 f = fdopen(operation->extra_fd, "re");
959 if (!f)
960 return -errno;
961
962 operation->extra_fd = -1;
963
964 /* The resulting temporary file starts with a boolean value that indicates success or not. */
965 errno = 0;
966 n = fread(&success, 1, sizeof(success), f);
967 if (n != sizeof(success))
968 return ret < 0 ? ret : (errno != 0 ? -errno : -EIO);
969
970 if (ret < 0) {
971 _cleanup_free_ char *name = NULL;
972
973 /* The clean-up operation failed. In this case the resulting temporary file should contain a boolean
974 * set to false followed by the name of the failed image. Let's try to read this and use it for the
975 * error message. If we can't read it, don't mind, and return the naked error. */
976
977 if (success) /* The resulting temporary file could not be updated, ignore it. */
978 return ret;
979
980 r = read_nul_string(f, &name);
981 if (r < 0 || isempty(name)) /* Same here... */
982 return ret;
983
984 return sd_bus_error_set_errnof(error, ret, "Failed to remove image %s: %m", name);
985 }
986
987 assert(success);
988
989 r = sd_bus_message_new_method_return(operation->message, &reply);
990 if (r < 0)
991 return r;
992
993 r = sd_bus_message_open_container(reply, 'a', "(st)");
994 if (r < 0)
995 return r;
996
997 /* On success the resulting temporary file will contain a list of image names that were removed followed by
998 * their size on disk. Let's read that and turn it into a bus message. */
999 for (;;) {
1000 _cleanup_free_ char *name = NULL;
1001 uint64_t size;
1002
1003 r = read_nul_string(f, &name);
1004 if (r < 0)
1005 return r;
1006 if (isempty(name)) /* reached the end */
1007 break;
1008
1009 errno = 0;
1010 n = fread(&size, 1, sizeof(size), f);
1011 if (n != sizeof(size))
1012 return errno != 0 ? -errno : -EIO;
1013
1014 r = sd_bus_message_append(reply, "(st)", name, size);
1015 if (r < 0)
1016 return r;
1017 }
1018
1019 r = sd_bus_message_close_container(reply);
1020 if (r < 0)
1021 return r;
1022
1023 return sd_bus_send(NULL, reply, NULL);
1024 }
1025
1026 static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1027 enum {
1028 REMOVE_ALL,
1029 REMOVE_HIDDEN,
1030 } mode;
1031
1032 _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
1033 _cleanup_close_ int result_fd = -1;
1034 Manager *m = userdata;
1035 Operation *operation;
1036 const char *mm;
1037 pid_t child;
1038 int r;
1039
1040 assert(message);
1041
1042 if (m->n_operations >= OPERATIONS_MAX)
1043 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
1044
1045 r = sd_bus_message_read(message, "s", &mm);
1046 if (r < 0)
1047 return r;
1048
1049 if (streq(mm, "all"))
1050 mode = REMOVE_ALL;
1051 else if (streq(mm, "hidden"))
1052 mode = REMOVE_HIDDEN;
1053 else
1054 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
1055
1056 r = bus_verify_polkit_async(
1057 message,
1058 CAP_SYS_ADMIN,
1059 "org.freedesktop.machine1.manage-machines",
1060 NULL,
1061 false,
1062 UID_INVALID,
1063 &m->polkit_registry,
1064 error);
1065 if (r < 0)
1066 return r;
1067 if (r == 0)
1068 return 1; /* Will call us back */
1069
1070 if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
1071 return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
1072
1073 /* Create a temporary file we can dump information about deleted images into. We use a temporary file for this
1074 * instead of a pipe or so, since this might grow quit large in theory and we don't want to process this
1075 * continuously */
1076 result_fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC);
1077 if (result_fd < 0)
1078 return -errno;
1079
1080 /* This might be a slow operation, run it asynchronously in a background process */
1081 r = safe_fork("(sd-clean)", FORK_RESET_SIGNALS, &child);
1082 if (r < 0)
1083 return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
1084 if (r == 0) {
1085 _cleanup_(image_hashmap_freep) Hashmap *images = NULL;
1086 bool success = true;
1087 Image *image;
1088 Iterator i;
1089 ssize_t l;
1090
1091 errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
1092
1093 images = hashmap_new(&string_hash_ops);
1094 if (!images) {
1095 r = -ENOMEM;
1096 goto child_fail;
1097 }
1098
1099 r = image_discover(images);
1100 if (r < 0)
1101 goto child_fail;
1102
1103 l = write(result_fd, &success, sizeof(success));
1104 if (l < 0) {
1105 r = -errno;
1106 goto child_fail;
1107 }
1108
1109 HASHMAP_FOREACH(image, images, i) {
1110
1111 /* We can't remove vendor images (i.e. those in /usr) */
1112 if (IMAGE_IS_VENDOR(image))
1113 continue;
1114
1115 if (IMAGE_IS_HOST(image))
1116 continue;
1117
1118 if (mode == REMOVE_HIDDEN && !IMAGE_IS_HIDDEN(image))
1119 continue;
1120
1121 r = image_remove(image);
1122 if (r == -EBUSY) /* keep images that are currently being used. */
1123 continue;
1124 if (r < 0) {
1125 /* If the operation failed, let's override everything we wrote, and instead write there at which image we failed. */
1126 success = false;
1127 (void) ftruncate(result_fd, 0);
1128 (void) lseek(result_fd, 0, SEEK_SET);
1129 (void) write(result_fd, &success, sizeof(success));
1130 (void) write(result_fd, image->name, strlen(image->name)+1);
1131 goto child_fail;
1132 }
1133
1134 l = write(result_fd, image->name, strlen(image->name)+1);
1135 if (l < 0) {
1136 r = -errno;
1137 goto child_fail;
1138 }
1139
1140 l = write(result_fd, &image->usage_exclusive, sizeof(image->usage_exclusive));
1141 if (l < 0) {
1142 r = -errno;
1143 goto child_fail;
1144 }
1145 }
1146
1147 result_fd = safe_close(result_fd);
1148 _exit(EXIT_SUCCESS);
1149
1150 child_fail:
1151 (void) write(errno_pipe_fd[1], &r, sizeof(r));
1152 _exit(EXIT_FAILURE);
1153 }
1154
1155 errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
1156
1157 /* The clean-up might take a while, hence install a watch on the child and return */
1158
1159 r = operation_new(m, NULL, child, message, errno_pipe_fd[0], &operation);
1160 if (r < 0) {
1161 (void) sigkill_wait(child);
1162 return r;
1163 }
1164
1165 operation->extra_fd = result_fd;
1166 operation->done = clean_pool_done;
1167
1168 result_fd = -1;
1169 errno_pipe_fd[0] = -1;
1170
1171 return 1;
1172 }
1173
1174 static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1175 Manager *m = userdata;
1176 uint64_t limit;
1177 int r;
1178
1179 assert(message);
1180
1181 r = sd_bus_message_read(message, "t", &limit);
1182 if (r < 0)
1183 return r;
1184 if (!FILE_SIZE_VALID_OR_INFINITY(limit))
1185 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
1186
1187 r = bus_verify_polkit_async(
1188 message,
1189 CAP_SYS_ADMIN,
1190 "org.freedesktop.machine1.manage-machines",
1191 NULL,
1192 false,
1193 UID_INVALID,
1194 &m->polkit_registry,
1195 error);
1196 if (r < 0)
1197 return r;
1198 if (r == 0)
1199 return 1; /* Will call us back */
1200
1201 /* Set up the machine directory if necessary */
1202 r = setup_machine_directory(limit, error);
1203 if (r < 0)
1204 return r;
1205
1206 /* Resize the backing loopback device, if there is one, except if we asked to drop any limit */
1207 if (limit != (uint64_t) -1) {
1208 r = btrfs_resize_loopback("/var/lib/machines", limit, false);
1209 if (r == -ENOTTY)
1210 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
1211 if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */
1212 return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m");
1213 }
1214
1215 (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit);
1216
1217 r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit);
1218 if (r == -ENOTTY)
1219 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
1220 if (r < 0)
1221 return sd_bus_error_set_errnof(error, r, "Failed to adjust quota limit: %m");
1222
1223 return sd_bus_reply_method_return(message, NULL);
1224 }
1225
1226 static int method_set_image_limit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1227 _cleanup_(image_unrefp) Image *i = NULL;
1228 const char *name;
1229 int r;
1230
1231 assert(message);
1232
1233 r = sd_bus_message_read(message, "s", &name);
1234 if (r < 0)
1235 return r;
1236
1237 if (!image_name_is_valid(name))
1238 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
1239
1240 r = image_find(name, &i);
1241 if (r < 0)
1242 return r;
1243 if (r == 0)
1244 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
1245
1246 i->userdata = userdata;
1247 return bus_image_method_set_limit(message, i, error);
1248 }
1249
1250 static int method_map_from_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1251 _cleanup_fclose_ FILE *f = NULL;
1252 Manager *m = userdata;
1253 const char *name, *p;
1254 Machine *machine;
1255 uint32_t uid;
1256 int r;
1257
1258 r = sd_bus_message_read(message, "su", &name, &uid);
1259 if (r < 0)
1260 return r;
1261
1262 if (!uid_is_valid(uid))
1263 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1264
1265 machine = hashmap_get(m->machines, name);
1266 if (!machine)
1267 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
1268
1269 if (machine->class != MACHINE_CONTAINER)
1270 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
1271
1272 p = procfs_file_alloca(machine->leader, "uid_map");
1273 f = fopen(p, "re");
1274 if (!f)
1275 return -errno;
1276
1277 for (;;) {
1278 uid_t uid_base, uid_shift, uid_range, converted;
1279 int k;
1280
1281 errno = 0;
1282 k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
1283 if (k < 0 && feof(f))
1284 break;
1285 if (k != 3) {
1286 if (ferror(f) && errno > 0)
1287 return -errno;
1288
1289 return -EIO;
1290 }
1291
1292 if (uid < uid_base || uid >= uid_base + uid_range)
1293 continue;
1294
1295 converted = uid - uid_base + uid_shift;
1296 if (!uid_is_valid(converted))
1297 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1298
1299 return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
1300 }
1301
1302 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "Machine '%s' has no matching user mappings.", name);
1303 }
1304
1305 static int method_map_to_machine_user(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1306 Manager *m = userdata;
1307 Machine *machine;
1308 uid_t uid;
1309 Iterator i;
1310 int r;
1311
1312 r = sd_bus_message_read(message, "u", &uid);
1313 if (r < 0)
1314 return r;
1315 if (!uid_is_valid(uid))
1316 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1317 if (uid < 0x10000)
1318 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "User " UID_FMT " belongs to host UID range", uid);
1319
1320 HASHMAP_FOREACH(machine, m->machines, i) {
1321 _cleanup_fclose_ FILE *f = NULL;
1322 char p[STRLEN("/proc//uid_map") + DECIMAL_STR_MAX(pid_t) + 1];
1323
1324 if (machine->class != MACHINE_CONTAINER)
1325 continue;
1326
1327 xsprintf(p, "/proc/" UID_FMT "/uid_map", machine->leader);
1328 f = fopen(p, "re");
1329 if (!f) {
1330 log_warning_errno(errno, "Failed to open %s, ignoring,", p);
1331 continue;
1332 }
1333
1334 for (;;) {
1335 _cleanup_free_ char *o = NULL;
1336 uid_t uid_base, uid_shift, uid_range, converted;
1337 int k;
1338
1339 errno = 0;
1340 k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
1341 if (k < 0 && feof(f))
1342 break;
1343 if (k != 3) {
1344 if (ferror(f) && errno > 0)
1345 return -errno;
1346
1347 return -EIO;
1348 }
1349
1350 if (uid < uid_shift || uid >= uid_shift + uid_range)
1351 continue;
1352
1353 converted = (uid - uid_shift + uid_base);
1354 if (!uid_is_valid(converted))
1355 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user ID " UID_FMT, uid);
1356
1357 o = machine_bus_path(machine);
1358 if (!o)
1359 return -ENOMEM;
1360
1361 return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
1362 }
1363 }
1364
1365 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_USER_MAPPING, "No matching user mapping for " UID_FMT ".", uid);
1366 }
1367
1368 static int method_map_from_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
1369 _cleanup_fclose_ FILE *f = NULL;
1370 Manager *m = groupdata;
1371 const char *name, *p;
1372 Machine *machine;
1373 uint32_t gid;
1374 int r;
1375
1376 r = sd_bus_message_read(message, "su", &name, &gid);
1377 if (r < 0)
1378 return r;
1379
1380 if (!gid_is_valid(gid))
1381 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1382
1383 machine = hashmap_get(m->machines, name);
1384 if (!machine)
1385 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
1386
1387 if (machine->class != MACHINE_CONTAINER)
1388 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not supported for non-container machines.");
1389
1390 p = procfs_file_alloca(machine->leader, "gid_map");
1391 f = fopen(p, "re");
1392 if (!f)
1393 return -errno;
1394
1395 for (;;) {
1396 gid_t gid_base, gid_shift, gid_range, converted;
1397 int k;
1398
1399 errno = 0;
1400 k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
1401 if (k < 0 && feof(f))
1402 break;
1403 if (k != 3) {
1404 if (ferror(f) && errno > 0)
1405 return -errno;
1406
1407 return -EIO;
1408 }
1409
1410 if (gid < gid_base || gid >= gid_base + gid_range)
1411 continue;
1412
1413 converted = gid - gid_base + gid_shift;
1414 if (!gid_is_valid(converted))
1415 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1416
1417 return sd_bus_reply_method_return(message, "u", (uint32_t) converted);
1418 }
1419
1420 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Machine '%s' has no matching group mappings.", name);
1421 }
1422
1423 static int method_map_to_machine_group(sd_bus_message *message, void *groupdata, sd_bus_error *error) {
1424 Manager *m = groupdata;
1425 Machine *machine;
1426 gid_t gid;
1427 Iterator i;
1428 int r;
1429
1430 r = sd_bus_message_read(message, "u", &gid);
1431 if (r < 0)
1432 return r;
1433 if (!gid_is_valid(gid))
1434 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1435 if (gid < 0x10000)
1436 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "Group " GID_FMT " belongs to host GID range", gid);
1437
1438 HASHMAP_FOREACH(machine, m->machines, i) {
1439 _cleanup_fclose_ FILE *f = NULL;
1440 char p[STRLEN("/proc//gid_map") + DECIMAL_STR_MAX(pid_t) + 1];
1441
1442 if (machine->class != MACHINE_CONTAINER)
1443 continue;
1444
1445 xsprintf(p, "/proc/" GID_FMT "/gid_map", machine->leader);
1446 f = fopen(p, "re");
1447 if (!f) {
1448 log_warning_errno(errno, "Failed to open %s, ignoring,", p);
1449 continue;
1450 }
1451
1452 for (;;) {
1453 _cleanup_free_ char *o = NULL;
1454 gid_t gid_base, gid_shift, gid_range, converted;
1455 int k;
1456
1457 errno = 0;
1458 k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT, &gid_base, &gid_shift, &gid_range);
1459 if (k < 0 && feof(f))
1460 break;
1461 if (k != 3) {
1462 if (ferror(f) && errno > 0)
1463 return -errno;
1464
1465 return -EIO;
1466 }
1467
1468 if (gid < gid_shift || gid >= gid_shift + gid_range)
1469 continue;
1470
1471 converted = (gid - gid_shift + gid_base);
1472 if (!gid_is_valid(converted))
1473 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group ID " GID_FMT, gid);
1474
1475 o = machine_bus_path(machine);
1476 if (!o)
1477 return -ENOMEM;
1478
1479 return sd_bus_reply_method_return(message, "sou", machine->name, o, (uint32_t) converted);
1480 }
1481 }
1482
1483 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_GROUP_MAPPING, "No matching group mapping for " GID_FMT ".", gid);
1484 }
1485
1486 const sd_bus_vtable manager_vtable[] = {
1487 SD_BUS_VTABLE_START(0),
1488 SD_BUS_PROPERTY("PoolPath", "s", property_get_pool_path, 0, 0),
1489 SD_BUS_PROPERTY("PoolUsage", "t", property_get_pool_usage, 0, 0),
1490 SD_BUS_PROPERTY("PoolLimit", "t", property_get_pool_limit, 0, 0),
1491 SD_BUS_METHOD("GetMachine", "s", "o", method_get_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1492 SD_BUS_METHOD("GetImage", "s", "o", method_get_image, SD_BUS_VTABLE_UNPRIVILEGED),
1493 SD_BUS_METHOD("GetMachineByPID", "u", "o", method_get_machine_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1494 SD_BUS_METHOD("ListMachines", NULL, "a(ssso)", method_list_machines, SD_BUS_VTABLE_UNPRIVILEGED),
1495 SD_BUS_METHOD("ListImages", NULL, "a(ssbttto)", method_list_images, SD_BUS_VTABLE_UNPRIVILEGED),
1496 SD_BUS_METHOD("CreateMachine", "sayssusa(sv)", "o", method_create_machine, 0),
1497 SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
1498 SD_BUS_METHOD("RegisterMachine", "sayssus", "o", method_register_machine, 0),
1499 SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
1500 SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1501 SD_BUS_METHOD("KillMachine", "ssi", NULL, method_kill_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1502 SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
1503 SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
1504 SD_BUS_METHOD("OpenMachinePTY", "s", "hs", method_open_machine_pty, 0),
1505 SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
1506 SD_BUS_METHOD("OpenMachineShell", "sssasas", "hs", method_open_machine_shell, SD_BUS_VTABLE_UNPRIVILEGED),
1507 SD_BUS_METHOD("BindMountMachine", "sssbb", NULL, method_bind_mount_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1508 SD_BUS_METHOD("CopyFromMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1509 SD_BUS_METHOD("CopyToMachine", "sss", NULL, method_copy_machine, SD_BUS_VTABLE_UNPRIVILEGED),
1510 SD_BUS_METHOD("OpenMachineRootDirectory", "s", "h", method_open_machine_root_directory, SD_BUS_VTABLE_UNPRIVILEGED),
1511 SD_BUS_METHOD("GetMachineUIDShift", "s", "u", method_get_machine_uid_shift, SD_BUS_VTABLE_UNPRIVILEGED),
1512 SD_BUS_METHOD("RemoveImage", "s", NULL, method_remove_image, SD_BUS_VTABLE_UNPRIVILEGED),
1513 SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
1514 SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
1515 SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
1516 SD_BUS_METHOD("GetImageHostname", "s", "s", method_get_image_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
1517 SD_BUS_METHOD("GetImageMachineID", "s", "ay", method_get_image_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
1518 SD_BUS_METHOD("GetImageMachineInfo", "s", "a{ss}", method_get_image_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
1519 SD_BUS_METHOD("GetImageOSRelease", "s", "a{ss}", method_get_image_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
1520 SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
1521 SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),
1522 SD_BUS_METHOD("CleanPool", "s", "a(st)", method_clean_pool, SD_BUS_VTABLE_UNPRIVILEGED),
1523 SD_BUS_METHOD("MapFromMachineUser", "su", "u", method_map_from_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
1524 SD_BUS_METHOD("MapToMachineUser", "u", "sou", method_map_to_machine_user, SD_BUS_VTABLE_UNPRIVILEGED),
1525 SD_BUS_METHOD("MapFromMachineGroup", "su", "u", method_map_from_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
1526 SD_BUS_METHOD("MapToMachineGroup", "u", "sou", method_map_to_machine_group, SD_BUS_VTABLE_UNPRIVILEGED),
1527 SD_BUS_SIGNAL("MachineNew", "so", 0),
1528 SD_BUS_SIGNAL("MachineRemoved", "so", 0),
1529 SD_BUS_VTABLE_END
1530 };
1531
1532 int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1533 const char *path, *result, *unit;
1534 Manager *m = userdata;
1535 Machine *machine;
1536 uint32_t id;
1537 int r;
1538
1539 assert(message);
1540 assert(m);
1541
1542 r = sd_bus_message_read(message, "uoss", &id, &path, &unit, &result);
1543 if (r < 0) {
1544 bus_log_parse_error(r);
1545 return 0;
1546 }
1547
1548 machine = hashmap_get(m->machine_units, unit);
1549 if (!machine)
1550 return 0;
1551
1552 if (streq_ptr(path, machine->scope_job)) {
1553 machine->scope_job = mfree(machine->scope_job);
1554
1555 if (machine->started) {
1556 if (streq(result, "done"))
1557 machine_send_create_reply(machine, NULL);
1558 else {
1559 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
1560
1561 sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
1562
1563 machine_send_create_reply(machine, &e);
1564 }
1565 }
1566
1567 machine_save(machine);
1568 }
1569
1570 machine_add_to_gc_queue(machine);
1571 return 0;
1572 }
1573
1574 int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1575 _cleanup_free_ char *unit = NULL;
1576 const char *path;
1577 Manager *m = userdata;
1578 Machine *machine;
1579 int r;
1580
1581 assert(message);
1582 assert(m);
1583
1584 path = sd_bus_message_get_path(message);
1585 if (!path)
1586 return 0;
1587
1588 r = unit_name_from_dbus_path(path, &unit);
1589 if (r == -EINVAL) /* not for a unit */
1590 return 0;
1591 if (r < 0) {
1592 log_oom();
1593 return 0;
1594 }
1595
1596 machine = hashmap_get(m->machine_units, unit);
1597 if (!machine)
1598 return 0;
1599
1600 machine_add_to_gc_queue(machine);
1601 return 0;
1602 }
1603
1604 int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1605 const char *path, *unit;
1606 Manager *m = userdata;
1607 Machine *machine;
1608 int r;
1609
1610 assert(message);
1611 assert(m);
1612
1613 r = sd_bus_message_read(message, "so", &unit, &path);
1614 if (r < 0) {
1615 bus_log_parse_error(r);
1616 return 0;
1617 }
1618
1619 machine = hashmap_get(m->machine_units, unit);
1620 if (!machine)
1621 return 0;
1622
1623 machine_add_to_gc_queue(machine);
1624 return 0;
1625 }
1626
1627 int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1628 Manager *m = userdata;
1629 Machine *machine;
1630 Iterator i;
1631 int b, r;
1632
1633 assert(message);
1634 assert(m);
1635
1636 r = sd_bus_message_read(message, "b", &b);
1637 if (r < 0) {
1638 bus_log_parse_error(r);
1639 return 0;
1640 }
1641 if (b)
1642 return 0;
1643
1644 /* systemd finished reloading, let's recheck all our machines */
1645 log_debug("System manager has been reloaded, rechecking machines...");
1646
1647 HASHMAP_FOREACH(machine, m->machines, i)
1648 machine_add_to_gc_queue(machine);
1649
1650 return 0;
1651 }
1652
1653 int manager_start_scope(
1654 Manager *manager,
1655 const char *scope,
1656 pid_t pid,
1657 const char *slice,
1658 const char *description,
1659 sd_bus_message *more_properties,
1660 sd_bus_error *error,
1661 char **job) {
1662
1663 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
1664 int r;
1665
1666 assert(manager);
1667 assert(scope);
1668 assert(pid > 1);
1669
1670 r = sd_bus_message_new_method_call(
1671 manager->bus,
1672 &m,
1673 "org.freedesktop.systemd1",
1674 "/org/freedesktop/systemd1",
1675 "org.freedesktop.systemd1.Manager",
1676 "StartTransientUnit");
1677 if (r < 0)
1678 return r;
1679
1680 r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
1681 if (r < 0)
1682 return r;
1683
1684 r = sd_bus_message_open_container(m, 'a', "(sv)");
1685 if (r < 0)
1686 return r;
1687
1688 if (!isempty(slice)) {
1689 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
1690 if (r < 0)
1691 return r;
1692 }
1693
1694 if (!isempty(description)) {
1695 r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
1696 if (r < 0)
1697 return r;
1698 }
1699
1700 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, pid);
1701 if (r < 0)
1702 return r;
1703
1704 r = sd_bus_message_append(m, "(sv)", "Delegate", "b", 1);
1705 if (r < 0)
1706 return r;
1707
1708 r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", UINT64_C(16384));
1709 if (r < 0)
1710 return bus_log_create_error(r);
1711
1712 if (more_properties) {
1713 r = sd_bus_message_copy(m, more_properties, true);
1714 if (r < 0)
1715 return r;
1716 }
1717
1718 r = sd_bus_message_close_container(m);
1719 if (r < 0)
1720 return r;
1721
1722 r = sd_bus_message_append(m, "a(sa(sv))", 0);
1723 if (r < 0)
1724 return r;
1725
1726 r = sd_bus_call(manager->bus, m, 0, error, &reply);
1727 if (r < 0)
1728 return r;
1729
1730 if (job) {
1731 const char *j;
1732 char *copy;
1733
1734 r = sd_bus_message_read(reply, "o", &j);
1735 if (r < 0)
1736 return r;
1737
1738 copy = strdup(j);
1739 if (!copy)
1740 return -ENOMEM;
1741
1742 *job = copy;
1743 }
1744
1745 return 1;
1746 }
1747
1748 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
1749 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1750 int r;
1751
1752 assert(manager);
1753 assert(unit);
1754
1755 r = sd_bus_call_method(
1756 manager->bus,
1757 "org.freedesktop.systemd1",
1758 "/org/freedesktop/systemd1",
1759 "org.freedesktop.systemd1.Manager",
1760 "StopUnit",
1761 error,
1762 &reply,
1763 "ss", unit, "fail");
1764 if (r < 0) {
1765 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
1766 sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
1767
1768 if (job)
1769 *job = NULL;
1770
1771 sd_bus_error_free(error);
1772 return 0;
1773 }
1774
1775 return r;
1776 }
1777
1778 if (job) {
1779 const char *j;
1780 char *copy;
1781
1782 r = sd_bus_message_read(reply, "o", &j);
1783 if (r < 0)
1784 return r;
1785
1786 copy = strdup(j);
1787 if (!copy)
1788 return -ENOMEM;
1789
1790 *job = copy;
1791 }
1792
1793 return 1;
1794 }
1795
1796 int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
1797 assert(manager);
1798 assert(unit);
1799
1800 return sd_bus_call_method(
1801 manager->bus,
1802 "org.freedesktop.systemd1",
1803 "/org/freedesktop/systemd1",
1804 "org.freedesktop.systemd1.Manager",
1805 "KillUnit",
1806 error,
1807 NULL,
1808 "ssi", unit, "all", signo);
1809 }
1810
1811 int manager_unit_is_active(Manager *manager, const char *unit) {
1812 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1813 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1814 _cleanup_free_ char *path = NULL;
1815 const char *state;
1816 int r;
1817
1818 assert(manager);
1819 assert(unit);
1820
1821 path = unit_dbus_path_from_name(unit);
1822 if (!path)
1823 return -ENOMEM;
1824
1825 r = sd_bus_get_property(
1826 manager->bus,
1827 "org.freedesktop.systemd1",
1828 path,
1829 "org.freedesktop.systemd1.Unit",
1830 "ActiveState",
1831 &error,
1832 &reply,
1833 "s");
1834 if (r < 0) {
1835 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1836 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1837 return true;
1838
1839 if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
1840 sd_bus_error_has_name(&error, BUS_ERROR_LOAD_FAILED))
1841 return false;
1842
1843 return r;
1844 }
1845
1846 r = sd_bus_message_read(reply, "s", &state);
1847 if (r < 0)
1848 return -EINVAL;
1849
1850 return !STR_IN_SET(state, "inactive", "failed");
1851 }
1852
1853 int manager_job_is_active(Manager *manager, const char *path) {
1854 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1855 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1856 int r;
1857
1858 assert(manager);
1859 assert(path);
1860
1861 r = sd_bus_get_property(
1862 manager->bus,
1863 "org.freedesktop.systemd1",
1864 path,
1865 "org.freedesktop.systemd1.Job",
1866 "State",
1867 &error,
1868 &reply,
1869 "s");
1870 if (r < 0) {
1871 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_NO_REPLY) ||
1872 sd_bus_error_has_name(&error, SD_BUS_ERROR_DISCONNECTED))
1873 return true;
1874
1875 if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_OBJECT))
1876 return false;
1877
1878 return r;
1879 }
1880
1881 /* We don't actually care about the state really. The fact
1882 * that we could read the job state is enough for us */
1883
1884 return true;
1885 }
1886
1887 int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) {
1888 Machine *mm;
1889 int r;
1890
1891 assert(m);
1892 assert(pid >= 1);
1893 assert(machine);
1894
1895 mm = hashmap_get(m->machine_leaders, PID_TO_PTR(pid));
1896 if (!mm) {
1897 _cleanup_free_ char *unit = NULL;
1898
1899 r = cg_pid_get_unit(pid, &unit);
1900 if (r >= 0)
1901 mm = hashmap_get(m->machine_units, unit);
1902 }
1903 if (!mm)
1904 return 0;
1905
1906 *machine = mm;
1907 return 1;
1908 }
1909
1910 int manager_add_machine(Manager *m, const char *name, Machine **_machine) {
1911 Machine *machine;
1912
1913 assert(m);
1914 assert(name);
1915
1916 machine = hashmap_get(m->machines, name);
1917 if (!machine) {
1918 machine = machine_new(m, _MACHINE_CLASS_INVALID, name);
1919 if (!machine)
1920 return -ENOMEM;
1921 }
1922
1923 if (_machine)
1924 *_machine = machine;
1925
1926 return 0;
1927 }
1928
1929 int bus_reply_pair_array(sd_bus_message *m, char **l) {
1930 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1931 char **k, **v;
1932 int r;
1933
1934 r = sd_bus_message_new_method_return(m, &reply);
1935 if (r < 0)
1936 return r;
1937
1938 r = sd_bus_message_open_container(reply, 'a', "{ss}");
1939 if (r < 0)
1940 return r;
1941
1942 STRV_FOREACH_PAIR(k, v, l) {
1943 r = sd_bus_message_append(reply, "{ss}", *k, *v);
1944 if (r < 0)
1945 return r;
1946 }
1947
1948 r = sd_bus_message_close_container(reply);
1949 if (r < 0)
1950 return r;
1951
1952 return sd_bus_send(NULL, reply, NULL);
1953
1954 }