From 2582f1418e5cb696d0705d65db9fb5905a55173e 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 | 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)