]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
unshare: Support names for map-user/group options
authorMatthew Harm Bekkema <id@mbekkema.name>
Wed, 15 Apr 2020 13:05:16 +0000 (23:05 +1000)
committerMatthew Harm Bekkema <id@mbekkema.name>
Wed, 15 Apr 2020 13:05:16 +0000 (23:05 +1000)
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 <id@mbekkema.name>
sys-utils/unshare.1
sys-utils/unshare.c

index 92a3f1c714e033c7f0fd5ae780e595973b52c67e..2e8d76c727c45481d02b0675dac7d40c34df527e 100644 (file)
@@ -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.
index 06c95c06ae2808cc53660c635f93da31b9d2f207..0d352e453707f7bc94c822090fdcfc6f7b0b3277 100644 (file)
@@ -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[=<file>]       unshare time namespace\n"), out);
        fputs(USAGE_SEPARATOR, out);
        fputs(_(" -f, --fork                fork before launching <program>\n"), out);
-       fputs(_(" --map-user=<uid>          map current user to uid (implies --user)\n"), out);
-       fputs(_(" --map-group=<gid>         map current group to gid (implies --user)\n"), out);
+       fputs(_(" --map-user=<uid>|<name>   map current user to uid (implies --user)\n"), out);
+       fputs(_(" --map-group=<gid>|<name>  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;