libpod: --user works with --hostuser entries

create the /etc/passwd and /etc/group files before any user/group
lookup so that the entries added dynamically are found by --user.

As a side effect, do not automatically create the group with same
value as the uid when not specified, since it is expected to run with
gid=0.

Closes: https://github.com/containers/podman/issues/25805

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2025-04-07 11:20:04 +02:00
parent 40d7ab19f5
commit 85024a9ba7
4 changed files with 23 additions and 23 deletions

View File

@ -195,15 +195,15 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
cleanupFunc()
}
}()
if err := c.makeBindMounts(); err != nil {
return nil, nil, err
}
overrides := c.getUserOverrides()
execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, overrides)
if err != nil {
if slices.Contains(c.config.HostUsers, c.config.User) {
execUser, err = lookupHostUser(c.config.User)
}
if err != nil {
return nil, nil, err
}
return nil, nil, err
}
// NewFromSpec() is deprecated according to its comment
@ -236,10 +236,6 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
g.SetProcessApparmorProfile(updatedProfile)
}
if err := c.makeBindMounts(); err != nil {
return nil, nil, err
}
if err := c.mountNotifySocket(g); err != nil {
return nil, nil, err
}
@ -2434,7 +2430,7 @@ func (c *Container) generateGroupEntry() (string, error) {
// Things we *can't* handle: adding the user we added in
// generatePasswdEntry to any *existing* groups.
addedGID := 0
addedGID := -1
if c.config.AddCurrentUserPasswdEntry {
entry, gid, err := c.generateCurrentUserGroupEntry()
if err != nil {
@ -2503,7 +2499,7 @@ func (c *Container) generateUserGroupEntry(addedGID int) (string, error) {
}
splitUser := strings.SplitN(c.config.User, ":", 2)
group := splitUser[0]
group := "0"
if len(splitUser) > 1 {
group = splitUser[1]
}
@ -2513,7 +2509,7 @@ func (c *Container) generateUserGroupEntry(addedGID int) (string, error) {
return "", nil //nolint: nilerr
}
if addedGID != 0 && addedGID == int(gid) {
if addedGID != -1 && addedGID == int(gid) {
return "", nil
}

View File

@ -47,16 +47,16 @@ func TestGenerateUserGroupEntry(t *testing.T) {
Mountpoint: "/does/not/exist/tmp/",
},
}
group, err := c.generateUserGroupEntry(0)
group, err := c.generateUserGroupEntry(-1)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, group, "456789:x:456789:123456\n")
c.config.User = "567890"
group, err = c.generateUserGroupEntry(0)
group, err = c.generateUserGroupEntry(-1)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, group, "567890:x:567890:567890\n")
assert.Equal(t, group, "0:x:0:567890\n")
}

View File

@ -90,13 +90,6 @@ USER 1000`, ALPINE)
Expect(session.OutputToString()).To(ContainSubstring("/etc/group"))
})
It("podman run numeric user not specified in container modifies group", func() {
session := podmanTest.Podman([]string{"run", "--read-only", "-u", "20001", BB, "mount"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("/etc/group"))
})
It("podman run numeric group from image and no group file", func() {
dockerfile := fmt.Sprintf(`FROM %s
RUN rm -f /etc/passwd /etc/shadow /etc/group

View File

@ -906,6 +906,17 @@ EOF
fi
user=$(id -u)
userspec=$(id -un):$(id -g)
run_podman run --hostuser=$user --user $userspec --rm $IMAGE sh -c 'echo $(id -un):$(id -g)'
is "$output" "$userspec"
run_podman run --hostuser=$user --user $userspec --group-entry="$(id -gn):x:$(id -g):" --rm $IMAGE sh -c 'echo $(id -un):$(id -gn)'
is "$output" "$(id -un):$(id -gn)"
run_podman 126 run --hostuser=$user --user "$(id -un):$(id -gn)" --rm $IMAGE sh -c 'echo $(id -un):$(id -gn)'
is "$output" "Error:.* no matching entries in group file"
run_podman run --hostuser=$user --rm $IMAGE grep $user /etc/passwd
run_podman run --hostuser=$user --user $user --rm $IMAGE grep $user /etc/passwd
user=bogus