Skip to content

Commit

Permalink
Unbreak 'sudo' inside toolbox containers with Podman 2.0.5
Browse files Browse the repository at this point in the history
Since Podman 2.0.5, containers that were created with
'podman create --userns=keep-id ...' automatically get the user added
to /etc/passwd [1]. However, this user isn't as fully configured as it
needs to be. The home directory is specified as '/' and the shell is
/bin/sh.

Note that Podman doesn't add the user's login group to /etc/group [2].
This leads to the following error message when entering the container:
  /usr/bin/id: cannot find name for group ID 1000

It's expected that this will be fixed in Podman itself.

Therefore, the entry point needs to call usermod(8) to update the user,
instead of using useradd(8) to create it.

[1] Podman commit 6c6670f12a3e6b91
    containers/podman#6829

[2] containers/podman#7389

containers#523
  • Loading branch information
debarshiray committed Aug 30, 2020
1 parent 59f4a79 commit 9ea6fe5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ Tools:
* `touch(1)`
* `unlink(1)`
* `useradd(8)`
* `usermod(8)`

Paths:
* `/etc/host.conf`: optional, if present not a bind mount
Expand Down
66 changes: 49 additions & 17 deletions src/cmd/initContainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,17 @@ func initContainer(cmd *cobra.Command, args []string) error {
initContainerFlags.user,
initContainerFlags.home,
initContainerFlags.shell,
initContainerFlags.homeLink); err != nil {
initContainerFlags.homeLink,
false); err != nil {
return err
}
} else {
if err := configureUsers(initContainerFlags.uid,
initContainerFlags.user,
initContainerFlags.home,
initContainerFlags.shell,
initContainerFlags.homeLink,
true); err != nil {
return err
}
}
Expand Down Expand Up @@ -337,7 +347,7 @@ func initContainerHelp(cmd *cobra.Command, args []string) {

func configureUsers(targetUserUid int,
targetUser, targetUserHome, targetUserShell string,
homeLink bool) error {
homeLink, targetUserExists bool) error {
if homeLink {
if err := redirectPath("/home", "/var/home", true); err != nil {
return err
Expand All @@ -349,24 +359,46 @@ func configureUsers(targetUserUid int,
return fmt.Errorf("failed to get group for sudo: %w", err)
}

logrus.Debugf("Adding user %s with UID %d:", targetUser, targetUserUid)
if targetUserExists {
logrus.Debugf("Modifying user %s with UID %d:", targetUser, targetUserUid)

useraddArgs := []string{
"--groups", sudoGroup,
"--home-dir", targetUserHome,
"--no-create-home",
"--shell", targetUserShell,
"--uid", fmt.Sprint(targetUserUid),
targetUser,
}
usermodArgs := []string{
"--append",
"--groups", sudoGroup,
"--home", targetUserHome,
"--shell", targetUserShell,
"--uid", fmt.Sprint(targetUserUid),
targetUser,
}

logrus.Debug("useradd")
for _, arg := range useraddArgs {
logrus.Debugf("%s", arg)
}
logrus.Debug("usermod")
for _, arg := range usermodArgs {
logrus.Debugf("%s", arg)
}

if err := shell.Run("usermod", nil, nil, nil, usermodArgs...); err != nil {
return fmt.Errorf("failed to modify user %s with UID %d", targetUser, targetUserUid)
}
} else {
logrus.Debugf("Adding user %s with UID %d:", targetUser, targetUserUid)

useraddArgs := []string{
"--groups", sudoGroup,
"--home-dir", targetUserHome,
"--no-create-home",
"--shell", targetUserShell,
"--uid", fmt.Sprint(targetUserUid),
targetUser,
}

logrus.Debug("useradd")
for _, arg := range useraddArgs {
logrus.Debugf("%s", arg)
}

if err := shell.Run("useradd", nil, nil, nil, useraddArgs...); err != nil {
return fmt.Errorf("failed to add user %s with UID %d", targetUser, targetUserUid)
if err := shell.Run("useradd", nil, nil, nil, useraddArgs...); err != nil {
return fmt.Errorf("failed to add user %s with UID %d", targetUser, targetUserUid)
}
}

logrus.Debugf("Removing password for user %s", targetUser)
Expand Down

0 comments on commit 9ea6fe5

Please sign in to comment.