diff --git a/toolkit/tools/internal/userutils/userutils.go b/toolkit/tools/internal/userutils/userutils.go index 612fcf9369..9a22a8951e 100644 --- a/toolkit/tools/internal/userutils/userutils.go +++ b/toolkit/tools/internal/userutils/userutils.go @@ -93,8 +93,14 @@ func UpdateUserPassword(installRoot, username, hashedPassword string) error { shadowFilePath := filepath.Join(installRoot, ShadowFile) if hashedPassword == "" { - // In the /etc/shadow file, `!` means there is no password and password login is disabled. - hashedPassword = "!" + // In the /etc/shadow file, the values `*` and `!` both mean the user's password login is disabled but the user + // may login using other means (e.g. ssh, auto-login, etc.). This interpretation is also used by PAM. When sshd + // has `UsePAM` set to `yes`, then sshd defers to PAM the decision on whether or not the user is disabled. + // However, when `UsePAM` is set to `no`, then sshd must make this interpretation for itself. And the Mariner + // build of sshd is configured to interpret the `!` in the shadow file to mean the user is fully disabled, even + // for ssh login. But it interprets `*` to mean that only password login is disabled but sshd public/private key + // login is fine. + hashedPassword = "*" } // Find the line that starts with "::..." diff --git a/toolkit/tools/internal/userutils/userutils_test.go b/toolkit/tools/internal/userutils/userutils_test.go index 617aa0ed4b..555d3fe08c 100644 --- a/toolkit/tools/internal/userutils/userutils_test.go +++ b/toolkit/tools/internal/userutils/userutils_test.go @@ -80,20 +80,20 @@ func TestHashPasswordNotEmpty(t *testing.T) { } func TestUpdateUserPasswordEmptyToEmpty(t *testing.T) { - testUpdateUserPassword(t, "root:!:19634:7:99999:7:::", "root:!:19634:7:99999:7:::", "root", "") + testUpdateUserPassword(t, "root:*:19634:7:99999:7:::", "root:*:19634:7:99999:7:::", "root", "") } func TestUpdateUserPasswordSomethingToEmpty(t *testing.T) { testUpdateUserPassword(t, "root:$6$E0M9VkDvOLvO$nr9FjmIiSSP5C5V3Lhuqv4VzWmscABoiQ0mF.ZTbwKEN4nS60nsiU17qA/RGMbXHtJfci/DeLT1Zu2nhNFbwQ.:19634:7:99999:7:::", - "root:!:19634:7:99999:7:::", + "root:*:19634:7:99999:7:::", "root", "") } func TestUpdateUserPassword(t *testing.T) { testUpdateUserPassword(t, - "root:!:19634:7:99999:7:::", + "root:*:19634:7:99999:7:::", "root:$6$E0M9VkDvOLvO$nr9FjmIiSSP5C5V3Lhuqv4VzWmscABoiQ0mF.ZTbwKEN4nS60nsiU17qA/RGMbXHtJfci/DeLT1Zu2nhNFbwQ.:19634:7:99999:7:::", "root", "$6$E0M9VkDvOLvO$nr9FjmIiSSP5C5V3Lhuqv4VzWmscABoiQ0mF.ZTbwKEN4nS60nsiU17qA/RGMbXHtJfci/DeLT1Zu2nhNFbwQ.")