Aside from the usual boilerplate of moving the shared logic to shared/, we also rework the implementation of --bind-user= to be similar to what we'll do in systemd-vmspawn. Instead of messing with the nspawn container user namespace, we use idmapped mounts to map the user's home directory on the host to the mapped uid in the container. Ideally we'd also use the "userdb.transient" credentials to provision the user records, but this would only work for booted containers, whereas the current logic works for non-booted containers as well. Aside from being similar to how we'll implement --bind-user= in vmspawn, using idmapped mounts also allows supporting --bind-user= without having to use --private-users=.
80 lines
4.1 KiB
C
80 lines
4.1 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include "forward.h"
|
|
#include "volatile-util.h"
|
|
|
|
typedef enum MountSettingsMask {
|
|
MOUNT_FATAL = 1 << 0, /* if set, a mount error is considered fatal */
|
|
MOUNT_USE_USERNS = 1 << 1, /* if set, mounts are patched considering uid/gid shifts in a user namespace */
|
|
MOUNT_IN_USERNS = 1 << 2, /* if set, the mount is executed in the inner child, otherwise in the outer child */
|
|
MOUNT_APPLY_APIVFS_RO = 1 << 3, /* if set, /proc/sys, and /sys will be mounted read-only, otherwise read-write. */
|
|
MOUNT_APPLY_APIVFS_NETNS = 1 << 4, /* if set, /proc/sys/net will be mounted read-write.
|
|
Works only if MOUNT_APPLY_APIVFS_RO is also set. */
|
|
MOUNT_APPLY_TMPFS_TMP = 1 << 5, /* if set, /tmp will be mounted as tmpfs */
|
|
MOUNT_ROOT_ONLY = 1 << 6, /* if set, only root mounts are mounted */
|
|
MOUNT_NON_ROOT_ONLY = 1 << 7, /* if set, only non-root mounts are mounted */
|
|
MOUNT_MKDIR = 1 << 8, /* if set, make directory to mount over first */
|
|
MOUNT_TOUCH = 1 << 9, /* if set, touch file to mount over first */
|
|
MOUNT_PREFIX_ROOT = 1 << 10,/* if set, prefix the source path with the container's root directory */
|
|
MOUNT_FOLLOW_SYMLINKS = 1 << 11,/* if set, we'll follow symlinks for the mount target */
|
|
MOUNT_UNMANAGED = 1 << 12,/* if set, we'll only mount this in the outer child if we are running in privileged mode */
|
|
MOUNT_PRIVILEGED = 1 << 13,/* if set, we'll only mount this if we have full privileges */
|
|
MOUNT_USRQUOTA_GRACEFUL = 1 << 14,/* if set, append "usrquota" to mount options if kernel tmpfs supports that */
|
|
} MountSettingsMask;
|
|
|
|
typedef enum CustomMountType {
|
|
CUSTOM_MOUNT_BIND,
|
|
CUSTOM_MOUNT_TMPFS,
|
|
CUSTOM_MOUNT_OVERLAY,
|
|
CUSTOM_MOUNT_INACCESSIBLE,
|
|
CUSTOM_MOUNT_ARBITRARY,
|
|
_CUSTOM_MOUNT_TYPE_MAX,
|
|
_CUSTOM_MOUNT_TYPE_INVALID = -EINVAL,
|
|
} CustomMountType;
|
|
|
|
typedef struct CustomMount {
|
|
CustomMountType type;
|
|
bool read_only;
|
|
char *source; /* for overlayfs this is the upper directory */
|
|
char *destination;
|
|
uid_t destination_uid;
|
|
char *options;
|
|
char *work_dir;
|
|
char **lower;
|
|
char *rm_rf_tmpdir;
|
|
char *type_argument; /* only for CUSTOM_MOUNT_ARBITRARY */
|
|
bool graceful;
|
|
bool in_userns;
|
|
} CustomMount;
|
|
|
|
CustomMount* custom_mount_add(CustomMount **l, size_t *n, CustomMountType t);
|
|
void custom_mount_free_all(CustomMount *l, size_t n);
|
|
int custom_mount_prepare_all(const char *dest, CustomMount *l, size_t n);
|
|
|
|
int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only);
|
|
int tmpfs_mount_parse(CustomMount **l, size_t *n, const char *s);
|
|
int overlay_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only);
|
|
int inaccessible_mount_parse(CustomMount **l, size_t *n, const char *s);
|
|
|
|
int mount_all(const char *dest, MountSettingsMask mount_settings, uid_t uid_shift, const char *selinux_apifs_context);
|
|
int mount_sysfs(const char *dest, MountSettingsMask mount_settings);
|
|
|
|
int mount_custom(const char *dest, CustomMount *mounts, size_t n, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context, MountSettingsMask mount_settings);
|
|
bool has_custom_root_mount(const CustomMount *mounts, size_t n);
|
|
|
|
int setup_volatile_mode(const char *directory, VolatileMode mode, uid_t uid_shift, const char *selinux_apifs_context);
|
|
int setup_volatile_mode_after_remount_idmap(
|
|
const char *directory,
|
|
VolatileMode mode,
|
|
uid_t uid_shift,
|
|
const char *selinux_apifs_context);
|
|
|
|
int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s);
|
|
int setup_pivot_root(const char *directory, const char *pivot_root_new, const char *pivot_root_old);
|
|
|
|
int tmpfs_patch_options(const char *options,uid_t uid_shift, const char *selinux_apifs_context, char **ret);
|
|
|
|
int pin_fully_visible_api_fs(void);
|
|
int wipe_fully_visible_api_fs(int mntns_fd);
|