From a61bbb370941c9d0590cd05e72d5823039de2321 Mon Sep 17 00:00:00 2001 From: Chris Webb Date: Mon, 24 Apr 2023 15:37:45 +0100 Subject: [PATCH] mount: add --map-users and --map-groups convenience options Allow an X-mount.idmap option to be specified either from an existing userns with --map-users=/proc/PID/ns/user or incrementally with a series of --map-users=INNER:OUTER:COUNT and --map-groups=INNER:OUTER:COUNT options which compose into a single X-mount.idmap mount option. Apart from distinguishing absolute namespace paths from literal mappings, defer validation to libmount when it parses X-mount.idmap. Signed-off-by: Chris Webb --- sys-utils/mount.8.adoc | 6 ++++++ sys-utils/mount.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index e39ac766b6..c20547e8cc 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -340,6 +340,12 @@ Move a subtree to some other place. See above, the subsection *The move operatio *-m*, **--mkdir**[=__mode__]:: Allow to make a target directory (mountpoint) if it does not exist yet. Alias to "-o X-mount.mkdir[=mode]", the default mode is 0755. For more details see *X-mount.mkdir* below. +*--map-groups*, *--map-users* _inner_:_outer_:_count_:: +Add the specified user/group mapping to an *X-mount.idmap* map. These options can be given multiple times to build up complete mappings for users and groups. For more details see *X-mount.idmap* below. + +*--map-users* /proc/_PID_/ns/user:: +Use the specified user namespace for user and group mapping in an id-mapped mount. This is an alias for "-o X-mount.idmap=/proc/_PID_/ns/user" and cannot be used twice nor together with the _inner_:_outer_:_count_ option format above. For more details see *X-mount.idmap* below. + *-n*, *--no-mtab*:: Mount without writing in _/etc/mtab_. This is necessary for example when _/etc_ is on a read-only filesystem. diff --git a/sys-utils/mount.c b/sys-utils/mount.c index dba6fcae92..abed9a03ab 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -501,6 +501,12 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -T, --fstab alternative file to /etc/fstab\n"), out); fputs(_(" -i, --internal-only don't call the mount. helpers\n"), out); fputs(_(" -l, --show-labels show also filesystem labels\n"), out); + fputs(_(" --map-groups ::\n" + " add the specified GID map to an ID-mapped mount\n"), out); + fputs(_(" --map-users ::\n" + " add the specified UID map to an ID-mapped mount\n"), out); + fputs(_(" --map-users /proc//ns/user\n" + " specify the user namespace for an ID-mapped mount\n"), out); fputs(_(" -m, --mkdir[=] alias to '-o X-mount.mkdir[=]'\n"), out); fputs(_(" -n, --no-mtab don't write to /etc/mtab\n"), out); fputs(_(" --options-mode \n" @@ -615,6 +621,7 @@ int main(int argc, char **argv) int c, rc = MNT_EX_SUCCESS, all = 0, show_labels = 0; struct libmnt_context *cxt; struct libmnt_table *fstab = NULL; + char *idmap = NULL; char *srcbuf = NULL; char *types = NULL; int oper = 0, is_move = 0; @@ -630,6 +637,8 @@ int main(int argc, char **argv) MOUNT_OPT_RSLAVE, MOUNT_OPT_RPRIVATE, MOUNT_OPT_RUNBINDABLE, + MOUNT_OPT_MAP_GROUPS, + MOUNT_OPT_MAP_USERS, MOUNT_OPT_TARGET, MOUNT_OPT_TARGET_PREFIX, MOUNT_OPT_SOURCE, @@ -668,6 +677,8 @@ int main(int argc, char **argv) { "make-rslave", no_argument, NULL, MOUNT_OPT_RSLAVE }, { "make-rprivate", no_argument, NULL, MOUNT_OPT_RPRIVATE }, { "make-runbindable", no_argument, NULL, MOUNT_OPT_RUNBINDABLE }, + { "map-groups", required_argument, NULL, MOUNT_OPT_MAP_GROUPS }, + { "map-users", required_argument, NULL, MOUNT_OPT_MAP_USERS }, { "mkdir", optional_argument, NULL, 'm' }, { "no-canonicalize", no_argument, NULL, 'c' }, { "internal-only", no_argument, NULL, 'i' }, @@ -850,6 +861,23 @@ int main(int argc, char **argv) append_option(cxt, "runbindable", NULL); propa = 1; break; + case MOUNT_OPT_MAP_GROUPS: + case MOUNT_OPT_MAP_USERS: + if (optarg && *optarg == '=') + optarg++; + if (idmap && (*idmap == '/' || *optarg == '/')) { + warnx(_("bad usage")); + errtryhelp(MNT_EX_USAGE); + } else if (*optarg == '/') { + idmap = xstrdup(optarg); + } else { + char *tmp; + xasprintf(&tmp, "%s%s%s%s", idmap ? idmap : "", idmap ? " " : "", + c == MOUNT_OPT_MAP_GROUPS ? "g:" : "u:", optarg); + free(idmap); + idmap = tmp; + } + break; case MOUNT_OPT_TARGET: mnt_context_disable_swapmatch(cxt, 1); mnt_context_set_target(cxt, optarg); @@ -898,6 +926,9 @@ int main(int argc, char **argv) argc -= optind; argv += optind; + if (idmap) + append_option(cxt, "X-mount.idmap", idmap); + optmode |= optmode_mode | optmode_src; if (optmode) { if (!optmode_mode) -- 2.47.2