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.
#include "all-io.h"
#include "signames.h"
#include "strutils.h"
+#include "pwdutils.h"
/* synchronize parent and child by pipe */
#define PIPE_SYNC_BYTE 0x06
}
}
+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;
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);
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;