From 013611934d2e03c99282a4ce1c11d92bdf19b4ea Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Sun, 30 Aug 2020 16:26:07 +0200 Subject: [PATCH] Unbreak 'sudo' inside toolbox containers with Podman 2.0.5 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 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 https://github.com/containers/podman/pull/6829 [2] https://github.com/containers/podman/issues/7389 https://github.com/containers/toolbox/issues/523 --- README.md | 1 + src/cmd/initContainer.go | 68 +++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 611ae0709..72996dbb6 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ Tools: * `touch(1)` * `unlink(1)` * `useradd(8)` +* `usermod(8)` Paths: * `/etc/host.conf`: optional, if present not a bind mount diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go index fa57c2006..45b8af221 100644 --- a/src/cmd/initContainer.go +++ b/src/cmd/initContainer.go @@ -233,12 +233,22 @@ func initContainer(cmd *cobra.Command, args []string) error { } } - if _, err := user.Lookup(initContainerFlags.user); err != nil { + if targetUser, err := user.Lookup(initContainerFlags.user); err != nil { if err := configureUsers(initContainerFlags.uid, initContainerFlags.user, initContainerFlags.home, initContainerFlags.shell, - initContainerFlags.homeLink); err != nil { + initContainerFlags.homeLink, + false); err != nil { + return err + } + } else if targetUser.HomeDir != initContainerFlags.home { + if err := configureUsers(initContainerFlags.uid, + initContainerFlags.user, + initContainerFlags.home, + initContainerFlags.shell, + initContainerFlags.homeLink, + true); err != nil { return err } } @@ -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 @@ -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)