diff --git a/pkg/daemon/update.go b/pkg/daemon/update.go index 96243c5ed0..12ff701e8d 100644 --- a/pkg/daemon/update.go +++ b/pkg/daemon/update.go @@ -1241,29 +1241,29 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi defer func() { if retErr != nil { - if err := dn.updateSSHKeys(newIgnConfig.Passwd.Users, oldIgnConfig.Passwd.Users); err != nil { + if err := dn.updateSSHKeys(oldIgnConfig.Passwd.Users, newIgnConfig.Passwd.Users); err != nil { errs := kubeErrs.NewAggregate([]error{err, retErr}) retErr = fmt.Errorf("error rolling back SSH keys updates: %w", errs) return } } }() - } - // Set password hash - if err := dn.SetPasswordHash(newIgnConfig.Passwd.Users, oldIgnConfig.Passwd.Users); err != nil { - return err - } + // Set password hash + if err := dn.SetPasswordHash(newIgnConfig.Passwd.Users, oldIgnConfig.Passwd.Users); err != nil { + return err + } - defer func() { - if retErr != nil { - if err := dn.SetPasswordHash(newIgnConfig.Passwd.Users, oldIgnConfig.Passwd.Users); err != nil { - errs := kubeErrs.NewAggregate([]error{err, retErr}) - retErr = fmt.Errorf("error rolling back password hash updates: %w", errs) - return + defer func() { + if retErr != nil { + if err := dn.SetPasswordHash(oldIgnConfig.Passwd.Users, newIgnConfig.Passwd.Users); err != nil { + errs := kubeErrs.NewAggregate([]error{err, retErr}) + retErr = fmt.Errorf("error rolling back password hash updates: %w", errs) + return + } } - } - }() + }() + } if dn.os.IsCoreOSVariant() { coreOSDaemon := CoreOSDaemon{dn} @@ -2439,7 +2439,21 @@ func (dn *Daemon) atomicallyWriteSSHKey(authKeyPath, keys string) error { return nil } -// Set a given PasswdUser's Password Hash +func getUserPasswordHash(user string) (string, error) { + shadowOut, err := exec.Command("getent", "shadow", user).CombinedOutput() + if err != nil { + return "", fmt.Errorf("Failed to check password hash for %s: %w", user, err) + } + shadowSlice := strings.SplitN(strings.TrimSpace(string(shadowOut)), ":", 3) + if len(shadowSlice) >= 2 { + return shadowSlice[1], nil + } + return "", nil + +} + +// SetPasswordHash updates the password for each user in newUsers, skipping +// users whose password already matches the desired configuration. func (dn *Daemon) SetPasswordHash(newUsers, oldUsers []ign3types.PasswdUser) error { // confirm that user exits klog.Info("Checking if absent users need to be disconfigured") @@ -2464,6 +2478,15 @@ func (dn *Daemon) SetPasswordHash(newUsers, oldUsers []ign3types.PasswdUser) err pwhash = *u.PasswordHash } + // Check if hash update is needed. Skip if not. + currentHash, err := getUserPasswordHash(u.Name) + if err != nil { + return err + } + if currentHash == pwhash { + continue + } + if out, err := exec.Command("usermod", "-p", pwhash, u.Name).CombinedOutput(); err != nil { return fmt.Errorf("Failed to reset password for %s: %s:%w", u.Name, out, err) }