podman/libpod/container_internal_linux_test.go
Matthew Heon f57c39fc7c Make an entry in /etc/group when we modify /etc/passwd
To ensure that the user running in the container ahs a valid
entry in /etc/passwd so lookup functions for the current user
will not error, Podman previously began adding entries to the
passwd file. We did not, however, add entries to the group file,
and this created problems - our passwd entries included the group
the user is in, but said group might not exist. The solution is
to mirror our logic for /etc/passwd modifications to also edit
/etc/group in the container.

Unfortunately, this is not a catch-all solution. Our logic here
is only advanced enough to *add* to the group file - so if the
group already exists but we add a user not a part of it, we will
not modify that existing entry, and things remain inconsistent.
We can look into adding this later if we absolutely need to, but
it would involve adding significant complexity to this already
massively complicated function.

While we're here, address an edge case where Podman could add a
user or group whose UID overlapped with an existing user or
group.

Also, let's make users able to log into users we added. Instead
of generating user entries with an 'x' in the password field,
indicating they have an entry in /etc/shadow, generate a '*'
indicating the user has no password but can be logged into by
other means e.g. ssh key, su.

Fixes #7503
Fixes #7389
Fixes #7499

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
2020-09-10 13:02:31 -04:00

71 lines
1.4 KiB
Go

// +build linux
package libpod
import (
"io/ioutil"
"os"
"testing"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
)
func TestGenerateUserPasswdEntry(t *testing.T) {
dir, err := ioutil.TempDir("", "libpod_test_")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
c := Container{
config: &ContainerConfig{
Spec: &spec.Spec{},
ContainerSecurityConfig: ContainerSecurityConfig{
User: "123:456",
},
},
state: &ContainerState{
Mountpoint: "/does/not/exist/tmp/",
},
}
user, _, _, err := c.generateUserPasswdEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, user, "123:*:123:456:container user:/:/bin/sh\n")
c.config.User = "567"
user, _, _, err = c.generateUserPasswdEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, user, "567:*:567:0:container user:/:/bin/sh\n")
}
func TestGenerateUserGroupEntry(t *testing.T) {
c := Container{
config: &ContainerConfig{
Spec: &spec.Spec{},
ContainerSecurityConfig: ContainerSecurityConfig{
User: "123:456",
},
},
state: &ContainerState{
Mountpoint: "/does/not/exist/tmp/",
},
}
group, _, err := c.generateUserGroupEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, group, "456:x:456:123\n")
c.config.User = "567"
group, _, err = c.generateUserGroupEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, group, "567:x:567:567\n")
}