microsoft / microsoft/sqlmanagementobjects

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

Aperta
#234 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
C#
Stelle
143
Fork
28
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

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.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Iniziare da src/Microsoft/SqlServer/Management/Smo/LoginBase.cs, leggendo gli overload di ChangePassword e ExecuteLoginPasswordOptions, quindi confrontarne il comportamento con SetMustChangePassword. Dopo un'esecuzione riuscita senza registrazione, invalidare le proprietà memorizzate nella cache interessate, in modo che le letture sullo stesso oggetto riflettano il risultato di ALTER LOGIN per MustChangePassword, IsLocked, IsPasswordExpired, IsMustChange, PasswordLastSetTime e PasswordHash.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
csharp, sql
Ambito
backend-api-design, databases
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
72/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.