machine-dbus.c revision 385080c09e48ea62a80525197f66f3347d96d2ce
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2011 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/mount.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* When we include libgen.h because we need dirname() we immediately
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * undefine basename() since libgen.h defines it as a macro to the POSIX
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * version which is really broken. We prefer GNU basename(). */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <libgen.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#undef basename
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-label.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "strv.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-common-errors.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "copy.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "fileio.h"
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include "in-addr-util.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "local-addresses.h"
23c80348e656a4e6fd9ba8f17523a65b6fa349a0Kay Sievers#include "path-util.h"
003dffde2c1b93afbc9aff24b277276f65424406Lennart Poettering#include "mkdir.h"
003dffde2c1b93afbc9aff24b277276f65424406Lennart Poettering#include "bus-internal.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "machine.h"
003dffde2c1b93afbc9aff24b277276f65424406Lennart Poettering#include "machine-dbus.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "formats-util.h"
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering#include "process-util.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "env-util.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "terminal-util.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int property_get_id(
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering sd_bus *bus,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *path,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *interface,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *property,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering sd_bus_message *reply,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering void *userdata,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering sd_bus_error *error) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering Machine *m = userdata;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(bus);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(reply);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_message_append_array(reply, 'y', &m->id, 16);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int property_get_state(
df2d202e6ed4001a21c6512c244acad5d4706c87Lennart Poettering sd_bus *bus,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *path,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *interface,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering const char *property,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering sd_bus_message *reply,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering void *userdata,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering sd_bus_error *error) {
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering Machine *m = userdata;
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering const char *state;
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering int r;
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering assert(bus);
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering assert(reply);
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering assert(m);
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering state = machine_state_to_string(machine_get_state(m));
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering r = sd_bus_message_append_basic(reply, 's', state);
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering if (r < 0)
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering return r;
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering return 1;
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering}
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poetteringstatic int property_get_netif(
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering sd_bus *bus,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering const char *path,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering const char *interface,
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering const char *property,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering sd_bus_message *reply,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering void *userdata,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering sd_bus_error *error) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering Machine *m = userdata;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(bus);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(reply);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering return sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poetteringint bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering Machine *m = userdata;
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering int r;
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering assert(message);
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering assert(m);
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering r = bus_verify_polkit_async(
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering message,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering CAP_KILL,
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering "org.freedesktop.machine1.manage-machines",
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering NULL,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering false,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering UID_INVALID,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering &m->manager->polkit_registry,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering error);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r == 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 1; /* Will call us back */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = machine_stop(m);
df2d202e6ed4001a21c6512c244acad5d4706c87Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return sd_bus_reply_method_return(message, NULL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringint bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering Machine *m = userdata;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *swho;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int32_t signo;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering KillWho who;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(message);
df2d202e6ed4001a21c6512c244acad5d4706c87Lennart Poettering assert(m);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_read(message, "si", &swho, &signo);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (isempty(swho))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering who = KILL_ALL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering else {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering who = kill_who_from_string(swho);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (who < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (signo <= 0 || signo >= _NSIG)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = bus_verify_polkit_async(
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering message,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering CAP_KILL,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "org.freedesktop.machine1.manage-machines",
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering NULL,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering false,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering UID_INVALID,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering &m->manager->polkit_registry,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering error);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r == 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 1; /* Will call us back */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = machine_kill(m, who, signo);
8aec412ff697bc14995746953912ca6fdf2c9ba8Lennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_reply_method_return(message, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd_bus_error *error) {
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering Machine *m = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering assert(message);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return r;
7f0d207d2c816e0a8cb2742b0a789911f7c99356Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iay)");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering switch (m->class) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case MACHINE_HOST: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ struct local_address *addresses = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct local_address *a;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int n, i;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (n < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return n;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (a = addresses, i = 0; i < n; a++, i++) {
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = sd_bus_message_open_container(reply, 'r', "iay");
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return r;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = sd_bus_message_append(reply, "i", addresses[i].family);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return r;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = sd_bus_message_append_array(reply, 'y', &addresses[i].address, FAMILY_ADDRESS_SIZE(addresses[i].family));
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return r;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = sd_bus_message_close_container(reply);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case MACHINE_CONTAINER: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_close_pair_ int pair[2] = { -1, -1 };
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_free_ char *us = NULL, *them = NULL;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering _cleanup_close_ int netns_fd = -1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *p;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering siginfo_t si;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering pid_t child;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = readlink_malloc("/proc/self/ns/net", &us);
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering if (r < 0)
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering return r;
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering p = procfs_file_alloca(m->leader, "ns/net");
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering r = readlink_malloc(p, &them);
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering if (streq(us, them))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = namespace_open(m->leader, NULL, NULL, &netns_fd, NULL, NULL);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering child = fork();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (child < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (child == 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ struct local_address *addresses = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct local_address *a;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int i, n;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering pair[0] = safe_close(pair[0]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = namespace_enter(-1, -1, netns_fd, -1, -1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering n = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (n < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (a = addresses, i = 0; i < n; a++, i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct iovec iov[2] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { .iov_base = &a->family, .iov_len = sizeof(a->family) },
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering { .iov_base = &a->address, .iov_len = FAMILY_ADDRESS_SIZE(a->family) },
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering };
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = writev(pair[1], iov, 2);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering _exit(EXIT_FAILURE);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering }
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering pair[1] = safe_close(pair[1]);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering _exit(EXIT_SUCCESS);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering pair[1] = safe_close(pair[1]);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering for (;;) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering int family;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering ssize_t n;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering union in_addr_union in_addr;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering struct iovec iov[2];
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering struct msghdr mh = {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering .msg_iov = iov,
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering .msg_iovlen = 2,
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering };
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering iov[1] = (struct iovec) { .iov_base = &in_addr, .iov_len = sizeof(in_addr) };
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering n = recvmsg(pair[0], &mh, 0);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (n < 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return -errno;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if ((size_t) n < sizeof(family))
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering break;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_open_container(reply, 'r', "iay");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(reply, "i", family);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
a3e7f417d72ba3251fd6b3a228a2721a4b725a03Zbigniew Jędrzejewski-Szmek
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering switch (family) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case AF_INET:
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (n != sizeof(struct in_addr) + sizeof(family))
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return -EIO;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering r = sd_bus_message_append_array(reply, 'y', &in_addr.in, sizeof(in_addr.in));
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering break;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering case AF_INET6:
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (n != sizeof(struct in6_addr) + sizeof(family))
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return -EIO;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = sd_bus_message_append_array(reply, 'y', &in_addr.in6, sizeof(in_addr.in6));
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering break;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = sd_bus_message_close_container(reply);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = wait_for_terminate(child, &si);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
8d90c8a8d6867ffcfb61a11b73205cd7b1a72f3aLennart Poettering if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
8d90c8a8d6867ffcfb61a11b73205cd7b1a72f3aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering break;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering default:
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting IP address data is only supported on container machines.");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = sd_bus_message_close_container(reply);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return sd_bus_send(NULL, reply, NULL);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering}
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_strv_free_ char **l = NULL;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering Machine *m = userdata;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering char **k, **v;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering int r;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering assert(message);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering assert(m);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering switch (m->class) {
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case MACHINE_HOST:
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = load_env_file_pairs(NULL, "/etc/os-release", NULL, &l);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case MACHINE_CONTAINER: {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_close_ int mntns_fd = -1, root_fd = -1;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_close_pair_ int pair[2] = { -1, -1 };
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering siginfo_t si;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pid_t child;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = namespace_open(m->leader, NULL, &mntns_fd, NULL, NULL, &root_fd);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering child = fork();
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (child < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (child == 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_close_ int fd = -1;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering pair[0] = safe_close(pair[0]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = namespace_enter(-1, mntns_fd, -1, -1, root_fd);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (fd < 0) {
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (fd < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _exit(EXIT_FAILURE);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = copy_bytes(fd, pair[1], (off_t) -1, false);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _exit(EXIT_FAILURE);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _exit(EXIT_SUCCESS);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering pair[1] = safe_close(pair[1]);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering f = fdopen(pair[0], "re");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!f)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return -errno;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pair[0] = -1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = load_env_file_pairs(f, "/etc/os-release", NULL, &l);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = wait_for_terminate(child, &si);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering break;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering default:
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines.");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "{ss}");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering STRV_FOREACH_PAIR(k, v, l) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_append(reply, "{ss}", *k, *v);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_close_container(reply);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return sd_bus_send(NULL, reply, NULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringint bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_error *error) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_free_ char *pty_name = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_close_ int master = -1;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering Machine *m = userdata;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(message);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(m);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = bus_verify_polkit_async(
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering message,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering CAP_SYS_ADMIN,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering NULL,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering false,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering UID_INVALID,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &m->manager->polkit_registry,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering error);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r == 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 1; /* Will call us back */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (master < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return master;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = ptsname_namespace(master, &pty_name);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_append(reply, "hs", master, pty_name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return sd_bus_send(NULL, reply, NULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poetteringstatic int container_bus_new(Machine *m, sd_bus_error *error, sd_bus **ret) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering int r;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering assert(m);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering assert(ret);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering switch (m->class) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering case MACHINE_HOST:
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering *ret = NULL;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering break;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering case MACHINE_CONTAINER: {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering char *address;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering r = sd_bus_new(&bus);
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering if (r < 0)
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering return r;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering if (asprintf(&address, "x-machine-kernel:pid=%1$" PID_PRI ";x-machine-unix:pid=%1$" PID_PRI, m->leader) < 0)
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering return -ENOMEM;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering bus->address = address;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering bus->bus_client = true;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering bus->trusted = false;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering bus->is_system = true;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering r = sd_bus_start(bus);
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering if (r == -ENOENT)
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering return sd_bus_error_set_errnof(error, r, "There is no system bus in container %s.", m->name);
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering if (r < 0)
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering return r;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering *ret = bus;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering bus = NULL;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering break;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering }
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering default:
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering return -EOPNOTSUPP;
5f8cc96a0301c1177b11dd2e89370ef0b2ef577bLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering return 0;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering}
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poetteringint bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bus_error *error) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_free_ char *pty_name = NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_bus_flush_close_unref_ sd_bus *allocated_bus = NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_close_ int master = -1;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering sd_bus *container_bus = NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering Machine *m = userdata;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering const char *p, *getty;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering int r;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering assert(message);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering assert(m);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = bus_verify_polkit_async(
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering message,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering CAP_SYS_ADMIN,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering NULL,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering false,
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering UID_INVALID,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering &m->manager->polkit_registry,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering error);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r == 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return 1; /* Will call us back */
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (master < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return master;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = ptsname_namespace(master, &pty_name);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering p = path_startswith(pty_name, "/dev/pts/");
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (!p)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = container_bus_new(m, error, &allocated_bus);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering container_bus = allocated_bus ?: m->manager->bus;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering getty = strjoina("container-getty@", p, ".service");
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering r = sd_bus_call_method(
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering container_bus,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering "org.freedesktop.systemd1",
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering "/org/freedesktop/systemd1",
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering "org.freedesktop.systemd1.Manager",
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering "StartUnit",
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering error, NULL,
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering "ss", getty, "replace");
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = sd_bus_message_append(reply, "hs", master, pty_name);
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return sd_bus_send(NULL, reply, NULL);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering}
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poetteringint bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bus_error *error) {
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *tm = NULL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering _cleanup_free_ char *pty_name = NULL;
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering _cleanup_bus_flush_close_unref_ sd_bus *allocated_bus = NULL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering sd_bus *container_bus = NULL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering _cleanup_close_ int master = -1;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering _cleanup_strv_free_ char **env = NULL, **args = NULL;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering Machine *m = userdata;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering const char *p, *unit, *user, *path, *description, *utmp_id;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering int r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering assert(message);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering assert(m);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = sd_bus_message_read(message, "ss", &user, &path);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
1ddb263d21099ae42195c2bc382bdf72a7f24f82Lennart Poettering return r;
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (isempty(user))
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering user = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (isempty(path))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering path = "/bin/sh";
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering if (!path_is_absolute(path))
c2ce6a3d82b717c4c1e6245ad8c6ce1173f502d0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified path '%s' is not absolute", path);
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering r = sd_bus_message_read_strv(message, &args);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering if (strv_isempty(args)) {
8d07a7c47159ebc2bcc775e2c1997cb44bd1ac95Lennart Poettering args = strv_free(args);
9b5ed6feda08290edce3bf916fa7362733dd30eaLennart Poettering
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering args = strv_new(path, NULL);
adacb9575a09981fcf11279f2f661e3fc21e58ffLennart Poettering if (!args)
3a6fb33c54bc64398e0af1c9d7c74a6b614a849dLennart Poettering return -ENOMEM;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering args[0][0] = '-'; /* Tell /bin/sh that this shall be a login shell */
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering r = sd_bus_message_read_strv(message, &env);
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering if (r < 0)
ebd93cb684806ac0f352139e69ac8f53eb49f5e4Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!strv_env_is_valid(env))
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = bus_verify_polkit_async(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering message,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering CAP_SYS_ADMIN,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering false,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering UID_INVALID,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering &m->manager->polkit_registry,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering error);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r == 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1; /* Will call us back */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (master < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return master;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering r = ptsname_namespace(master, &pty_name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering p = path_startswith(pty_name, "/dev/pts/");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!p)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering utmp_id = path_startswith(pty_name, "/dev/");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(utmp_id);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = container_bus_new(m, error, &allocated_bus);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return r;
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering container_bus = allocated_bus ?: m->manager->bus;
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_new_method_call(
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering container_bus,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering &tm,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "org.freedesktop.systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1.Manager",
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "StartTransientUnit");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering /* Name and mode */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering unit = strjoina("container-shell@", p, ".service", NULL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(tm, "ss", unit, "fail");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering /* Properties */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_open_container(tm, 'a', "(sv)");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering description = strjoina("Shell for User ", isempty(user) ? "root" : user);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(tm,
554604b3073467af75dc94fac9e2343148603289Lennart Poettering "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
554604b3073467af75dc94fac9e2343148603289Lennart Poettering "Description", "s", description,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering "StandardInput", "s", "tty",
e5f5b5b9c92d59ef3cb5169982cb6f436c9206faLennart Poettering "StandardOutput", "s", "tty",
e5f5b5b9c92d59ef3cb5169982cb6f436c9206faLennart Poettering "StandardError", "s", "tty",
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering "TTYPath", "s", pty_name,
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering "SendSIGHUP", "b", true,
554604b3073467af75dc94fac9e2343148603289Lennart Poettering "IgnoreSIGPIPE", "b", false,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "KillMode", "s", "mixed",
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "TTYVHangup", "b", true,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "TTYReset", "b", true,
554604b3073467af75dc94fac9e2343148603289Lennart Poettering "UtmpIdentifier", "s", utmp_id,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "UtmpMode", "s", "user",
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "PAMName", "s", "login");
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(tm, "(sv)", "User", "s", isempty(user) ? "root" : user);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (!strv_isempty(env)) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_open_container(tm, 'r', "sv");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
554604b3073467af75dc94fac9e2343148603289Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(tm, "s", "Environment");
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (r < 0)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_message_open_container(tm, 'v', "as");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_message_append_strv(tm, env);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_close_container(tm);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering return r;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_close_container(tm);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Exec container */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = sd_bus_message_open_container(tm, 'r', "sv");
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (r < 0)
554604b3073467af75dc94fac9e2343148603289Lennart Poettering return r;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering r = sd_bus_message_append(tm, "s", "ExecStart");
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering return r;
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_message_open_container(tm, 'v', "a(sasb)");
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering if (r < 0)
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering return r;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_message_open_container(tm, 'a', "(sasb)");
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (r < 0)
554604b3073467af75dc94fac9e2343148603289Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_open_container(tm, 'r', "sasb");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_append(tm, "s", path);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_append_strv(tm, args);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
554604b3073467af75dc94fac9e2343148603289Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_append(tm, "b", true);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_close_container(tm);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_close_container(tm);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_close_container(tm);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_close_container(tm);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_close_container(tm);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Auxiliary units */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_message_append(tm, "a(sa(sv))", 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_call(container_bus, tm, 0, error, NULL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_new_method_return(message, &reply);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poettering r = sd_bus_message_append(reply, "hs", master, pty_name);
a931ad47a8623163a29d898224d8a8c1177ffdafLennart Poettering if (r < 0)
a931ad47a8623163a29d898224d8a8c1177ffdafLennart Poettering return r;
a931ad47a8623163a29d898224d8a8c1177ffdafLennart Poettering
a931ad47a8623163a29d898224d8a8c1177ffdafLennart Poettering return sd_bus_send(NULL, reply, NULL);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
554604b3073467af75dc94fac9e2343148603289Lennart Poetteringint bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bus_error *error) {
554604b3073467af75dc94fac9e2343148603289Lennart Poettering _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
554604b3073467af75dc94fac9e2343148603289Lennart Poettering char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
554604b3073467af75dc94fac9e2343148603289Lennart Poettering bool mount_slave_created = false, mount_slave_mounted = false,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering mount_tmp_created = false, mount_tmp_mounted = false,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering mount_outside_created = false, mount_outside_mounted = false;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *dest, *src;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Machine *m = userdata;
86b8d289717bad2800342efca0a5023aa8374e9cLennart Poettering int read_only, make_directory;
86b8d289717bad2800342efca0a5023aa8374e9cLennart Poettering pid_t child;
86b8d289717bad2800342efca0a5023aa8374e9cLennart Poettering siginfo_t si;
86b8d289717bad2800342efca0a5023aa8374e9cLennart Poettering int r;
c49b30a23583ff39daaa26696bcab478d2fee0bbLennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(message);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (m->class != MACHINE_CONTAINER)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Bind mounting is only supported on container machines.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_read(message, "ssbb", &src, &dest, &read_only, &make_directory);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!path_is_absolute(src) || !path_is_safe(src))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (isempty(dest))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering dest = src;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (!path_is_absolute(dest) || !path_is_safe(dest))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = bus_verify_polkit_async(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering message,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering CAP_SYS_ADMIN,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering "org.freedesktop.machine1.manage-machines",
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering false,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering UID_INVALID,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &m->manager->polkit_registry,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r == 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1; /* Will call us back */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* One day, when bind mounting /proc/self/fd/n works across
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * namespace boundaries we should rework this logic to make
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * use of it... */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering p = strjoina("/run/systemd/nspawn/propagate/", m->name, "/");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (laccess(p, F_OK) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering /* Our goal is to install a new bind mount into the container,
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering possibly read-only. This is irritatingly complex
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering unfortunately, currently.
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering First, we start by creating a private playground in /tmp,
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering that we can mount MS_SLAVE. (Which is necessary, since
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering MS_MOUNT cannot be applied to mounts with MS_SHARED parent
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering mounts.) */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!mkdtemp(mount_slave))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return sd_bus_error_set_errnof(error, errno, "Failed to create playground %s: %m", mount_slave);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_slave_created = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (mount(mount_slave, mount_slave, NULL, MS_BIND, NULL) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to make bind mount %s: %m", mount_slave);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto finish;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_slave_mounted = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (mount(NULL, mount_slave, NULL, MS_SLAVE, NULL) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to remount slave %s: %m", mount_slave);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering /* Second, we mount the source directory to a directory inside
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering of our MS_SLAVE playground. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_tmp = strjoina(mount_slave, "/mount");
de58a50e24a0d55e3bbcc77f8f6170a7322acf52Lennart Poettering if (mkdir(mount_tmp, 0700) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_tmp_created = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (mount(src, mount_tmp, NULL, MS_BIND, NULL) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to overmount %s: %m", mount_tmp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering
de58a50e24a0d55e3bbcc77f8f6170a7322acf52Lennart Poettering mount_tmp_mounted = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Third, we remount the new bind mount read-only if requested. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (read_only)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to remount read-only %s: %m", mount_tmp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Fourth, we move the new bind mount into the propagation
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * directory. This way it will appear there read-only
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * right-away. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_outside = strjoina("/run/systemd/nspawn/propagate/", m->name, "/XXXXXX");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!mkdtemp(mount_outside)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Cannot create propagation directory %s: %m", mount_outside);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_outside_created = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to move %s to %s: %m", mount_tmp, mount_outside);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_outside_mounted = true;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering mount_tmp_mounted = false;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering (void) rmdir(mount_tmp);
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering mount_tmp_created = false;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering (void) umount(mount_slave);
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering mount_slave_mounted = false;
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (void) rmdir(mount_slave);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mount_slave_created = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering child = fork();
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek if (child < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto finish;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek if (child == 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const char *mount_inside;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int mntfd;
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek const char *q;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering q = procfs_file_alloca(m->leader, "ns/mnt");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (mntfd < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto child_fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (setns(mntfd, CLONE_NEWNS) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = log_error_errno(errno, "Failed to join namespace of leader: %m");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering goto child_fail;
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek }
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (make_directory)
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek (void) mkdir_p(dest, 0755);
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Fifth, move the mount to the right place inside */
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek mount_inside = strjoina("/run/systemd/nspawn/incoming/", basename(mount_outside));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = log_error_errno(errno, "Failed to mount: %m");
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek goto child_fail;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering }
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers _exit(EXIT_SUCCESS);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers child_fail:
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers (void) write(errno_pipe_fd[1], &r, sizeof(r));
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers _exit(EXIT_FAILURE);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers }
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = wait_for_terminate(child, &si);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (r < 0) {
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = sd_bus_error_set_errnof(error, r, "Failed to wait for client: %m");
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers goto finish;
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers }
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (si.si_code != CLD_EXITED) {
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers goto finish;
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers }
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (si.si_status != EXIT_SUCCESS) {
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (read(errno_pipe_fd[0], &r, sizeof(r)) == sizeof(r))
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = sd_bus_error_set_errnof(error, r, "Failed to mount: %m");
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers else
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Client failed.");
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers goto finish;
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers }
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = sd_bus_reply_method_return(message, NULL);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sieversfinish:
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (mount_outside_mounted)
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers umount(mount_outside);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (mount_outside_created)
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers rmdir(mount_outside);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (mount_tmp_mounted)
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers umount(mount_tmp);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers if (mount_tmp_created)
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers rmdir(mount_tmp);
if (mount_slave_mounted)
umount(mount_slave);
if (mount_slave_created)
rmdir(mount_slave);
return r;
}
static int machine_operation_done(sd_event_source *s, const siginfo_t *si, void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
MachineOperation *o = userdata;
int r;
assert(o);
assert(si);
o->pid = 0;
if (si->si_code != CLD_EXITED) {
r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client died abnormally.");
goto fail;
}
if (si->si_status != EXIT_SUCCESS) {
if (read(o->errno_fd, &r, sizeof(r)) == sizeof(r))
r = sd_bus_error_set_errnof(&error, r, "%m");
else
r = sd_bus_error_setf(&error, SD_BUS_ERROR_FAILED, "Client failed.");
goto fail;
}
r = sd_bus_reply_method_return(o->message, NULL);
if (r < 0)
log_error_errno(r, "Failed to reply to message: %m");
machine_operation_unref(o);
return 0;
fail:
r = sd_bus_reply_method_error(o->message, &error);
if (r < 0)
log_error_errno(r, "Failed to reply to message: %m");
machine_operation_unref(o);
return 0;
}
int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *src, *dest, *host_path, *container_path, *host_basename, *host_dirname, *container_basename, *container_dirname;
_cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
_cleanup_close_ int hostfd = -1;
Machine *m = userdata;
MachineOperation *o;
bool copy_from;
pid_t child;
char *t;
int r;
assert(message);
assert(m);
if (m->n_operations >= MACHINE_OPERATIONS_MAX)
return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing copies.");
if (m->class != MACHINE_CONTAINER)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Copying files is only supported on container machines.");
r = sd_bus_message_read(message, "ss", &src, &dest);
if (r < 0)
return r;
if (!path_is_absolute(src))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute.");
if (isempty(dest))
dest = src;
else if (!path_is_absolute(dest))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute.");
r = bus_verify_polkit_async(
message,
CAP_SYS_ADMIN,
"org.freedesktop.machine1.manage-machines",
NULL,
false,
UID_INVALID,
&m->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
if (copy_from) {
container_path = src;
host_path = dest;
} else {
host_path = src;
container_path = dest;
}
host_basename = basename(host_path);
t = strdupa(host_path);
host_dirname = dirname(t);
container_basename = basename(container_path);
t = strdupa(container_path);
container_dirname = dirname(t);
hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
if (hostfd < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to open host directory %s: %m", host_dirname);
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
child = fork();
if (child < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
if (child == 0) {
int containerfd;
const char *q;
int mntfd;
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
q = procfs_file_alloca(m->leader, "ns/mnt");
mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (mntfd < 0) {
r = log_error_errno(errno, "Failed to open mount namespace of leader: %m");
goto child_fail;
}
if (setns(mntfd, CLONE_NEWNS) < 0) {
r = log_error_errno(errno, "Failed to join namespace of leader: %m");
goto child_fail;
}
containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
if (containerfd < 0) {
r = log_error_errno(errno, "Failed top open destination directory: %m");
goto child_fail;
}
if (copy_from)
r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
else
r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
hostfd = safe_close(hostfd);
containerfd = safe_close(containerfd);
if (r < 0) {
r = log_error_errno(r, "Failed to copy tree: %m");
goto child_fail;
}
_exit(EXIT_SUCCESS);
child_fail:
(void) write(errno_pipe_fd[1], &r, sizeof(r));
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
_exit(EXIT_FAILURE);
}
errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
/* Copying might take a while, hence install a watch the
* child, and return */
o = new0(MachineOperation, 1);
if (!o)
return log_oom();
o->pid = child;
o->message = sd_bus_message_ref(message);
o->errno_fd = errno_pipe_fd[0];
errno_pipe_fd[0] = -1;
r = sd_event_add_child(m->manager->event, &o->event_source, child, WEXITED, machine_operation_done, o);
if (r < 0) {
machine_operation_unref(o);
return log_oom();
}
LIST_PREPEND(operations, m->operations, o);
m->n_operations++;
o->machine = m;
return 1;
}
const sd_bus_vtable machine_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Machine, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Unit", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NetworkInterfaces", "ai", property_get_netif, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Kill", "si", NULL, bus_machine_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenPTY", NULL, "hs", bus_machine_method_open_pty, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenLogin", NULL, "hs", bus_machine_method_open_login, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenShell", "ssasas", "hs", bus_machine_method_open_shell, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("BindMount", "ssbb", NULL, bus_machine_method_bind_mount, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyFrom", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CopyTo", "ss", NULL, bus_machine_method_copy, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
Manager *m = userdata;
Machine *machine;
int r;
assert(bus);
assert(path);
assert(interface);
assert(found);
assert(m);
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
sd_bus_message *message;
pid_t pid;
message = sd_bus_get_current_message(bus);
if (!message)
return 0;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
if (r < 0)
return r;
r = sd_bus_creds_get_pid(creds, &pid);
if (r < 0)
return r;
r = manager_get_machine_by_pid(m, pid, &machine);
if (r <= 0)
return 0;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/machine1/machine/");
if (!p)
return 0;
e = bus_label_unescape(p);
if (!e)
return -ENOMEM;
machine = hashmap_get(m->machines, e);
if (!machine)
return 0;
}
*found = machine;
return 1;
}
char *machine_bus_path(Machine *m) {
_cleanup_free_ char *e = NULL;
assert(m);
e = bus_label_escape(m->name);
if (!e)
return NULL;
return strappend("/org/freedesktop/machine1/machine/", e);
}
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
Iterator i;
int r;
assert(bus);
assert(path);
assert(nodes);
HASHMAP_FOREACH(machine, m->machines, i) {
char *p;
p = machine_bus_path(machine);
if (!p)
return -ENOMEM;
r = strv_consume(&l, p);
if (r < 0)
return r;
}
*nodes = l;
l = NULL;
return 1;
}
int machine_send_signal(Machine *m, bool new_machine) {
_cleanup_free_ char *p = NULL;
assert(m);
p = machine_bus_path(m);
if (!p)
return -ENOMEM;
return sd_bus_emit_signal(
m->manager->bus,
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
new_machine ? "MachineNew" : "MachineRemoved",
"so", m->name, p);
}
int machine_send_create_reply(Machine *m, sd_bus_error *error) {
_cleanup_bus_message_unref_ sd_bus_message *c = NULL;
_cleanup_free_ char *p = NULL;
assert(m);
if (!m->create_message)
return 0;
c = m->create_message;
m->create_message = NULL;
if (error)
return sd_bus_reply_method_error(c, error);
/* Update the machine state file before we notify the client
* about the result. */
machine_save(m);
p = machine_bus_path(m);
if (!p)
return -ENOMEM;
return sd_bus_reply_method_return(c, "o", p);
}