microsoft / microsoft/sqlmanagementobjects

Login.ChangePassword() leaves MustChangePassword and IsLocked stale - the property bag is never updated or invalidated

Ouverte
#234 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
C#
Étoiles
143
Forks
28
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

After a successful Login.ChangePassword(newPassword, unlock: true, mustChange: true), reading login.MustChangePassword on the same object still returns the old value (typically False) until Refresh() is called. The same applies to the other properties the ALTER changes: IsLocked after an unlock, IsPasswordExpired, PasswordLastSetTime, IsMustChange.

This is the same object-cache pattern as #40 (Database.SetOwner() not updating .Owner): a method executes DDL immediately but neither updates nor invalidates the cached properties it just changed on the server.

Repro

$login = $server.Logins["testlogin"]   # SQL login, MustChangePassword currently False
$login.ChangePassword("N3wP@ssw0rd!", $true, $true)
$login.MustChangePassword              # False - stale; the server says otherwise:
# SELECT LOGINPROPERTY('testlogin', 'IsMustChange')  --> 1
$login.Refresh()
$login.MustChangePassword              # True

dbatools carries the workaround with the comment "We need to refresh login after ChangePassword. Otherwise, MustChangePassword will appear as False" (New-DbaLogin.ps1#L610-L611), and its Set-DbaLogin re-reads the login after unlocking for the same reason.

Mechanism

All ChangePassword overloads (LoginBase.cs#L142-L282) end in ExecuteLoginPasswordOptions (LoginBase.cs#L533-L555), which builds ALTER LOGIN ... WITH PASSWORD=... [UNLOCK] [MUST_CHANGE] and runs ExecutionManager.ExecuteNonQuery — and returns. Nothing touches the property bag.

A helper that does update the bag exists — SetMustChangePassword (LoginBase.cs#L334-L347) — but it early-returns unless the object is in design mode, and is only called from Create().

Suggested fix

After a successful non-recording execution, invalidate the affected cached properties so the next read fetches current values from the server — the approach proposed for #40 in PR #231. For ChangePassword that covers at least MustChangePassword, IsLocked, IsPasswordExpired, IsMustChange, PasswordLastSetTime, PasswordHash.

Happy to submit a PR along those lines if that helps.

This was created by Claude and reviewed by Andreas Jordan.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans src/Microsoft/SqlServer/Management/Smo/LoginBase.cs, en lisant les surcharges de ChangePassword et ExecuteLoginPasswordOptions, puis comparez leur comportement à celui de SetMustChangePassword. Après une exécution réussie sans enregistrement, invalidez les propriétés mises en cache concernées afin que les lectures sur le même objet reflètent le résultat de ALTER LOGIN pour MustChangePassword, IsLocked, IsPasswordExpired, IsMustChange, PasswordLastSetTime et PasswordHash.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
csharp, sql
Domaine
backend-api-design, databases
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
Active
Clarté
Clairement spécifiée
Accessibilité débutants
72/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.