nspawn: support foreign mappings also when nspawn doing the mapping itself
This adds a new "foreign" value to --private-users-ownership= which is a lot like "map", but maps from the host's foreign UID range rather than from the host's 0. (This has nothing much to do with making unprivileged directory-based containers work, it's just very handy that we can run privileged contains with such a mapping too, with an easy switch)
This commit is contained in:
+34
-12
@@ -1359,9 +1359,15 @@ int fd_make_mount_point(int fd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int make_userns(uid_t uid_shift, uid_t uid_range, uid_t source_owner, uid_t dest_owner, RemountIdmapping idmapping) {
|
||||
int make_userns(uid_t uid_shift,
|
||||
uid_t uid_range,
|
||||
uid_t source_owner,
|
||||
uid_t dest_owner,
|
||||
RemountIdmapping idmapping) {
|
||||
|
||||
_cleanup_close_ int userns_fd = -EBADF;
|
||||
_cleanup_free_ char *line = NULL;
|
||||
uid_t source_base = 0;
|
||||
|
||||
/* Allocates a userns file descriptor with the mapping we need. For this we'll fork off a child
|
||||
* process whose only purpose is to give us a new user namespace. It's killed when we got it. */
|
||||
@@ -1369,8 +1375,18 @@ int make_userns(uid_t uid_shift, uid_t uid_range, uid_t source_owner, uid_t dest
|
||||
if (!userns_shift_range_valid(uid_shift, uid_range))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid UID range for user namespace.");
|
||||
|
||||
if (IN_SET(idmapping, REMOUNT_IDMAPPING_NONE, REMOUNT_IDMAPPING_HOST_ROOT)) {
|
||||
if (asprintf(&line, UID_FMT " " UID_FMT " " UID_FMT "\n", 0u, uid_shift, uid_range) < 0)
|
||||
switch (idmapping) {
|
||||
|
||||
case REMOUNT_IDMAPPING_FOREIGN_WITH_HOST_ROOT:
|
||||
source_base = FOREIGN_UID_BASE;
|
||||
_fallthrough_;
|
||||
|
||||
case REMOUNT_IDMAPPING_NONE:
|
||||
case REMOUNT_IDMAPPING_HOST_ROOT:
|
||||
|
||||
if (asprintf(&line,
|
||||
UID_FMT " " UID_FMT " " UID_FMT "\n",
|
||||
source_base, uid_shift, uid_range) < 0)
|
||||
return log_oom_debug();
|
||||
|
||||
/* If requested we'll include an entry in the mapping so that the host root user can make
|
||||
@@ -1387,28 +1403,34 @@ int make_userns(uid_t uid_shift, uid_t uid_range, uid_t source_owner, uid_t dest
|
||||
if (idmapping == REMOUNT_IDMAPPING_HOST_ROOT)
|
||||
if (strextendf(&line,
|
||||
UID_FMT " " UID_FMT " " UID_FMT "\n",
|
||||
UID_MAPPED_ROOT, 0u, 1u) < 0)
|
||||
UID_MAPPED_ROOT, (uid_t) 0u, (uid_t) 1u) < 0)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
if (idmapping == REMOUNT_IDMAPPING_HOST_OWNER) {
|
||||
break;
|
||||
|
||||
case REMOUNT_IDMAPPING_HOST_OWNER:
|
||||
/* Remap the owner of the bind mounted directory to the root user within the container. This
|
||||
* way every file written by root within the container to the bind-mounted directory will
|
||||
* be owned by the original user from the host. All other users will remain unmapped. */
|
||||
if (asprintf(&line, UID_FMT " " UID_FMT " " UID_FMT "\n", source_owner, uid_shift, 1u) < 0)
|
||||
if (asprintf(&line,
|
||||
UID_FMT " " UID_FMT " " UID_FMT "\n",
|
||||
source_owner, uid_shift, (uid_t) 1u) < 0)
|
||||
return log_oom_debug();
|
||||
}
|
||||
break;
|
||||
|
||||
if (idmapping == REMOUNT_IDMAPPING_HOST_OWNER_TO_TARGET_OWNER) {
|
||||
case REMOUNT_IDMAPPING_HOST_OWNER_TO_TARGET_OWNER:
|
||||
/* Remap the owner of the bind mounted directory to the owner of the target directory
|
||||
* within the container. This way every file written by target directory owner within the
|
||||
* container to the bind-mounted directory will be owned by the original host user.
|
||||
* All other users will remain unmapped. */
|
||||
if (asprintf(
|
||||
&line,
|
||||
if (asprintf(&line,
|
||||
UID_FMT " " UID_FMT " " UID_FMT "\n",
|
||||
source_owner, dest_owner, 1u) < 0)
|
||||
source_owner, dest_owner, (uid_t) 1u) < 0)
|
||||
return log_oom_debug();
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
/* We always assign the same UID and GID ranges */
|
||||
|
||||
Reference in New Issue
Block a user