microsoft / microsoft/sqlmanagementobjects

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

Abierto
#234 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
C#
Estrellas
143
Forks
28
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

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.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comience en src/Microsoft/SqlServer/Management/Smo/LoginBase.cs, leyendo las sobrecargas de ChangePassword y ExecuteLoginPasswordOptions, y luego compare su comportamiento con SetMustChangePassword. Después de una ejecución correcta sin registro, invalide las propiedades almacenadas en caché afectadas para que las lecturas sobre el mismo objeto reflejen el resultado de ALTER LOGIN para MustChangePassword, IsLocked, IsPasswordExpired, IsMustChange, PasswordLastSetTime y PasswordHash.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
csharp, sql
Área
backend-api-design, databases
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Activo
Claridad
Bien especificado
Aptitud para principiantes
72/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.