1057 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			1057 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 07d5c061eacec0a3b145947a9b95a11b705ea5d3 Mon Sep 17 00:00:00 2001
 | |
| From: Debarshi Ray <rishi@fedoraproject.org>
 | |
| Date: Sat, 12 Aug 2023 14:26:22 +0200
 | |
| Subject: [PATCH 1/5] test/system: Test that group and user IDs work
 | |
| 
 | |
| These tests assume that the group and user information on the host
 | |
| operating system can be provided by different plugins for the GNU Name
 | |
| Service Switch (or NSS) functionality of the GNU C Library.  eg., on
 | |
| enterprise FreeIPA set-ups.  However, it's expected that everything
 | |
| inside the Toolbx container will be provided by /etc/group, /etc/passwd,
 | |
| /etc/shadow, etc..
 | |
| 
 | |
| While /etc/group and /etc/passwd can be read by any user, /etc/shadow
 | |
| can only be read by root.  However, it's awkward to use sudo(8) in the
 | |
| test cases involving /etc/shadow, because they ensure that root and
 | |
| $USER don't need passwords to authenticate inside the container, and
 | |
| sudo(8) itself depends on that.  If sudo(8) is used, the test suite can
 | |
| behave unexpectedly if Toolbx didn't set up the container correctly.
 | |
| eg., it can get blocked waiting for a password.
 | |
| 
 | |
| Hence, 'podman unshare' is used instead to enter the container's initial
 | |
| user namespace, where $USER from the host appears as root.  This is
 | |
| sufficient because the test cases only need to read /etc/shadow inside
 | |
| the Toolbx container.
 | |
| 
 | |
| https://github.com/containers/toolbox/pull/1355
 | |
| ---
 | |
|  test/system/206-user.bats | 520 ++++++++++++++++++++++++++++++++++++++
 | |
|  1 file changed, 520 insertions(+)
 | |
|  create mode 100644 test/system/206-user.bats
 | |
| 
 | |
| diff --git a/test/system/206-user.bats b/test/system/206-user.bats
 | |
| new file mode 100644
 | |
| index 000000000000..fdb2a33da88c
 | |
| --- /dev/null
 | |
| +++ b/test/system/206-user.bats
 | |
| @@ -0,0 +1,520 @@
 | |
| +# shellcheck shell=bats
 | |
| +#
 | |
| +# Copyright © 2023 Red Hat, Inc.
 | |
| +#
 | |
| +# Licensed under the Apache License, Version 2.0 (the "License");
 | |
| +# you may not use this file except in compliance with the License.
 | |
| +# You may obtain a copy of the License at
 | |
| +#
 | |
| +#     http://www.apache.org/licenses/LICENSE-2.0
 | |
| +#
 | |
| +# Unless required by applicable law or agreed to in writing, software
 | |
| +# distributed under the License is distributed on an "AS IS" BASIS,
 | |
| +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| +# See the License for the specific language governing permissions and
 | |
| +# limitations under the License.
 | |
| +#
 | |
| +
 | |
| +load 'libs/bats-support/load'
 | |
| +load 'libs/bats-assert/load'
 | |
| +load 'libs/helpers'
 | |
| +
 | |
| +setup() {
 | |
| +  bats_require_minimum_version 1.7.0
 | |
| +  _setup_environment
 | |
| +  cleanup_containers
 | |
| +}
 | |
| +
 | |
| +teardown() {
 | |
| +  cleanup_containers
 | |
| +}
 | |
| +
 | |
| +@test "user: separate namespace" {
 | |
| +  local ns_host
 | |
| +  ns_host=$(readlink /proc/$$/ns/user)
 | |
| +
 | |
| +  create_default_container
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run sh -c 'readlink /proc/$$/ns/user'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --index 0 --regexp '^user:\[[[:digit:]]+\]$'
 | |
| +  refute_line --index 0 "$ns_host"
 | |
| +
 | |
| +  if check_bats_version 1.10.0; then
 | |
| +    assert [ ${#lines[@]} -eq 1 ]
 | |
| +  else
 | |
| +    assert [ ${#lines[@]} -eq 2 ]
 | |
| +  fi
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside the default container" {
 | |
| +  local default_container
 | |
| +  default_container="$(get_system_id)-toolbox-$(get_system_version)"
 | |
| +
 | |
| +  create_default_container
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount "$default_container")"
 | |
| +
 | |
| +  "$TOOLBOX" run true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount "$default_container"
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside Arch Linux" {
 | |
| +  create_distro_container arch latest arch-toolbox-latest
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount arch-toolbox-latest)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro arch true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount arch-toolbox-latest
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside Fedora 34" {
 | |
| +  create_distro_container fedora 34 fedora-toolbox-34
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount fedora-toolbox-34)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro fedora --release 34 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount fedora-toolbox-34
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside RHEL 8.7" {
 | |
| +  create_distro_container rhel 8.7 rhel-toolbox-8.7
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount rhel-toolbox-8.7)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro rhel --release 8.7 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount rhel-toolbox-8.7
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside Ubuntu 16.04" {
 | |
| +  create_distro_container ubuntu 16.04 ubuntu-toolbox-16.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-16.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 16.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-16.04
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside Ubuntu 18.04" {
 | |
| +  create_distro_container ubuntu 18.04 ubuntu-toolbox-18.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-18.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 18.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-18.04
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: root in shadow(5) inside Ubuntu 20.04" {
 | |
| +  create_distro_container ubuntu 20.04 ubuntu-toolbox-20.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-20.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 20.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-20.04
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp '^root::.+$'
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside the default container" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_default_container
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside Arch Linux" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container arch latest arch-toolbox-latest
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro arch sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside Fedora 34" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container fedora 34 fedora-toolbox-34
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro fedora --release 34 sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside RHEL 8.7" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container rhel 8.7 rhel-toolbox-8.7
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro rhel --release 8.7 sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside Ubuntu 16.04" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container ubuntu 16.04 ubuntu-toolbox-16.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 16.04 sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside Ubuntu 18.04" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container ubuntu 18.04 ubuntu-toolbox-18.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 18.04 sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in passwd(5) inside Ubuntu 20.04" {
 | |
| +  local user_gecos
 | |
| +  user_gecos="$(getent passwd "$USER" | cut --delimiter : --fields 5)"
 | |
| +
 | |
| +  local user_id_real
 | |
| +  user_id_real="$(id --real --user)"
 | |
| +
 | |
| +  create_distro_container ubuntu 20.04 ubuntu-toolbox-20.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 20.04 sh -c 'cat /etc/passwd'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^$USER::$user_id_real:$user_id_real:$user_gecos:$HOME:$SHELL$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside the default container" {
 | |
| +  local default_container
 | |
| +  default_container="$(get_system_id)-toolbox-$(get_system_version)"
 | |
| +
 | |
| +  create_default_container
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount "$default_container")"
 | |
| +
 | |
| +  "$TOOLBOX" run true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount "$default_container"
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside Arch Linux" {
 | |
| +  create_distro_container arch latest arch-toolbox-latest
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount arch-toolbox-latest)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro arch true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount arch-toolbox-latest
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside Fedora 34" {
 | |
| +  create_distro_container fedora 34 fedora-toolbox-34
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount fedora-toolbox-34)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro fedora --release 34 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount fedora-toolbox-34
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside RHEL 8.7" {
 | |
| +  create_distro_container rhel 8.7 rhel-toolbox-8.7
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount rhel-toolbox-8.7)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro rhel --release 8.7 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount rhel-toolbox-8.7
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside Ubuntu 16.04" {
 | |
| +  create_distro_container ubuntu 16.04 ubuntu-toolbox-16.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-16.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 16.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-16.04
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside Ubuntu 18.04" {
 | |
| +  create_distro_container ubuntu 18.04 ubuntu-toolbox-18.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-18.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 18.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-18.04
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in shadow(5) inside Ubuntu 20.04" {
 | |
| +  create_distro_container ubuntu 20.04 ubuntu-toolbox-20.04
 | |
| +  container_root_file_system="$("$PODMAN" unshare "$PODMAN" mount ubuntu-toolbox-20.04)"
 | |
| +
 | |
| +  "$TOOLBOX" run --distro ubuntu --release 20.04 true
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$PODMAN" unshare cat "$container_root_file_system/etc/shadow"
 | |
| +  "$PODMAN" unshare "$PODMAN" unmount ubuntu-toolbox-20.04
 | |
| +
 | |
| +  assert_success
 | |
| +  refute_line --regexp "^$USER:.*$"
 | |
| +  assert [ ${#lines[@]} -gt 0 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside the default container" {
 | |
| +  create_default_container
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^(sudo|wheel):x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside Arch Linux" {
 | |
| +  create_distro_container arch latest arch-toolbox-latest
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro arch sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^wheel:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside Fedora 34" {
 | |
| +  create_distro_container fedora 34 fedora-toolbox-34
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro fedora --release 34 sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^wheel:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside RHEL 8.7" {
 | |
| +  create_distro_container rhel 8.7 rhel-toolbox-8.7
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro rhel --release 8.7 sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^wheel:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside Ubuntu 16.04" {
 | |
| +  create_distro_container ubuntu 16.04 ubuntu-toolbox-16.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 16.04 sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^sudo:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside Ubuntu 18.04" {
 | |
| +  create_distro_container ubuntu 18.04 ubuntu-toolbox-18.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 18.04 sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^sudo:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| +
 | |
| +@test "user: $USER in group(5) inside Ubuntu 20.04" {
 | |
| +  create_distro_container ubuntu 20.04 ubuntu-toolbox-20.04
 | |
| +
 | |
| +  run --keep-empty-lines --separate-stderr "$TOOLBOX" run --distro ubuntu --release 20.04 sh -c 'cat /etc/group'
 | |
| +
 | |
| +  assert_success
 | |
| +  assert_line --regexp "^sudo:x:[[:digit:]]+:$USER$"
 | |
| +  assert [ ${#lines[@]} -gt 1 ]
 | |
| +
 | |
| +  # shellcheck disable=SC2154
 | |
| +  assert [ ${#stderr_lines[@]} -eq 0 ]
 | |
| +}
 | |
| -- 
 | |
| 2.41.0
 | |
| 
 | |
| 
 | |
| From 22ba72f3152650d538437bf298ebde4a63e2adc9 Mon Sep 17 00:00:00 2001
 | |
| From: Debarshi Ray <rishi@fedoraproject.org>
 | |
| Date: Wed, 4 Nov 2020 00:55:31 +0100
 | |
| Subject: [PATCH 2/5] Deprecate the --monitor-host option of 'init-container'
 | |
| 
 | |
| The --monitor-host option was added to the 'init-container' command in
 | |
| commit 8b84b5e4604921fa to accommodate Podman versions older than 1.2.0
 | |
| that didn't have the '--dns none' and '--no-hosts' options for
 | |
| 'podman create'.  These options are necessary to keep the Toolbx
 | |
| container's /etc/resolv.conf and /etc/hosts files synchronized with
 | |
| those of the host.
 | |
| 
 | |
| Note that Podman 1.2.0 was already available a few months before
 | |
| commit 8b84b5e4604921fa introduced the --monitor-host option.  The
 | |
| chances of someone using an older Podman back then was already on the
 | |
| decline, and it's very unlikely that a container created with such a
 | |
| Podman has survived till this date.
 | |
| 
 | |
| Commit b6b484fa792b442a raised the minimum required Podman version to
 | |
| 1.4.0, and made the '--dns none' and '--no-hosts' options a hard
 | |
| requirement.  The minimum required Podman version was again raised
 | |
| recently in commit 8e80dd5db1e6f40b to 1.6.4.  Therefore, these days,
 | |
| there's no need to separately use the --monitor-host option of
 | |
| 'init-container' for newly created containers to indicate that the
 | |
| Podman version wasn't older than 1.2.0.
 | |
| 
 | |
| Given all this, it's time to stop using the --monitor-host option of
 | |
| 'init-container', and assume that it's always set.  The option is still
 | |
| accepted to retain compatibility with existing Toolbx containers.
 | |
| 
 | |
| For containers that were created with the --monitor-host option, a
 | |
| deprecation notice will be shown as:
 | |
|   $ podman start --attach CONTAINER
 | |
|   Flag --monitor-host has been deprecated, it does nothing
 | |
|   ...
 | |
| 
 | |
| https://github.com/containers/toolbox/pull/617
 | |
| ---
 | |
|  doc/toolbox-init-container.1.md | 32 +++---------
 | |
|  src/cmd/create.go               |  1 -
 | |
|  src/cmd/initContainer.go        | 86 ++++++++++++++++-----------------
 | |
|  3 files changed, 49 insertions(+), 70 deletions(-)
 | |
| 
 | |
| diff --git a/doc/toolbox-init-container.1.md b/doc/toolbox-init-container.1.md
 | |
| index 45c9a77939f2..51a7b1ee643d 100644
 | |
| --- a/doc/toolbox-init-container.1.md
 | |
| +++ b/doc/toolbox-init-container.1.md
 | |
| @@ -9,7 +9,6 @@ toolbox\-init\-container - Initialize a running container
 | |
|                         *--home-link*
 | |
|                         *--media-link*
 | |
|                         *--mnt-link*
 | |
| -                       *--monitor-host*
 | |
|                         *--shell SHELL*
 | |
|                         *--uid UID*
 | |
|                         *--user USER*
 | |
| @@ -76,31 +75,12 @@ Make `/mnt` a symbolic link to `/var/mnt`.
 | |
|  
 | |
|  **--monitor-host**
 | |
|  
 | |
| -Ensures that certain configuration files inside the toolbox container are kept
 | |
| -synchronized with their counterparts on the host, and bind mounts some paths
 | |
| -from the host's file system into the container.
 | |
| -
 | |
| -The synchronized files are:
 | |
| -
 | |
| -- `/etc/host.conf`
 | |
| -- `/etc/hosts`
 | |
| -- `/etc/localtime`
 | |
| -- `/etc/resolv.conf`
 | |
| -- `/etc/timezone`
 | |
| -
 | |
| -The bind mounted paths are:
 | |
| -
 | |
| -- `/etc/machine-id`
 | |
| -- `/run/libvirt`
 | |
| -- `/run/systemd/journal`
 | |
| -- `/run/systemd/resolve`
 | |
| -- `/run/udev/data`
 | |
| -- `/tmp`
 | |
| -- `/var/lib/flatpak`
 | |
| -- `/var/lib/libvirt`
 | |
| -- `/var/lib/systemd/coredump`
 | |
| -- `/var/log/journal`
 | |
| -- `/var/mnt`
 | |
| +Deprecated, does nothing.
 | |
| +
 | |
| +Crucial configuration files inside the toolbox container are always kept
 | |
| +synchronized with their counterparts on the host, and various subsets of the
 | |
| +host's file system hierarchy are always bind mounted to their corresponding
 | |
| +locations inside the toolbox container.
 | |
|  
 | |
|  **--shell** SHELL
 | |
|  
 | |
| diff --git a/src/cmd/create.go b/src/cmd/create.go
 | |
| index 2a103f01ed2d..6cec99258847 100644
 | |
| --- a/src/cmd/create.go
 | |
| +++ b/src/cmd/create.go
 | |
| @@ -393,7 +393,6 @@ func createContainer(container, image, release, authFile string, showCommandToEn
 | |
|  		"--shell", userShell,
 | |
|  		"--uid", currentUser.Uid,
 | |
|  		"--user", currentUser.Username,
 | |
| -		"--monitor-host",
 | |
|  	}
 | |
|  
 | |
|  	entryPoint = append(entryPoint, slashHomeLink...)
 | |
| diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go
 | |
| index c4cd1b02d298..cb132bffc817 100644
 | |
| --- a/src/cmd/initContainer.go
 | |
| +++ b/src/cmd/initContainer.go
 | |
| @@ -107,8 +107,12 @@ func init() {
 | |
|  
 | |
|  	flags.BoolVar(&initContainerFlags.monitorHost,
 | |
|  		"monitor-host",
 | |
| -		false,
 | |
| -		"Ensure that certain configuration files inside the toolbox container are in sync with the host")
 | |
| +		true,
 | |
| +		"Deprecated, does nothing")
 | |
| +	if err := flags.MarkDeprecated("monitor-host", "it does nothing"); err != nil {
 | |
| +		panicMsg := fmt.Sprintf("cannot mark --monitor-host as deprecated: %s", err)
 | |
| +		panic(panicMsg)
 | |
| +	}
 | |
|  
 | |
|  	flags.StringVar(&initContainerFlags.shell,
 | |
|  		"shell",
 | |
| @@ -163,59 +167,55 @@ func initContainer(cmd *cobra.Command, args []string) error {
 | |
|  
 | |
|  	defer toolboxEnvFile.Close()
 | |
|  
 | |
| -	if initContainerFlags.monitorHost {
 | |
| -		logrus.Debug("Monitoring host")
 | |
| -
 | |
| -		if utils.PathExists("/run/host/etc") {
 | |
| -			logrus.Debug("Path /run/host/etc exists")
 | |
| -
 | |
| -			if _, err := os.Readlink("/etc/host.conf"); err != nil {
 | |
| -				if err := redirectPath("/etc/host.conf",
 | |
| -					"/run/host/etc/host.conf",
 | |
| -					false); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| -			}
 | |
| +	if utils.PathExists("/run/host/etc") {
 | |
| +		logrus.Debug("Path /run/host/etc exists")
 | |
|  
 | |
| -			if _, err := os.Readlink("/etc/hosts"); err != nil {
 | |
| -				if err := redirectPath("/etc/hosts",
 | |
| -					"/run/host/etc/hosts",
 | |
| -					false); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| +		if _, err := os.Readlink("/etc/host.conf"); err != nil {
 | |
| +			if err := redirectPath("/etc/host.conf",
 | |
| +				"/run/host/etc/host.conf",
 | |
| +				false); err != nil {
 | |
| +				return err
 | |
|  			}
 | |
| +		}
 | |
|  
 | |
| -			if localtimeTarget, err := os.Readlink("/etc/localtime"); err != nil ||
 | |
| -				localtimeTarget != "/run/host/etc/localtime" {
 | |
| -				if err := redirectPath("/etc/localtime",
 | |
| -					"/run/host/etc/localtime",
 | |
| -					false); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| +		if _, err := os.Readlink("/etc/hosts"); err != nil {
 | |
| +			if err := redirectPath("/etc/hosts",
 | |
| +				"/run/host/etc/hosts",
 | |
| +				false); err != nil {
 | |
| +				return err
 | |
|  			}
 | |
| +		}
 | |
|  
 | |
| -			if err := updateTimeZoneFromLocalTime(); err != nil {
 | |
| +		if localtimeTarget, err := os.Readlink("/etc/localtime"); err != nil ||
 | |
| +			localtimeTarget != "/run/host/etc/localtime" {
 | |
| +			if err := redirectPath("/etc/localtime",
 | |
| +				"/run/host/etc/localtime",
 | |
| +				false); err != nil {
 | |
|  				return err
 | |
|  			}
 | |
| +		}
 | |
| +
 | |
| +		if err := updateTimeZoneFromLocalTime(); err != nil {
 | |
| +			return err
 | |
| +		}
 | |
|  
 | |
| -			if _, err := os.Readlink("/etc/resolv.conf"); err != nil {
 | |
| -				if err := redirectPath("/etc/resolv.conf",
 | |
| -					"/run/host/etc/resolv.conf",
 | |
| -					false); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| +		if _, err := os.Readlink("/etc/resolv.conf"); err != nil {
 | |
| +			if err := redirectPath("/etc/resolv.conf",
 | |
| +				"/run/host/etc/resolv.conf",
 | |
| +				false); err != nil {
 | |
| +				return err
 | |
|  			}
 | |
| +		}
 | |
|  
 | |
| -			for _, mount := range initContainerMounts {
 | |
| -				if err := mountBind(mount.containerPath, mount.source, mount.flags); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| +		for _, mount := range initContainerMounts {
 | |
| +			if err := mountBind(mount.containerPath, mount.source, mount.flags); err != nil {
 | |
| +				return err
 | |
|  			}
 | |
| +		}
 | |
|  
 | |
| -			if utils.PathExists("/sys/fs/selinux") {
 | |
| -				if err := mountBind("/sys/fs/selinux", "/usr/share/empty", ""); err != nil {
 | |
| -					return err
 | |
| -				}
 | |
| +		if utils.PathExists("/sys/fs/selinux") {
 | |
| +			if err := mountBind("/sys/fs/selinux", "/usr/share/empty", ""); err != nil {
 | |
| +				return err
 | |
|  			}
 | |
|  		}
 | |
|  	}
 | |
| -- 
 | |
| 2.41.0
 | |
| 
 | |
| 
 | |
| From 66a791ff10234023b858b7a28dd98985b054eca1 Mon Sep 17 00:00:00 2001
 | |
| From: Debarshi Ray <rishi@fedoraproject.org>
 | |
| Date: Tue, 7 Mar 2023 16:13:04 +0100
 | |
| Subject: [PATCH 3/5] cmd/initContainer: Bind mount locations regardless of
 | |
|  /run/host/etc
 | |
| 
 | |
| Bind mounting the locations at runtime doesn't really have anything to
 | |
| do with whether /run/host/etc is present inside the Toolbx container.
 | |
| 
 | |
| The only possible exception could have been /etc/machine-id, but it
 | |
| isn't, because the bind mount is only performed if the source at
 | |
| /run/host/etc/machine-id is present.
 | |
| 
 | |
| This is a historical mistake that has persisted for a long time, since,
 | |
| in practice, /run/host/etc will almost always exist inside the Toolbx
 | |
| container.  It's time to finally correct it.
 | |
| 
 | |
| Fallout from 9436bbece01d7aa4dc91b4013ed9f80d0b8d34f4
 | |
| 
 | |
| https://github.com/containers/toolbox/pull/1255
 | |
| ---
 | |
|  src/cmd/initContainer.go | 24 ++++++++++++------------
 | |
|  1 file changed, 12 insertions(+), 12 deletions(-)
 | |
| 
 | |
| diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go
 | |
| index cb132bffc817..153e5ccb824e 100644
 | |
| --- a/src/cmd/initContainer.go
 | |
| +++ b/src/cmd/initContainer.go
 | |
| @@ -206,18 +206,6 @@ func initContainer(cmd *cobra.Command, args []string) error {
 | |
|  				return err
 | |
|  			}
 | |
|  		}
 | |
| -
 | |
| -		for _, mount := range initContainerMounts {
 | |
| -			if err := mountBind(mount.containerPath, mount.source, mount.flags); err != nil {
 | |
| -				return err
 | |
| -			}
 | |
| -		}
 | |
| -
 | |
| -		if utils.PathExists("/sys/fs/selinux") {
 | |
| -			if err := mountBind("/sys/fs/selinux", "/usr/share/empty", ""); err != nil {
 | |
| -				return err
 | |
| -			}
 | |
| -		}
 | |
|  	}
 | |
|  
 | |
|  	if initContainerFlags.mediaLink {
 | |
| @@ -236,6 +224,18 @@ func initContainer(cmd *cobra.Command, args []string) error {
 | |
|  		}
 | |
|  	}
 | |
|  
 | |
| +	for _, mount := range initContainerMounts {
 | |
| +		if err := mountBind(mount.containerPath, mount.source, mount.flags); err != nil {
 | |
| +			return err
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	if utils.PathExists("/sys/fs/selinux") {
 | |
| +		if err := mountBind("/sys/fs/selinux", "/usr/share/empty", ""); err != nil {
 | |
| +			return err
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
|  	if _, err := user.Lookup(initContainerFlags.user); err != nil {
 | |
|  		if err := configureUsers(initContainerFlags.uid,
 | |
|  			initContainerFlags.user,
 | |
| -- 
 | |
| 2.41.0
 | |
| 
 | |
| 
 | |
| From d416f1b4abd0782526c011b078442856c733e718 Mon Sep 17 00:00:00 2001
 | |
| From: Debarshi Ray <rishi@fedoraproject.org>
 | |
| Date: Tue, 15 Aug 2023 20:57:46 +0200
 | |
| Subject: [PATCH 4/5] cmd/initContainer: Simplify code by removing a function
 | |
|  parameter
 | |
| 
 | |
| Until now, configureUsers() was pushing the burden of deciding whether
 | |
| to add a new user or modify an existing one on the callers, even though
 | |
| it can trivially decide itself.  Involving the caller loosens the
 | |
| encapsulation of the user configuration logic by spreading it across
 | |
| configureUsers() and it's caller, and adds an extra function parameter
 | |
| that needs to be carefully set and is vulnerable to programmer errors.
 | |
| 
 | |
| Fallout from 9ea6fe5852ea8f5225114d825e8e6813e2a3cfea
 | |
| 
 | |
| https://github.com/containers/toolbox/pull/1356
 | |
| ---
 | |
|  src/cmd/initContainer.go | 62 ++++++++++++++++------------------------
 | |
|  1 file changed, 24 insertions(+), 38 deletions(-)
 | |
| 
 | |
| diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go
 | |
| index 153e5ccb824e..02c389635378 100644
 | |
| --- a/src/cmd/initContainer.go
 | |
| +++ b/src/cmd/initContainer.go
 | |
| @@ -236,24 +236,12 @@ func initContainer(cmd *cobra.Command, args []string) error {
 | |
|  		}
 | |
|  	}
 | |
|  
 | |
| -	if _, err := user.Lookup(initContainerFlags.user); err != nil {
 | |
| -		if err := configureUsers(initContainerFlags.uid,
 | |
| -			initContainerFlags.user,
 | |
| -			initContainerFlags.home,
 | |
| -			initContainerFlags.shell,
 | |
| -			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
 | |
| -		}
 | |
| +	if err := configureUsers(initContainerFlags.uid,
 | |
| +		initContainerFlags.user,
 | |
| +		initContainerFlags.home,
 | |
| +		initContainerFlags.shell,
 | |
| +		initContainerFlags.homeLink); err != nil {
 | |
| +		return err
 | |
|  	}
 | |
|  
 | |
|  	if utils.PathExists("/etc/krb5.conf.d") && !utils.PathExists("/etc/krb5.conf.d/kcm_default_ccache") {
 | |
| @@ -386,9 +374,7 @@ func initContainerHelp(cmd *cobra.Command, args []string) {
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| -func configureUsers(targetUserUid int,
 | |
| -	targetUser, targetUserHome, targetUserShell string,
 | |
| -	homeLink, targetUserExists bool) error {
 | |
| +func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShell string, homeLink bool) error {
 | |
|  	if homeLink {
 | |
|  		if err := redirectPath("/home", "/var/home", true); err != nil {
 | |
|  			return err
 | |
| @@ -400,45 +386,45 @@ func configureUsers(targetUserUid int,
 | |
|  		return fmt.Errorf("failed to get group for sudo: %w", err)
 | |
|  	}
 | |
|  
 | |
| -	if targetUserExists {
 | |
| -		logrus.Debugf("Modifying user %s with UID %d:", targetUser, targetUserUid)
 | |
| +	if _, err := user.Lookup(targetUser); err != nil {
 | |
| +		logrus.Debugf("Adding user %s with UID %d:", targetUser, targetUserUid)
 | |
|  
 | |
| -		usermodArgs := []string{
 | |
| -			"--append",
 | |
| +		useraddArgs := []string{
 | |
|  			"--groups", sudoGroup,
 | |
| -			"--home", targetUserHome,
 | |
| +			"--home-dir", targetUserHome,
 | |
| +			"--no-create-home",
 | |
|  			"--shell", targetUserShell,
 | |
|  			"--uid", fmt.Sprint(targetUserUid),
 | |
|  			targetUser,
 | |
|  		}
 | |
|  
 | |
| -		logrus.Debug("usermod")
 | |
| -		for _, arg := range usermodArgs {
 | |
| +		logrus.Debug("useradd")
 | |
| +		for _, arg := range useraddArgs {
 | |
|  			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: %w", targetUser, targetUserUid, err)
 | |
| +		if err := shell.Run("useradd", nil, nil, nil, useraddArgs...); err != nil {
 | |
| +			return fmt.Errorf("failed to add user %s with UID %d: %w", targetUser, targetUserUid, err)
 | |
|  		}
 | |
|  	} else {
 | |
| -		logrus.Debugf("Adding user %s with UID %d:", targetUser, targetUserUid)
 | |
| +		logrus.Debugf("Modifying user %s with UID %d:", targetUser, targetUserUid)
 | |
|  
 | |
| -		useraddArgs := []string{
 | |
| +		usermodArgs := []string{
 | |
| +			"--append",
 | |
|  			"--groups", sudoGroup,
 | |
| -			"--home-dir", targetUserHome,
 | |
| -			"--no-create-home",
 | |
| +			"--home", targetUserHome,
 | |
|  			"--shell", targetUserShell,
 | |
|  			"--uid", fmt.Sprint(targetUserUid),
 | |
|  			targetUser,
 | |
|  		}
 | |
|  
 | |
| -		logrus.Debug("useradd")
 | |
| -		for _, arg := range useraddArgs {
 | |
| +		logrus.Debug("usermod")
 | |
| +		for _, arg := range usermodArgs {
 | |
|  			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: %w", targetUser, targetUserUid, err)
 | |
| +		if err := shell.Run("usermod", nil, nil, nil, usermodArgs...); err != nil {
 | |
| +			return fmt.Errorf("failed to modify user %s with UID %d: %w", targetUser, targetUserUid, err)
 | |
|  		}
 | |
|  	}
 | |
|  
 | |
| -- 
 | |
| 2.41.0
 | |
| 
 | |
| 
 | |
| From e673dc792438c64683237d26b21d005ffb008fd5 Mon Sep 17 00:00:00 2001
 | |
| From: Debarshi Ray <rishi@fedoraproject.org>
 | |
| Date: Tue, 22 Aug 2023 23:29:43 +0200
 | |
| Subject: [PATCH 5/5] cmd/initContainer: Simplify removing the user's password
 | |
| 
 | |
| It's one less invocation of an external command, which is good because
 | |
| spawning a new process is generally expensive.
 | |
| 
 | |
| One positive side-effect of this is that on some Active Directory
 | |
| set-ups, the entry point no longer fails with:
 | |
|   Error: failed to remove password for user login@company.com: failed
 | |
|       to invoke passwd(1)
 | |
| 
 | |
| ... because of:
 | |
|   # passwd --delete login@company.com
 | |
|   passwd: Libuser error at line: 210 - name contains invalid char `@'.
 | |
| 
 | |
| This is purely an accident, and isn't meant to be an intential change to
 | |
| support Active Directory.  Tools like useradd(8) and usermod(8) from
 | |
| Shadow aren't meant to work with Active Directory users, and, hence, it
 | |
| can still break in other ways.  For that, one option is to expose $USER
 | |
| from the host operating system to the Toolbx container through a Varlink
 | |
| interface that can be used by nss-systemd inside the container.
 | |
| 
 | |
| Based on an idea from Si.
 | |
| 
 | |
| https://github.com/containers/toolbox/issues/585
 | |
| ---
 | |
|  src/cmd/initContainer.go | 8 ++------
 | |
|  1 file changed, 2 insertions(+), 6 deletions(-)
 | |
| 
 | |
| diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go
 | |
| index 02c389635378..91b53cee7d0d 100644
 | |
| --- a/src/cmd/initContainer.go
 | |
| +++ b/src/cmd/initContainer.go
 | |
| @@ -393,6 +393,7 @@ func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShe
 | |
|  			"--groups", sudoGroup,
 | |
|  			"--home-dir", targetUserHome,
 | |
|  			"--no-create-home",
 | |
| +			"--password", "",
 | |
|  			"--shell", targetUserShell,
 | |
|  			"--uid", fmt.Sprint(targetUserUid),
 | |
|  			targetUser,
 | |
| @@ -413,6 +414,7 @@ func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShe
 | |
|  			"--append",
 | |
|  			"--groups", sudoGroup,
 | |
|  			"--home", targetUserHome,
 | |
| +			"--password", "",
 | |
|  			"--shell", targetUserShell,
 | |
|  			"--uid", fmt.Sprint(targetUserUid),
 | |
|  			targetUser,
 | |
| @@ -428,12 +430,6 @@ func configureUsers(targetUserUid int, targetUser, targetUserHome, targetUserShe
 | |
|  		}
 | |
|  	}
 | |
|  
 | |
| -	logrus.Debugf("Removing password for user %s", targetUser)
 | |
| -
 | |
| -	if err := shell.Run("passwd", nil, nil, nil, "--delete", targetUser); err != nil {
 | |
| -		return fmt.Errorf("failed to remove password for user %s: %w", targetUser, err)
 | |
| -	}
 | |
| -
 | |
|  	logrus.Debug("Removing password for user root")
 | |
|  
 | |
|  	if err := shell.Run("passwd", nil, nil, nil, "--delete", "root"); err != nil {
 | |
| -- 
 | |
| 2.41.0
 | |
| 
 |