summaryrefslogtreecommitdiff
path: root/src/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/machine')
l---------src/machine/Makefile1
-rw-r--r--src/machine/nss-mymachines/nss-mymachines.c738
-rw-r--r--src/machine/nss-mymachines/nss-mymachines.sym21
-rw-r--r--src/machine/src/.gitignore (renamed from src/machine/.gitignore)0
-rw-r--r--src/machine/src/Makefile128
-rw-r--r--src/machine/src/image-dbus.c (renamed from src/machine/image-dbus.c)0
-rw-r--r--src/machine/src/image-dbus.h (renamed from src/machine/image-dbus.h)0
-rw-r--r--src/machine/src/machine-dbus.c (renamed from src/machine/machine-dbus.c)0
-rw-r--r--src/machine/src/machine-dbus.h (renamed from src/machine/machine-dbus.h)2
-rw-r--r--src/machine/src/machine.c (renamed from src/machine/machine.c)2
-rw-r--r--src/machine/src/machine.h (renamed from src/machine/machine.h)0
-rw-r--r--src/machine/src/machinectl.c (renamed from src/machine/machinectl.c)2
-rw-r--r--src/machine/src/machined-dbus.c (renamed from src/machine/machined-dbus.c)2
-rw-r--r--src/machine/src/machined.c (renamed from src/machine/machined.c)2
-rw-r--r--src/machine/src/machined.h (renamed from src/machine/machined.h)4
-rw-r--r--src/machine/src/org.freedesktop.machine1.conf (renamed from src/machine/org.freedesktop.machine1.conf)0
-rw-r--r--src/machine/src/org.freedesktop.machine1.policy.in (renamed from src/machine/org.freedesktop.machine1.policy.in)0
-rw-r--r--src/machine/src/org.freedesktop.machine1.service (renamed from src/machine/org.freedesktop.machine1.service)0
-rw-r--r--src/machine/src/test-machine-tables.c (renamed from src/machine/test-machine-tables.c)0
19 files changed, 894 insertions, 8 deletions
diff --git a/src/machine/Makefile b/src/machine/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/machine/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/machine/nss-mymachines/nss-mymachines.c b/src/machine/nss-mymachines/nss-mymachines.c
new file mode 100644
index 0000000000..9d401b39dd
--- /dev/null
+++ b/src/machine/nss-mymachines/nss-mymachines.c
@@ -0,0 +1,738 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netdb.h>
+#include <nss.h>
+
+#include <systemd/sd-bus.h>
+#include <systemd/sd-login.h>
+
+#include "alloc-util.h"
+#include "bus-common-errors.h"
+#include "hostname-util.h"
+#include "in-addr-util.h"
+#include "macro.h"
+#include "nss-util.h"
+#include "signal-util.h"
+#include "string-util.h"
+#include "user-util.h"
+#include "util.h"
+
+NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
+NSS_GETPW_PROTOTYPES(mymachines);
+NSS_GETGR_PROTOTYPES(mymachines);
+
+#define HOST_UID_LIMIT ((uid_t) UINT32_C(0x10000))
+#define HOST_GID_LIMIT ((gid_t) UINT32_C(0x10000))
+
+static int count_addresses(sd_bus_message *m, int af, unsigned *ret) {
+ unsigned c = 0;
+ int r;
+
+ assert(m);
+ assert(ret);
+
+ while ((r = sd_bus_message_enter_container(m, 'r', "iay")) > 0) {
+ int family;
+
+ r = sd_bus_message_read(m, "i", &family);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_skip(m, "ay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+
+ if (af != AF_UNSPEC && family != af)
+ continue;
+
+ c ++;
+ }
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_rewind(m, false);
+ if (r < 0)
+ return r;
+
+ *ret = c;
+ return 0;
+}
+
+enum nss_status _nss_mymachines_gethostbyname4_r(
+ const char *name,
+ struct gaih_addrtuple **pat,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp) {
+
+ struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ int *ifindices = NULL;
+ _cleanup_free_ char *class = NULL;
+ size_t l, ms, idx;
+ unsigned i = 0, c = 0;
+ char *r_name;
+ int n_ifindices, r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(pat);
+ assert(buffer);
+ assert(errnop);
+ assert(h_errnop);
+
+ r = sd_machine_get_class(name, &class);
+ if (r < 0)
+ goto fail;
+ if (!streq(class, "container")) {
+ r = -ENOTTY;
+ goto fail;
+ }
+
+ n_ifindices = sd_machine_get_ifindices(name, &ifindices);
+ if (n_ifindices < 0) {
+ r = n_ifindices;
+ goto fail;
+ }
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachineAddresses",
+ NULL,
+ &reply,
+ "s", name);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+ if (r < 0)
+ goto fail;
+
+ r = count_addresses(reply, AF_UNSPEC, &c);
+ if (r < 0)
+ goto fail;
+
+ if (c <= 0) {
+ *errnop = ESRCH;
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ l = strlen(name);
+ ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * c;
+ if (buflen < ms) {
+ *errnop = ENOMEM;
+ *h_errnop = TRY_AGAIN;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ /* First, append name */
+ r_name = buffer;
+ memcpy(r_name, name, l+1);
+ idx = ALIGN(l+1);
+
+ /* Second, append addresses */
+ r_tuple_first = (struct gaih_addrtuple*) (buffer + idx);
+ while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+ int family;
+ const void *a;
+ size_t sz;
+
+ r = sd_bus_message_read(reply, "i", &family);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto fail;
+
+ if (!IN_SET(family, AF_INET, AF_INET6)) {
+ r = -EAFNOSUPPORT;
+ goto fail;
+ }
+
+ if (sz != FAMILY_ADDRESS_SIZE(family)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ r_tuple = (struct gaih_addrtuple*) (buffer + idx);
+ r_tuple->next = i == c-1 ? NULL : (struct gaih_addrtuple*) ((char*) r_tuple + ALIGN(sizeof(struct gaih_addrtuple)));
+ r_tuple->name = r_name;
+ r_tuple->family = family;
+ r_tuple->scopeid = n_ifindices == 1 ? ifindices[0] : 0;
+ memcpy(r_tuple->addr, a, sz);
+
+ idx += ALIGN(sizeof(struct gaih_addrtuple));
+ i++;
+ }
+
+ assert(i == c);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto fail;
+
+ assert(idx == ms);
+
+ if (*pat)
+ **pat = *r_tuple_first;
+ else
+ *pat = r_tuple_first;
+
+ if (ttlp)
+ *ttlp = 0;
+
+ /* Explicitly reset all error variables */
+ *errnop = 0;
+ *h_errnop = NETDB_SUCCESS;
+ h_errno = 0;
+
+ return NSS_STATUS_SUCCESS;
+
+fail:
+ *errnop = -r;
+ *h_errnop = NO_DATA;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_mymachines_gethostbyname3_r(
+ const char *name,
+ int af,
+ struct hostent *result,
+ char *buffer, size_t buflen,
+ int *errnop, int *h_errnop,
+ int32_t *ttlp,
+ char **canonp) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *class = NULL;
+ unsigned c = 0, i = 0;
+ char *r_name, *r_aliases, *r_addr, *r_addr_list;
+ size_t l, idx, ms, alen;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(result);
+ assert(buffer);
+ assert(errnop);
+ assert(h_errnop);
+
+ if (af == AF_UNSPEC)
+ af = AF_INET;
+
+ if (af != AF_INET && af != AF_INET6) {
+ r = -EAFNOSUPPORT;
+ goto fail;
+ }
+
+ r = sd_machine_get_class(name, &class);
+ if (r < 0)
+ goto fail;
+ if (!streq(class, "container")) {
+ r = -ENOTTY;
+ goto fail;
+ }
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "GetMachineAddresses",
+ NULL,
+ &reply,
+ "s", name);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_enter_container(reply, 'a', "(iay)");
+ if (r < 0)
+ goto fail;
+
+ r = count_addresses(reply, af, &c);
+ if (r < 0)
+ goto fail;
+
+ if (c <= 0) {
+ *errnop = ENOENT;
+ *h_errnop = HOST_NOT_FOUND;
+ return NSS_STATUS_NOTFOUND;
+ }
+
+ alen = FAMILY_ADDRESS_SIZE(af);
+ l = strlen(name);
+
+ ms = ALIGN(l+1) + c * ALIGN(alen) + (c+2) * sizeof(char*);
+
+ if (buflen < ms) {
+ *errnop = ENOMEM;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ /* First, append name */
+ r_name = buffer;
+ memcpy(r_name, name, l+1);
+ idx = ALIGN(l+1);
+
+ /* Second, create aliases array */
+ r_aliases = buffer + idx;
+ ((char**) r_aliases)[0] = NULL;
+ idx += sizeof(char*);
+
+ /* Third, append addresses */
+ r_addr = buffer + idx;
+ while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
+ int family;
+ const void *a;
+ size_t sz;
+
+ r = sd_bus_message_read(reply, "i", &family);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_read_array(reply, 'y', &a, &sz);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto fail;
+
+ if (family != af)
+ continue;
+
+ if (sz != alen) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ memcpy(r_addr + i*ALIGN(alen), a, alen);
+ i++;
+ }
+
+ assert(i == c);
+ idx += c * ALIGN(alen);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ goto fail;
+
+ /* Third, append address pointer array */
+ r_addr_list = buffer + idx;
+ for (i = 0; i < c; i++)
+ ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
+
+ ((char**) r_addr_list)[i] = NULL;
+ idx += (c+1) * sizeof(char*);
+
+ assert(idx == ms);
+
+ result->h_name = r_name;
+ result->h_aliases = (char**) r_aliases;
+ result->h_addrtype = af;
+ result->h_length = alen;
+ result->h_addr_list = (char**) r_addr_list;
+
+ if (ttlp)
+ *ttlp = 0;
+
+ if (canonp)
+ *canonp = r_name;
+
+ /* Explicitly reset all error variables */
+ *errnop = 0;
+ *h_errnop = NETDB_SUCCESS;
+ h_errno = 0;
+
+ return NSS_STATUS_SUCCESS;
+
+fail:
+ *errnop = -r;
+ *h_errnop = NO_DATA;
+ return NSS_STATUS_UNAVAIL;
+}
+
+NSS_GETHOSTBYNAME_FALLBACKS(mymachines);
+
+enum nss_status _nss_mymachines_getpwnam_r(
+ const char *name,
+ struct passwd *pwd,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ const char *p, *e, *machine;
+ uint32_t mapped;
+ uid_t uid;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(pwd);
+
+ p = startswith(name, "vu-");
+ if (!p)
+ goto not_found;
+
+ e = strrchr(p, '-');
+ if (!e || e == p)
+ goto not_found;
+
+ if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
+ goto not_found;
+
+ r = parse_uid(e + 1, &uid);
+ if (r < 0)
+ goto not_found;
+
+ machine = strndupa(p, e - p);
+ if (!machine_name_is_valid(machine))
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "MapFromMachineUser",
+ &error,
+ &reply,
+ "su",
+ machine, (uint32_t) uid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "u", &mapped);
+ if (r < 0)
+ goto fail;
+
+ /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */
+ if (mapped < HOST_UID_LIMIT || mapped == uid)
+ goto not_found;
+
+ l = strlen(name);
+ if (buflen < l+1) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memcpy(buffer, name, l+1);
+
+ pwd->pw_name = buffer;
+ pwd->pw_uid = mapped;
+ pwd->pw_gid = 65534; /* nobody */
+ pwd->pw_gecos = buffer;
+ pwd->pw_passwd = (char*) "*"; /* locked */
+ pwd->pw_dir = (char*) "/";
+ pwd->pw_shell = (char*) "/sbin/nologin";
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_mymachines_getpwuid_r(
+ uid_t uid,
+ struct passwd *pwd,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ const char *machine, *object;
+ uint32_t mapped;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ if (!uid_is_valid(uid)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ /* We consider all uids < 65536 host uids */
+ if (uid < HOST_UID_LIMIT)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "MapToMachineUser",
+ &error,
+ &reply,
+ "u",
+ (uint32_t) uid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_USER_MAPPING))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "sou", &machine, &object, &mapped);
+ if (r < 0)
+ goto fail;
+
+ if (mapped == uid)
+ goto not_found;
+
+ if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ pwd->pw_name = buffer;
+ pwd->pw_uid = uid;
+ pwd->pw_gid = 65534; /* nobody */
+ pwd->pw_gecos = buffer;
+ pwd->pw_passwd = (char*) "*"; /* locked */
+ pwd->pw_dir = (char*) "/";
+ pwd->pw_shell = (char*) "/sbin/nologin";
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_mymachines_getgrnam_r(
+ const char *name,
+ struct group *gr,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ const char *p, *e, *machine;
+ uint32_t mapped;
+ uid_t gid;
+ size_t l;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ assert(name);
+ assert(gr);
+
+ p = startswith(name, "vg-");
+ if (!p)
+ goto not_found;
+
+ e = strrchr(p, '-');
+ if (!e || e == p)
+ goto not_found;
+
+ if (e - p > HOST_NAME_MAX - 1) /* -1 for the last dash */
+ goto not_found;
+
+ r = parse_gid(e + 1, &gid);
+ if (r < 0)
+ goto not_found;
+
+ machine = strndupa(p, e - p);
+ if (!machine_name_is_valid(machine))
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "MapFromMachineGroup",
+ &error,
+ &reply,
+ "su",
+ machine, (uint32_t) gid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "u", &mapped);
+ if (r < 0)
+ goto fail;
+
+ if (mapped < HOST_GID_LIMIT || mapped == gid)
+ goto not_found;
+
+ l = sizeof(char*) + strlen(name) + 1;
+ if (buflen < l) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memzero(buffer, sizeof(char*));
+ strcpy(buffer + sizeof(char*), name);
+
+ gr->gr_name = buffer + sizeof(char*);
+ gr->gr_gid = gid;
+ gr->gr_passwd = (char*) "*"; /* locked */
+ gr->gr_mem = (char**) buffer;
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
+
+enum nss_status _nss_mymachines_getgrgid_r(
+ gid_t gid,
+ struct group *gr,
+ char *buffer, size_t buflen,
+ int *errnop) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message* reply = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ const char *machine, *object;
+ uint32_t mapped;
+ int r;
+
+ BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
+
+ if (!gid_is_valid(gid)) {
+ r = -EINVAL;
+ goto fail;
+ }
+
+ /* We consider all gids < 65536 host gids */
+ if (gid < HOST_GID_LIMIT)
+ goto not_found;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0)
+ goto fail;
+
+ r = sd_bus_call_method(bus,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "MapToMachineGroup",
+ &error,
+ &reply,
+ "u",
+ (uint32_t) gid);
+ if (r < 0) {
+ if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_GROUP_MAPPING))
+ goto not_found;
+
+ goto fail;
+ }
+
+ r = sd_bus_message_read(reply, "sou", &machine, &object, &mapped);
+ if (r < 0)
+ goto fail;
+
+ if (mapped == gid)
+ goto not_found;
+
+ if (buflen < sizeof(char*) + 1) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ memzero(buffer, sizeof(char*));
+ if (snprintf(buffer + sizeof(char*), buflen - sizeof(char*), "vg-%s-" GID_FMT, machine, (gid_t) mapped) >= (int) buflen) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ gr->gr_name = buffer + sizeof(char*);
+ gr->gr_gid = gid;
+ gr->gr_passwd = (char*) "*"; /* locked */
+ gr->gr_mem = (char**) buffer;
+
+ *errnop = 0;
+ return NSS_STATUS_SUCCESS;
+
+not_found:
+ *errnop = 0;
+ return NSS_STATUS_NOTFOUND;
+
+fail:
+ *errnop = -r;
+ return NSS_STATUS_UNAVAIL;
+}
diff --git a/src/machine/nss-mymachines/nss-mymachines.sym b/src/machine/nss-mymachines/nss-mymachines.sym
new file mode 100644
index 0000000000..0728ac3ba7
--- /dev/null
+++ b/src/machine/nss-mymachines/nss-mymachines.sym
@@ -0,0 +1,21 @@
+/***
+ This file is part of systemd.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+***/
+
+{
+global:
+ _nss_mymachines_gethostbyname_r;
+ _nss_mymachines_gethostbyname2_r;
+ _nss_mymachines_gethostbyname3_r;
+ _nss_mymachines_gethostbyname4_r;
+ _nss_mymachines_getpwnam_r;
+ _nss_mymachines_getpwuid_r;
+ _nss_mymachines_getgrnam_r;
+ _nss_mymachines_getgrgid_r;
+local: *;
+};
diff --git a/src/machine/.gitignore b/src/machine/src/.gitignore
index e1065b5894..e1065b5894 100644
--- a/src/machine/.gitignore
+++ b/src/machine/src/.gitignore
diff --git a/src/machine/src/Makefile b/src/machine/src/Makefile
new file mode 100644
index 0000000000..43a799440d
--- /dev/null
+++ b/src/machine/src/Makefile
@@ -0,0 +1,128 @@
+# -*- Mode: makefile; indent-tabs-mode: t -*-
+#
+# This file is part of systemd.
+#
+# Copyright 2010-2012 Lennart Poettering
+# Copyright 2010-2012 Kay Sievers
+# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013 David Strauss
+# Copyright 2016 Luke Shumaker
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk
+include $(topsrcdir)/build-aux/Makefile.head.mk
+
+ifneq ($(ENABLE_MACHINED),)
+systemd_machined_SOURCES = \
+ src/machine/machined.c \
+ src/machine/machined.h
+
+systemd_machined_LDADD = \
+ libmachine-core.la
+
+rootlibexec_PROGRAMS += \
+ systemd-machined
+
+libmachine_core_la_SOURCES = \
+ src/machine/machine.c \
+ src/machine/machine.h \
+ src/machine/machined-dbus.c \
+ src/machine/machine-dbus.c \
+ src/machine/machine-dbus.h \
+ src/machine/image-dbus.c \
+ src/machine/image-dbus.h
+
+libmachine_core_la_LIBADD = \
+ libshared.la
+
+noinst_LTLIBRARIES += \
+ libmachine-core.la
+
+machinectl_SOURCES = \
+ src/machine/machinectl.c
+
+machinectl_LDADD = \
+ libshared.la
+
+rootbin_PROGRAMS += \
+ machinectl
+
+test_machine_tables_SOURCES = \
+ src/machine/test-machine-tables.c
+
+test_machine_tables_LDADD = \
+ libmachine-core.la
+
+tests += \
+ test-machine-tables
+
+nodist_systemunit_DATA += \
+ units/systemd-machined.service
+
+dist_systemunit_DATA += \
+ units/machine.slice
+
+dist_systemunit_DATA_busnames += \
+ units/org.freedesktop.machine1.busname
+
+dist_dbussystemservice_DATA += \
+ src/machine/org.freedesktop.machine1.service
+
+dist_dbuspolicy_DATA += \
+ src/machine/org.freedesktop.machine1.conf
+
+polkitpolicy_files += \
+ src/machine/org.freedesktop.machine1.policy
+
+dist_bashcompletion_data += \
+ shell-completion/bash/machinectl
+
+dist_zshcompletion_data += \
+ shell-completion/zsh/_machinectl \
+ shell-completion/zsh/_sd_machines
+
+SYSTEM_UNIT_ALIASES += \
+ systemd-machined.service dbus-org.freedesktop.machine1.service
+
+BUSNAMES_TARGET_WANTS += \
+ org.freedesktop.machine1.busname
+
+libnss_mymachines_la_SOURCES = \
+ src/nss-mymachines/nss-mymachines.sym \
+ src/nss-mymachines/nss-mymachines.c
+
+libnss_mymachines_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -module \
+ -export-dynamic \
+ -avoid-version \
+ -shared \
+ -shrext .so.2 \
+ -Wl,--version-script=$(top_srcdir)/src/nss-mymachines/nss-mymachines.sym
+
+libnss_mymachines_la_LIBADD = \
+ libsystemd-internal.la
+
+lib_LTLIBRARIES += \
+ libnss_mymachines.la
+
+endif
+
+polkitpolicy_in_files += \
+ src/machine/org.freedesktop.machine1.policy.in
+
+EXTRA_DIST += \
+ units/systemd-machined.service.in
+
+include $(topsrcdir)/build-aux/Makefile.tail.mk
diff --git a/src/machine/image-dbus.c b/src/machine/src/image-dbus.c
index 73f5112c4d..73f5112c4d 100644
--- a/src/machine/image-dbus.c
+++ b/src/machine/src/image-dbus.c
diff --git a/src/machine/image-dbus.h b/src/machine/src/image-dbus.h
index b62da996c6..b62da996c6 100644
--- a/src/machine/image-dbus.h
+++ b/src/machine/src/image-dbus.h
diff --git a/src/machine/machine-dbus.c b/src/machine/src/machine-dbus.c
index 71f20b3f07..71f20b3f07 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/src/machine-dbus.c
diff --git a/src/machine/machine-dbus.h b/src/machine/src/machine-dbus.h
index 3a8162b171..224f36529f 100644
--- a/src/machine/machine-dbus.h
+++ b/src/machine/src/machine-dbus.h
@@ -19,7 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "sd-bus.h"
+#include <systemd/sd-bus.h>
#include "machine.h"
diff --git a/src/machine/machine.c b/src/machine/src/machine.c
index 406d5a4b85..468fc1fecf 100644
--- a/src/machine/machine.c
+++ b/src/machine/src/machine.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <unistd.h>
-#include "sd-messages.h"
+#include <systemd/sd-messages.h>
#include "alloc-util.h"
#include "bus-error.h"
diff --git a/src/machine/machine.h b/src/machine/src/machine.h
index 1d8cc5911a..1d8cc5911a 100644
--- a/src/machine/machine.h
+++ b/src/machine/src/machine.h
diff --git a/src/machine/machinectl.c b/src/machine/src/machinectl.c
index 4853139321..fb743ab6cb 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/src/machinectl.c
@@ -29,7 +29,7 @@
#include <sys/socket.h>
#include <unistd.h>
-#include "sd-bus.h"
+#include <systemd/sd-bus.h>
#include "alloc-util.h"
#include "bus-error.h"
diff --git a/src/machine/machined-dbus.c b/src/machine/src/machined-dbus.c
index b933099330..96f2c4769e 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/src/machined-dbus.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <unistd.h>
-#include "sd-id128.h"
+#include <systemd/sd-id128.h>
#include "alloc-util.h"
#include "btrfs-util.h"
diff --git a/src/machine/machined.c b/src/machine/src/machined.c
index f2c1966a6b..6ada8671f8 100644
--- a/src/machine/machined.c
+++ b/src/machine/src/machined.c
@@ -21,7 +21,7 @@
#include <string.h>
#include <unistd.h>
-#include "sd-daemon.h"
+#include <systemd/sd-daemon.h>
#include "alloc-util.h"
#include "bus-error.h"
diff --git a/src/machine/machined.h b/src/machine/src/machined.h
index e7d7dfdceb..0fe50aaa66 100644
--- a/src/machine/machined.h
+++ b/src/machine/src/machined.h
@@ -21,8 +21,8 @@
#include <stdbool.h>
-#include "sd-bus.h"
-#include "sd-event.h"
+#include <systemd/sd-bus.h>
+#include <systemd/sd-event.h>
#include "hashmap.h"
#include "list.h"
diff --git a/src/machine/org.freedesktop.machine1.conf b/src/machine/src/org.freedesktop.machine1.conf
index 9d40b90151..9d40b90151 100644
--- a/src/machine/org.freedesktop.machine1.conf
+++ b/src/machine/src/org.freedesktop.machine1.conf
diff --git a/src/machine/org.freedesktop.machine1.policy.in b/src/machine/src/org.freedesktop.machine1.policy.in
index 69f78a5c25..69f78a5c25 100644
--- a/src/machine/org.freedesktop.machine1.policy.in
+++ b/src/machine/src/org.freedesktop.machine1.policy.in
diff --git a/src/machine/org.freedesktop.machine1.service b/src/machine/src/org.freedesktop.machine1.service
index d3dc99852b..d3dc99852b 100644
--- a/src/machine/org.freedesktop.machine1.service
+++ b/src/machine/src/org.freedesktop.machine1.service
diff --git a/src/machine/test-machine-tables.c b/src/machine/src/test-machine-tables.c
index f851a4d37d..f851a4d37d 100644
--- a/src/machine/test-machine-tables.c
+++ b/src/machine/src/test-machine-tables.c