summaryrefslogtreecommitdiff
path: root/libpod/container_internal_linux.go
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2020-06-30 15:44:14 -0400
committerValentin Rothberg <rothberg@redhat.com>2020-08-11 14:58:29 +0200
commit3dfd8630a51a37734ad8c51162c4d004b8ffffb2 (patch)
tree6ebf1d923f718c6717add408a11c714070ccc995 /libpod/container_internal_linux.go
parent92d01d76c63d0a286365f610151524fb24b74e16 (diff)
downloadpodman-3dfd8630a51a37734ad8c51162c4d004b8ffffb2.tar.gz
podman-3dfd8630a51a37734ad8c51162c4d004b8ffffb2.tar.bz2
podman-3dfd8630a51a37734ad8c51162c4d004b8ffffb2.zip
Add username to /etc/passwd inside of container if --userns keep-id
If I enter a continer with --userns keep-id, my UID will be present inside of the container, but most likely my user will not be defined. This patch will take information about the user and stick it into the container. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'libpod/container_internal_linux.go')
-rw-r--r--libpod/container_internal_linux.go58
1 files changed, 50 insertions, 8 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index cfcf9b823..f86903fd1 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -9,6 +9,7 @@ import (
"io/ioutil"
"net"
"os"
+ "os/user"
"path"
"path/filepath"
"strconv"
@@ -33,7 +34,7 @@ import (
"github.com/containers/libpod/v2/pkg/util"
"github.com/containers/storage/pkg/archive"
securejoin "github.com/cyphar/filepath-securejoin"
- "github.com/opencontainers/runc/libcontainer/user"
+ User "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -1420,9 +1421,23 @@ func (c *Container) getHosts() string {
return hosts
}
-// generatePasswd generates a container specific passwd file,
-// iff g.config.User is a number
-func (c *Container) generatePasswd() (string, error) {
+// generateCurrentUserPasswdEntry generates an /etc/passwd entry for the user
+// running the container engine
+func (c *Container) generateCurrentUserPasswdEntry() (string, error) {
+ uid := rootless.GetRootlessUID()
+ if uid == 0 {
+ return "", nil
+ }
+ u, err := user.LookupId(strconv.Itoa(rootless.GetRootlessUID()))
+ if err != nil {
+ return "", errors.Wrapf(err, "failed to get current user")
+ }
+ return fmt.Sprintf("%s:x:%s:%s:%s:%s:/bin/sh\n", u.Username, u.Uid, u.Gid, u.Username, c.WorkingDir()), nil
+}
+
+// generateUserPasswdEntry generates an /etc/passwd entry for the container user
+// to run in the container.
+func (c *Container) generateUserPasswdEntry() (string, error) {
var (
groupspec string
gid int
@@ -1440,14 +1455,16 @@ func (c *Container) generatePasswd() (string, error) {
if err != nil {
return "", nil
}
+
// Lookup the user to see if it exists in the container image
_, err = lookup.GetUser(c.state.Mountpoint, userspec)
- if err != nil && err != user.ErrNoPasswdEntries {
+ if err != nil && err != User.ErrNoPasswdEntries {
return "", err
}
if err == nil {
return "", nil
}
+
if groupspec != "" {
ugid, err := strconv.ParseUint(groupspec, 10, 32)
if err == nil {
@@ -1460,14 +1477,39 @@ func (c *Container) generatePasswd() (string, error) {
gid = group.Gid
}
}
+ return fmt.Sprintf("%d:x:%d:%d:container user:%s:/bin/sh\n", uid, uid, gid, c.WorkingDir()), nil
+}
+
+// generatePasswd generates a container specific passwd file,
+// iff g.config.User is a number
+func (c *Container) generatePasswd() (string, error) {
+ if !c.config.AddCurrentUserPasswdEntry && c.config.User == "" {
+ return "", nil
+ }
+ pwd := ""
+ if c.config.User != "" {
+ entry, err := c.generateUserPasswdEntry()
+ if err != nil {
+ return "", err
+ }
+ pwd += entry
+ }
+ if c.config.AddCurrentUserPasswdEntry {
+ entry, err := c.generateCurrentUserPasswdEntry()
+ if err != nil {
+ return "", err
+ }
+ pwd += entry
+ }
+ if pwd == "" {
+ return "", nil
+ }
originPasswdFile := filepath.Join(c.state.Mountpoint, "/etc/passwd")
orig, err := ioutil.ReadFile(originPasswdFile)
if err != nil && !os.IsNotExist(err) {
return "", errors.Wrapf(err, "unable to read passwd file %s", originPasswdFile)
}
-
- pwd := fmt.Sprintf("%s%d:x:%d:%d:container user:%s:/bin/sh\n", orig, uid, uid, gid, c.WorkingDir())
- passwdFile, err := c.writeStringToRundir("passwd", pwd)
+ passwdFile, err := c.writeStringToRundir("passwd", string(orig)+pwd)
if err != nil {
return "", errors.Wrapf(err, "failed to create temporary passwd file")
}