Incident Utilisateurs AD : Expiration massive des mots de passe utilisateurs dans Active Directory après coupure de courant
1. Contexte
- Environnement : Active Directory avec plusieurs Domain Controllers (DC), un principal et un secondaire (AD CS).
- Proxmox lié à l'AD pour authentification LDAP.
- Les utilisateurs du DSI (wassim.dsi, simon.dsi, david.dsi) étaient configurés avec des mots de passe actifs et ne devaient pas expirer.
- Une coupure de courant a provoqué l'arrêt brutal du DC Secondaire.
2. Symptômes observés
- Les utilisateurs ont tous un mot de passe expirés donc la connexion aux sessions est impossible.
- Logs Proxmox indiquant :
authentication failure; user=<utilisateur>@ad msg=80090308: LdapErr: DSID-0C090549, comment: AcceptSecurityContext error, data 532
data 532signifie : Password expired.
3. Analyse technique
-
Chaque compte utilisateur AD possède les attributs :
-
pwdLastSet(date du dernier changement de mot de passe) userAccountControl(flags, dont PASSWORD_EXPIRED)- La GPO du domaine indique :
-
Après la coupure de courant :
-
Les DC ont redémarré brutalement, certains journaux NTDS non flushés.
- L'heure système sur les DC a pu être désynchronisée.
- Les DC ont réévalué
pwdLastSetpour tous les comptes. -
Comme l'heure ou les USN étaient incohérents, AD a marqué tous les mots de passe comme expirés.
-
Même sans expiration forcée dans la GPO pour certains comptes, AD peut appliquer
PASSWORD_EXPIREDsi : -
pwdLastSet + MaxPasswordAge> heure système (calcul erroné) - ou si le DC considère que le compte n'a jamais eu son mot de passe défini correctement (corruption partielle NTDS)
4. Conséquences
- Tous les utilisateurs apparaissent comme ayant un mot de passe expiré.
- Proxmox renvoie des erreurs LDAP 532.
5. Solution appliquée
- Réinitialiser les mots de passe expirés pour tous les utilisateurs du domaine (sauf DSI) :
$ExcludeUsers = @("wassim.dsi","simon.dsi","david.dsi")
$TempPassword = "TempP@ssword123!"
Get-ADUser -Filter * -SearchBase "DC=cha,DC=chartres,DC=sportludique,DC=fr" | Where-Object {
$ExcludeUsers -notcontains $_.SamAccountName
} | ForEach-Object {
Set-ADAccountPassword -Identity $_.DistinguishedName -Reset -NewPassword (ConvertTo-SecureString $TempPassword -AsPlainText -Force)
Set-ADUser -Identity $_.DistinguishedName -ChangePasswordAtLogon $true
}
- Vérifier les utilisateurs avec mots de passe expirés :
-
Pour éviter que le problème se reproduise :
-
Désactiver l'expiration globale si souhaité :
MaximumPasswordAge = 0dans la GPODefault Domain Policy. - Ou mettre des comptes spécifiques comme "Password never expires".
PS C:\WINDOWS\system32> Get-ADUser -Filter * | Where-Object {$Exclude -notcontains $_.SamAccountName} | Set-ADUser -PasswordNeverExpires $true
6. Recommandations
- Surveiller la synchronisation horaire des DC (
w32tm /query /status). - Vérifier régulièrement l'état des journaux NTDS après redémarrage brutal.
- Maintenir des scripts pour réinitialiser les mots de passe expirés rapidement après un incident.
- Pour les comptes critiques (Proxmox, service admin), utiliser "Password never expires" pour éviter les blocages inattendus.