summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container_internal_linux.go27
-rw-r--r--libpod/oci_internal_linux.go22
-rw-r--r--pkg/lookup/lookup.go30
-rw-r--r--test/e2e/run_test.go6
4 files changed, 67 insertions, 18 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 355b9bea4..230b5b888 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -181,6 +181,30 @@ func (c *Container) cleanupNetwork() error {
return nil
}
+func (c *Container) getUserOverrides() *lookup.Overrides {
+ var hasPasswdFile, hasGroupFile bool
+ overrides := lookup.Overrides{}
+ for _, m := range c.config.Spec.Mounts {
+ if m.Destination == "/etc/passwd" {
+ overrides.ContainerEtcPasswdPath = m.Source
+ hasPasswdFile = true
+ }
+ if m.Destination == "/etc/group" {
+ overrides.ContainerEtcGroupPath = m.Source
+ hasGroupFile = true
+ }
+ if m.Destination == "/etc" {
+ if !hasPasswdFile {
+ overrides.ContainerEtcPasswdPath = filepath.Join(m.Source, "passwd")
+ }
+ if !hasGroupFile {
+ overrides.ContainerEtcGroupPath = filepath.Join(m.Source, "group")
+ }
+ }
+ }
+ return &overrides
+}
+
// Generate spec for a container
// Accepts a map of the container's dependencies
func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
@@ -188,7 +212,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
span.SetTag("type", "container")
defer span.Finish()
- execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, nil)
+ overrides := c.getUserOverrides()
+ execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides)
if err != nil {
return nil, err
}
diff --git a/libpod/oci_internal_linux.go b/libpod/oci_internal_linux.go
index 4df1e4010..a90af32ed 100644
--- a/libpod/oci_internal_linux.go
+++ b/libpod/oci_internal_linux.go
@@ -200,13 +200,16 @@ func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, se
pspec.Cwd = cwd
}
+
+ overrides := c.getUserOverrides()
+ execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, user, overrides)
+ if err != nil {
+ return nil, err
+ }
+
// If user was set, look it up in the container to get a UID to use on
// the host
if user != "" {
- execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, user, nil)
- if err != nil {
- return nil, err
- }
sgids := make([]uint32, 0, len(execUser.Sgids))
for _, sgid := range execUser.Sgids {
sgids = append(sgids, uint32(sgid))
@@ -220,6 +223,17 @@ func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, se
pspec.User = processUser
}
+ hasHomeSet := false
+ for _, s := range pspec.Env {
+ if strings.HasPrefix(s, "HOME=") {
+ hasHomeSet = true
+ break
+ }
+ }
+ if !hasHomeSet {
+ pspec.Env = append(pspec.Env, fmt.Sprintf("HOME=%s", execUser.Home))
+ }
+
processJSON, err := json.Marshal(pspec)
if err != nil {
return nil, err
diff --git a/pkg/lookup/lookup.go b/pkg/lookup/lookup.go
index 70b97144f..a249dd753 100644
--- a/pkg/lookup/lookup.go
+++ b/pkg/lookup/lookup.go
@@ -29,17 +29,30 @@ func GetUserGroupInfo(containerMount, containerUser string, override *Overrides)
defaultExecUser *user.ExecUser
err error
)
- passwdPath := etcpasswd
- groupPath := etcgroup
if override != nil {
// Check for an override /etc/passwd path
if override.ContainerEtcPasswdPath != "" {
- passwdPath = override.ContainerEtcPasswdPath
+ passwdDest = override.ContainerEtcPasswdPath
}
// Check for an override for /etc/group path
if override.ContainerEtcGroupPath != "" {
- groupPath = override.ContainerEtcGroupPath
+ groupDest = override.ContainerEtcGroupPath
+ }
+ }
+
+ if passwdDest == "" {
+ // Make sure the /etc/passwd destination is not a symlink to something naughty
+ if passwdDest, err = securejoin.SecureJoin(containerMount, etcpasswd); err != nil {
+ logrus.Debug(err)
+ return nil, err
+ }
+ }
+ if groupDest == "" {
+ // Make sure the /etc/group destination is not a symlink to something naughty
+ if groupDest, err = securejoin.SecureJoin(containerMount, etcgroup); err != nil {
+ logrus.Debug(err)
+ return nil, err
}
}
@@ -56,15 +69,6 @@ func GetUserGroupInfo(containerMount, containerUser string, override *Overrides)
}
- // Make sure the /etc/group and /etc/passwd destinations are not a symlink to something naughty
- if passwdDest, err = securejoin.SecureJoin(containerMount, passwdPath); err != nil {
- logrus.Debug(err)
- return nil, err
- }
- if groupDest, err = securejoin.SecureJoin(containerMount, groupPath); err != nil {
- logrus.Debug(err)
- return nil, err
- }
return user.GetExecUserPath(containerUser, defaultExecUser, passwdDest, groupDest)
}
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 55920467c..1e6f1d97d 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -200,6 +200,12 @@ var _ = Describe("Podman run", func() {
match, _ := session.GrepString("/root")
Expect(match).Should(BeTrue())
+ session = podmanTest.Podman([]string{"run", "--rm", "--user", "2", ALPINE, "printenv", "HOME"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ match, _ = session.GrepString("/sbin")
+ Expect(match).Should(BeTrue())
+
session = podmanTest.Podman([]string{"run", "--rm", "--env", "HOME=/foo", ALPINE, "printenv", "HOME"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))