diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-05-21 16:30:58 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-05-21 16:32:01 +0200 |
commit | 03cfe0d51499e86b1573d121337594719d9f2012 (patch) | |
tree | cb76a92a501b16909f879944a4ad29ce88eefbad /src/shared | |
parent | ef6fc8ee57eff8a2b612de0270c9a25e066ee290 (diff) |
nspawn: finish user namespace support
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/base-filesystem.c | 16 | ||||
-rw-r--r-- | src/shared/base-filesystem.h | 4 | ||||
-rw-r--r-- | src/shared/dev-setup.c | 29 | ||||
-rw-r--r-- | src/shared/dev-setup.h | 4 | ||||
-rw-r--r-- | src/shared/switch-root.c | 2 |
5 files changed, 42 insertions, 13 deletions
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c index 11e0947407..ab6fc171b0 100644 --- a/src/shared/base-filesystem.c +++ b/src/shared/base-filesystem.c @@ -41,13 +41,16 @@ static const BaseFilesystem table[] = { { "lib", 0, "usr/lib\0", NULL }, { "root", 0755, NULL, NULL }, { "sbin", 0, "usr/sbin\0", NULL }, + { "usr", 0755, NULL, NULL }, + { "var", 0755, NULL, NULL }, + { "etc", 0755, NULL, NULL }, #if defined(__i386__) || defined(__x86_64__) { "lib64", 0, "usr/lib/x86_64-linux-gnu\0" "usr/lib64\0", "ld-linux-x86-64.so.2" }, #endif }; -int base_filesystem_create(const char *root) { +int base_filesystem_create(const char *root, uid_t uid, gid_t gid) { _cleanup_close_ int fd = -1; unsigned i; int r = 0; @@ -90,6 +93,12 @@ int base_filesystem_create(const char *root) { r = symlinkat(target, fd, table[i].dir); if (r < 0 && errno != EEXIST) return log_error_errno(errno, "Failed to create symlink at %s/%s: %m", root, table[i].dir); + + if (uid != UID_INVALID || gid != UID_INVALID) { + if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0) + return log_error_errno(errno, "Failed to chown symlink at %s/%s: %m", root, table[i].dir); + } + continue; } @@ -97,6 +106,11 @@ int base_filesystem_create(const char *root) { r = mkdirat(fd, table[i].dir, table[i].mode); if (r < 0 && errno != EEXIST) return log_error_errno(errno, "Failed to create directory at %s/%s: %m", root, table[i].dir); + + if (uid != UID_INVALID || gid != UID_INVALID) { + if (fchownat(fd, table[i].dir, uid, gid, AT_SYMLINK_NOFOLLOW) < 0) + return log_error_errno(errno, "Failed to chown directory at %s/%s: %m", root, table[i].dir); + } } return 0; diff --git a/src/shared/base-filesystem.h b/src/shared/base-filesystem.h index 03201f7083..39a496090f 100644 --- a/src/shared/base-filesystem.h +++ b/src/shared/base-filesystem.h @@ -21,4 +21,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -int base_filesystem_create(const char *root); +#include <sys/types.h> + +int base_filesystem_create(const char *root, uid_t uid, gid_t gid); diff --git a/src/shared/dev-setup.c b/src/shared/dev-setup.c index cb15da8a5d..25ad918b85 100644 --- a/src/shared/dev-setup.c +++ b/src/shared/dev-setup.c @@ -23,13 +23,12 @@ #include <stdlib.h> #include <unistd.h> -#include "dev-setup.h" #include "util.h" #include "label.h" +#include "path-util.h" +#include "dev-setup.h" -int dev_setup(const char *prefix) { - const char *j, *k; - +int dev_setup(const char *prefix, uid_t uid, gid_t gid) { static const char symlinks[] = "-/proc/kcore\0" "/dev/core\0" "/proc/self/fd\0" "/dev/fd\0" @@ -37,7 +36,13 @@ int dev_setup(const char *prefix) { "/proc/self/fd/1\0" "/dev/stdout\0" "/proc/self/fd/2\0" "/dev/stderr\0"; + const char *j, *k; + int r; + NULSTR_FOREACH_PAIR(j, k, symlinks) { + _cleanup_free_ char *link_name = NULL; + const char *n; + if (j[0] == '-') { j++; @@ -46,15 +51,21 @@ int dev_setup(const char *prefix) { } if (prefix) { - _cleanup_free_ char *link_name = NULL; - - link_name = strjoin(prefix, "/", k, NULL); + link_name = prefix_root(prefix, k); if (!link_name) return -ENOMEM; - symlink_label(j, link_name); + n = link_name; } else - symlink_label(j, k); + n = k; + + r = symlink_label(j, n); + if (r < 0) + log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n); + + if (uid != UID_INVALID || gid != GID_INVALID) + if (lchown(n, uid, gid) < 0) + log_debug_errno(errno, "Failed to chown %s: %m", n); } return 0; diff --git a/src/shared/dev-setup.h b/src/shared/dev-setup.h index d41b6eefba..ab2748db7f 100644 --- a/src/shared/dev-setup.h +++ b/src/shared/dev-setup.h @@ -21,4 +21,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -int dev_setup(const char *pathprefix); +#include <sys/types.h> + +int dev_setup(const char *prefix, uid_t uid, gid_t gid); diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index ae3839de16..b12189cd10 100644 --- a/src/shared/switch-root.c +++ b/src/shared/switch-root.c @@ -105,7 +105,7 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, * to look like. They might even boot, if they are RO and * don't have the FS layout. Just ignore the error and * switch_root() nevertheless. */ - (void) base_filesystem_create(new_root); + (void) base_filesystem_create(new_root, UID_INVALID, GID_INVALID); if (chdir(new_root) < 0) return log_error_errno(errno, "Failed to change directory to %s: %m", new_root); |