From bae6853906c388051a49b9a43776eba97e4f0523 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 15 Jul 2020 15:25:12 -0400 Subject: Make changes to /etc/passwd on disk for non-read only Bind-mounting /etc/passwd into the container is problematic becuase of how system utilities like `useradd` work. They want to make a copy and then rename to try to prevent breakage; this is, unfortunately, impossible when the file they want to rename is a bind mount. The current behavior is fine for read-only containers, though, because we expect useradd to fail in those cases. Instead of bind-mounting, we can edit /etc/passwd in the container's rootfs. This is kind of gross, because the change will show up in `podman diff` and similar tools, and will be included in images made by `podman commit`. However, it's a lot better than breaking important system tools. Fixes #6953 Signed-off-by: Matthew Heon --- test/e2e/run_passwd_test.go | 8 ++++---- test/e2e/run_userns_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go index 3152f166b..5df8e1649 100644 --- a/test/e2e/run_passwd_test.go +++ b/test/e2e/run_passwd_test.go @@ -35,27 +35,27 @@ var _ = Describe("Podman run passwd", func() { }) It("podman run no user specified ", func() { - session := podmanTest.Podman([]string{"run", BB, "mount"}) + session := podmanTest.Podman([]string{"run", "--read-only", BB, "mount"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run user specified in container", func() { - session := podmanTest.Podman([]string{"run", "-u", "bin", BB, "mount"}) + session := podmanTest.Podman([]string{"run", "--read-only", "-u", "bin", BB, "mount"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run UID specified in container", func() { - session := podmanTest.Podman([]string{"run", "-u", "2:1", BB, "mount"}) + session := podmanTest.Podman([]string{"run", "--read-only", "-u", "2:1", BB, "mount"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains("passwd")).To(BeFalse()) }) It("podman run UID not specified in container", func() { - session := podmanTest.Podman([]string{"run", "-u", "20001:1", BB, "mount"}) + session := podmanTest.Podman([]string{"run", "--read-only", "-u", "20001:1", BB, "mount"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.LineInOutputContains("passwd")).To(BeTrue()) diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index 42f13537d..2ddb84a94 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -113,6 +113,31 @@ var _ = Describe("Podman UserNS support", func() { Expect(session.OutputToString()).To(Equal("0")) }) + It("podman run --userns=keep-id can add users", func() { + if os.Geteuid() == 0 { + Skip("Test only runs without root") + } + + userName := os.Getenv("USER") + if userName == "" { + Skip("Can't complete test if no username available") + } + + ctrName := "ctr-name" + session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "-d", "--stop-signal", "9", "--name", ctrName, fedoraMinimal, "sleep", "600"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + exec1 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "cat", "/etc/passwd"}) + exec1.WaitWithDefaultTimeout() + Expect(exec1.ExitCode()).To(Equal(0)) + Expect(exec1.OutputToString()).To(ContainSubstring(userName)) + + exec2 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "useradd", "testuser"}) + exec2.WaitWithDefaultTimeout() + Expect(exec2.ExitCode()).To(Equal(0)) + }) + It("podman --userns=auto", func() { u, err := user.Current() Expect(err).To(BeNil()) -- cgit v1.2.3-54-g00ecf