Skip to content

Commit

Permalink
mount: add --map-users and --map-groups convenience options
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
arachsys committed Apr 24, 2023
1 parent 7511ffb commit a61bbb3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
6 changes: 6 additions & 0 deletions sys-utils/mount.8.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
31 changes: 31 additions & 0 deletions sys-utils/mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,12 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -T, --fstab <path> alternative file to /etc/fstab\n"), out);
fputs(_(" -i, --internal-only don't call the mount.<type> helpers\n"), out);
fputs(_(" -l, --show-labels show also filesystem labels\n"), out);
fputs(_(" --map-groups <inner>:<outer>:<count>\n"
" add the specified GID map to an ID-mapped mount\n"), out);
fputs(_(" --map-users <inner>:<outer>:<count>\n"
" add the specified UID map to an ID-mapped mount\n"), out);
fputs(_(" --map-users /proc/<pid>/ns/user\n"
" specify the user namespace for an ID-mapped mount\n"), out);
fputs(_(" -m, --mkdir[=<mode>] alias to '-o X-mount.mkdir[=<mode>]'\n"), out);
fputs(_(" -n, --no-mtab don't write to /etc/mtab\n"), out);
fputs(_(" --options-mode <mode>\n"
Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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' },
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a61bbb3

Please sign in to comment.