From: Matthew Harm Bekkema Date: Wed, 15 Apr 2020 13:05:16 +0000 (+1000) Subject: unshare: Support names for map-user/group options X-Git-Tag: v2.36-rc1~140^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=987550cbe857062456a120536bb16a67845b255b;p=thirdparty%2Futil-linux.git unshare: Support names for map-user/group options The --map-user and --map-group options can now be specified by either uid/gid or user/group name. Signed-off-by: Matthew Harm Bekkema --- diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1 index 92a3f1c714..2e8d76c727 100644 --- a/sys-utils/unshare.1 +++ b/sys-utils/unshare.1 @@ -169,12 +169,12 @@ implies creating a new mount namespace since the /proc mount would otherwise mess up existing programs on the system. The new proc filesystem is explicitly mounted as private (with MS_PRIVATE|MS_REC). .TP -.BR \-\-map\-user=\fIuid +.BR \-\-map\-user=\fIuid|name Run the program only after the current effective user ID has been mapped to \fIuid\fP. If this option is specified multiple times, the last occurrence takes precedence. This option implies \fB\-\-user\fR. .TP -.BR \-\-map\-group=\fIgid +.BR \-\-map\-group=\fIgid|name Run the program only after the current effective group ID has been mapped to \fIgid\fP. If this option is specified multiple times, the last occurrence takes precedence. This option implies \fB\-\-setgroups=deny\fR and \fB\-\-user\fR. diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index 06c95c06ae..0d352e4537 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -45,6 +45,7 @@ #include "all-io.h" #include "signames.h" #include "strutils.h" +#include "pwdutils.h" /* synchronize parent and child by pipe */ #define PIPE_SYNC_BYTE 0x06 @@ -260,6 +261,42 @@ static void bind_ns_files_from_child(pid_t *child, int fds[2]) } } +static uid_t get_user(const char *s, const char *err) +{ + struct passwd *pw; + char *buf = NULL; + uid_t ret; + + pw = xgetpwnam(s, &buf); + if (pw) { + ret = pw->pw_uid; + free(pw); + free(buf); + } else { + ret = strtoul_or_err(s, err); + } + + return ret; +} + +static gid_t get_group(const char *s, const char *err) +{ + struct group *gr; + char *buf = NULL; + gid_t ret; + + gr = xgetgrnam(s, &buf); + if (gr) { + ret = gr->gr_gid; + free(gr); + free(buf); + } else { + ret = strtoul_or_err(s, err); + } + + return ret; +} + static void __attribute__((__noreturn__)) usage(void) { FILE *out = stdout; @@ -282,8 +319,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -T, --time[=] unshare time namespace\n"), out); fputs(USAGE_SEPARATOR, out); fputs(_(" -f, --fork fork before launching \n"), out); - fputs(_(" --map-user= map current user to uid (implies --user)\n"), out); - fputs(_(" --map-group= map current group to gid (implies --user)\n"), out); + fputs(_(" --map-user=| map current user to uid (implies --user)\n"), out); + fputs(_(" --map-group=| map current group to gid (implies --user)\n"), out); fputs(_(" -r, --map-root-user map current user to root (implies --user)\n"), out); fputs(_(" -c, --map-current-user map current user to itself (implies --user)\n"), out); fputs(USAGE_SEPARATOR, out); @@ -432,11 +469,11 @@ int main(int argc, char *argv[]) break; case OPT_MAPUSER: unshare_flags |= CLONE_NEWUSER; - mapuser = strtoul_or_err(optarg, _("failed to parse uid")); + mapuser = get_user(optarg, _("failed to parse uid")); break; case OPT_MAPGROUP: unshare_flags |= CLONE_NEWUSER; - mapgroup = strtoul_or_err(optarg, _("failed to parse gid")); + mapgroup = get_group(optarg, _("failed to parse gid")); break; case 'r': unshare_flags |= CLONE_NEWUSER;