From 9ea6fe5852ea8f5225114d825e8e6813e2a3cfea 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 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 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 | 66 +++++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 17 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..169153310 100644 --- a/src/cmd/initContainer.go +++ b/src/cmd/initContainer.go @@ -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 } } @@ -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)