From e015c9e3f74153ef069bfbb013e715766e793bf9 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 19 Aug 2022 15:15:47 +0200 Subject: podman: add uid and gid options to keep-id add two new options to the keep-id user namespace option: - uid: allow to override the UID used inside the container. - gid: allow to override the GID used inside the container. For example, the following command will map the rootless user (that has UID=0 inside the rootless user namespace) to the UID=11 inside the container user namespace: $ podman run --userns=keep-id:uid=11 --rm -ti fedora cat /proc/self/uid_map 0 1 11 11 0 1 12 12 65525 Closes: https://github.com/containers/podman/issues/15294 Signed-off-by: Giuseppe Scrivano --- pkg/namespaces/namespaces.go | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'pkg/namespaces') diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index 8eacb8da7..6dd576ea5 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -21,6 +21,14 @@ const ( slirpType = "slirp4netns" ) +// KeepIDUserNsOptions defines how to keepIDmatically create a user namespace. +type KeepIDUserNsOptions struct { + // UID is the target uid in the user namespace. + UID *uint32 + // GID is the target uid in the user namespace. + GID *uint32 +} + // CgroupMode represents cgroup mode in the container. type CgroupMode string @@ -93,7 +101,8 @@ func (n UsernsMode) IsHost() bool { // IsKeepID indicates whether container uses a mapping where the (uid, gid) on the host is kept inside of the namespace. func (n UsernsMode) IsKeepID() bool { - return n == "keep-id" + parts := strings.Split(string(n), ":") + return parts[0] == "keep-id" } // IsNoMap indicates whether container uses a mapping where the (uid, gid) on the host is not present in the namespace. @@ -154,6 +163,44 @@ func (n UsernsMode) GetAutoOptions() (*types.AutoUserNsOptions, error) { return &options, nil } +// GetKeepIDOptions returns a KeepIDUserNsOptions with the settings to keepIDmatically set up +// a user namespace. +func (n UsernsMode) GetKeepIDOptions() (*KeepIDUserNsOptions, error) { + parts := strings.SplitN(string(n), ":", 2) + if parts[0] != "keep-id" { + return nil, fmt.Errorf("wrong user namespace mode") + } + options := KeepIDUserNsOptions{} + if len(parts) == 1 { + return &options, nil + } + for _, o := range strings.Split(parts[1], ",") { + v := strings.SplitN(o, "=", 2) + if len(v) != 2 { + return nil, fmt.Errorf("invalid option specified: %q", o) + } + switch v[0] { + case "uid": + s, err := strconv.ParseUint(v[1], 10, 32) + if err != nil { + return nil, err + } + v := uint32(s) + options.UID = &v + case "gid": + s, err := strconv.ParseUint(v[1], 10, 32) + if err != nil { + return nil, err + } + v := uint32(s) + options.GID = &v + default: + return nil, fmt.Errorf("unknown option specified: %q", v[0]) + } + } + return &options, nil +} + // IsPrivate indicates whether the container uses the a private userns. func (n UsernsMode) IsPrivate() bool { return !(n.IsHost() || n.IsContainer()) -- cgit v1.2.3-54-g00ecf