What Is the AD User Cannot Change Password Setting?
When troubleshooting ad user cannot change password, inspect the user's discretionary access control list (DACL) before changing domain password policy. The account may be denied the Change Password extended right. That is an access-control restriction on self-service password changes, a different question from whether an administrator can reset the password.
Start with the exact account and the operation that failed. Record whether the person attempted to change their own password or asked a helpdesk operator to set a new one. A successful administrative reset does not demonstrate that self-change is permitted. Equally, a failed self-change does not by itself identify a Deny ACE as the cause: the DACL still needs to be read.
This guide examines a specific permission condition, rather than prescribing a new password age or length. Keep the broader policy review separate: Active Directory password security covers domain policies, expiration, account settings and credential storage. Changing those controls is not a substitute for establishing which ACEs apply to the account under investigation.
How It Works: Self-Change Permission and Administrative Reset
Microsoft identifies the User-Change-Password extended right by the display name Change Password and the GUID ab721a53-1e2f-11d0-9819-00aa0040529b. The relevant evidence is in the user object's security descriptor. Do not infer the state from an ordinary userAccountControl bit test: the collector condition reviewed here does not use that attribute.
The Microsoft LDAP modification procedure describes a standard configuration with object-specific ACEs for two trustees: Everyone and SELF. Denying the permission uses ADS_ACETYPE_ACCESS_DENIED_OBJECT; granting it uses the corresponding object-specific Allow type.
| Item to record | Value for this review | Why it matters |
|---|---|---|
| Object type | ab721a53-1e2f-11d0-9819-00aa0040529b | Identifies Change Password rather than a different object permission |
| Everyone trustee | S-1-1-0 | One trustee accepted by the collector predicate |
| SELF trustee | S-1-5-10 | The other trustee accepted by that predicate |
| ACE direction | Deny | An Allow entry does not satisfy the detector |
| Target | Exact user distinguished name | Lets the reviewer associate the evidence with the correct account |
Preserve the distinction between the documented configuration and the detector's condition. Microsoft's reading example recognizes the standard denied state when both trustee ACEs are Deny. The collector uses an OR condition: a matching Deny for either trustee is enough for its predicate. Record a single matching ACE as a single-trustee condition needing review; do not describe it as the complete two-ACE configuration from the Microsoft example.
Administrative password reset is a separate permission question. The ResetNightmare article discusses a Kerberos password-operation exploit and the distinction from delegated Reset Password rights. It provides context for separating operations, not evidence that this self-change restriction causes that exploit. Assess that separate exposure using the linked article's prerequisites and remediation guidance.
Detection: Read the DACL Independently
Step 1: Choose an Account and Preserve Context
Use the account's distinguished name, rather than a guessed display name. Note the account owner, enabled or disabled state, business purpose, domain controller queried and time of inspection. Include disabled accounts in the inventory if you are reconciling it with this collector predicate: Detect() has no Disabled filter. Account state can affect remediation priority, but it must not silently remove an entry from the permission review.
For a service identity, identify who owns password changes before classifying the restriction as unwanted. The question is whether the restriction is intentional and supported by an owned process. A service account label alone is not sufficient evidence for an exception.
Step 2: Retrieve and Filter the Access Rules
Microsoft's LDAP reading procedure reads ntSecurityDescriptor, obtains its DACL, then examines ObjectType, trustee and AceType. It also warns that trustee names are localized. Compare the well-known SIDs rather than hard-coding English account names.
The following read-only PowerShell adaptation uses ADSI through .NET on a Windows administration workstation. Replace the example domain controller and DN with verified values. It reads the directory security descriptor directly, outside the collector's ACL parser. These commands have not been executed against a domain for this article.
Add-Type -AssemblyName System.DirectoryServices
$dc = 'dc01.example.test'
$dn = 'CN=Example User,OU=Users,DC=example,DC=test'
$entry = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://$dc/$dn"
$entry.psbase.Options.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl
$descriptor = $entry.psbase.ObjectSecurity
$rules = @($descriptor.GetAccessRules(
$true, $true, [System.Security.Principal.SecurityIdentifier]
))
$changePassword = [guid]'ab721a53-1e2f-11d0-9819-00aa0040529b'
$matchingDenies = @($rules | Where-Object {
$_.ObjectType -eq $changePassword -and
$_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny -and
$_.IdentityReference.Value -in @('S-1-1-0', 'S-1-5-10')
})
$matchingDenies | Select-Object IdentityReference, ObjectType,
AccessControlType, ActiveDirectoryRights, IsInherited,
InheritanceType, InheritanceFlags, PropagationFlags | Format-List
$entry.psbase.Dispose()
The API references document ObjectSecurity, SecurityMasks and GetAccessRules. Both explicit and inherited rules are requested, and trustee identities are returned as SIDs. Keep the unfiltered rules available for a wider DACL review; the filter deliberately selects only this article's condition.
If binding or security descriptor retrieval fails, retain the error and mark the account as uninspected. An unreadable DACL is not an empty DACL. Do not replace an inspection failure with a successful-looking clean result.
Step 3: Interpret the Shape Without Overstating the Result
| Observed result | What to record | Next action |
|---|---|---|
| Both Everyone and SELF have matching object-specific Deny entries | Candidate two-trustee denied configuration | Confirm the control-access right and rule applicability, then review intent before a targeted change |
| Only one trustee has a matching Deny | Single-trustee condition accepted by the detector predicate | Inspect the complete DACL; do not discard it because the other entry is absent |
| No matching Deny is returned after a successful read | This narrow condition was not found | Continue troubleshooting; this is not a complete effective-access or password-policy verdict |
| DACL could not be retrieved | Evidence missing | Resolve the read failure before drawing a conclusion |
The output includes rights and inheritance information so the reviewer can inspect applicability. The filter does not test the access mask or inheritance applicability. Before classifying a pair as Microsoft's standard configuration, compare it with the modification procedure's ADS_RIGHT_DS_CONTROL_ACCESS mask and ACE flags. This is a focused ACE inventory, not a full Windows access-check implementation. Broad permissions, other trustees and nonstandard ACL arrangements need further assessment. Do not count two matching ACEs on one account as two affected accounts, or treat different reads of the same DN as different identities.
Remediation: Restore Self-Change Only for Approved Accounts
Step 1: Document Intent and the Before State
Assign an owner to each reviewed account and keep the DACL evidence before editing it. Record whether self-change should be available, who approved the decision and what operational dependency must be checked. If a restriction is retained, document its business reason, responsible team, password-management procedure and review point. Avoid granting or removing permissions across an OU merely because a single user reported a failure.
Review explicit and inherited rules before selecting the modification. If the restriction comes from an inherited rule, identify its origin and affected population. Escalate that scope decision to the responsible directory owner rather than treating a parent-level change as an individual-account fix.
Step 2: Make a Targeted Change
Microsoft documents CannotChangePassword in Set-ADAccountControl. Its example describes setting the user's security descriptor. The following adaptation clears the restriction for one approved account; first preview it with -WhatIf.
Set-ADAccountControl -Identity 'CN=Example User,OU=Users,DC=example,DC=test' -Server 'dc01.example.test' -CannotChangePassword $false -WhatIf
Once the target and change are approved, run the individual-account operation with confirmation:
Set-ADAccountControl -Identity 'CN=Example User,OU=Users,DC=example,DC=test' -Server 'dc01.example.test' -CannotChangePassword $false -Confirm
These are documented command adaptations, not commands executed during this review. A preview is not proof that the later write succeeded. Capture the actual operation's result and check for errors before moving to validation.
For a custom LDAP implementation, follow Microsoft's modification procedure: locate the Change Password entries for both trustees, change their object-specific AceType to Allow, add missing entries with the documented control-access mask and object-type flag, then write and commit the security descriptor. Follow its ACL ordering step when creating entries. Do not replace the entire DACL with a minimal pair of rules, or strip unrelated permissions to make the account appear compliant.
Step 3: Read Back and Verify the Intended Operation
After the write, retrieve the security descriptor afresh and repeat the Microsoft reading procedure. Compare both trustees, the GUID and the AceType with the before state. Keep any remaining inherited restrictions visible. A successful command response is an intermediate artifact; the post-change DACL is the permission evidence.
Then arrange a controlled self-change check by the account owner using the normal password-change workflow. Keep that outcome separate from the DACL result. If the operation still fails, investigate the actual error and other applicable controls instead of repeatedly altering the ACL or weakening domain policy. A helpdesk reset is not the verification step for restored self-change.
How EtcSec Detects This
The catalogue identifier for this condition is USER_CANNOT_CHANGE_PASSWORD. In the reviewed cannot-change.go implementation, Detect() examines supplied ACL entries and selects those with:
- an ObjectType equal to the Change Password GUID, compared without regard to case;
- an AceType containing
DENIED, after conversion to uppercase; - a trustee equal to Everyone
S-1-1-0or SELFS-1-5-10.
It lowercases the selected object DNs into a map, then matches them to user DNs. This deduplicates the matching ACEs by account DN before building the affected-user list. The finding's Count comes from that list, and there is no Disabled filter. An Allow ACE does not meet the predicate, and the implementation does not read a userAccountControl flag to establish this condition. It also does not test the access mask or inheritance applicability, so a predicate match alone is not a complete effective-access verdict.
The collection boundary is the current limitation. In public/internal/providers/ldap/acl_parser.go, parseACE() accepts only ACCESS_ALLOWED and ACCESS_ALLOWED_OBJECT ACE types. Other types return nil, including the Deny ACEs required here. A correct predicate over supplied entries does not establish working detection through the LDAP collection path. This article makes no claim of an end-to-end collector test or live domain validation.
What to Keep in the Review Record
For each account, preserve the exact DN, queried controller, timestamp, matching trustee SIDs, ObjectType, Deny or Allow direction, rights and inheritance context. Retain inspection errors rather than dropping failed reads. Associate the before and after records with the same identity, plus the change approval or exception owner.
The closure decision should state what was established: a restriction was retained with a documented reason, permission was changed and independently reread, or further investigation remains open. Record a functional self-change result only when that check was actually performed. Do not convert this source review, a command example, a reset operation or an empty collector count into evidence of successful self-service rotation.
Sources
- Microsoft Learn: Modifying User Cannot Change Password (LDAP Provider)
- Microsoft Learn: Reading User Cannot Change Password (LDAP Provider)
- Microsoft Learn: User-Change-Password extended right
- Microsoft Learn: Set-ADAccountControl
- Microsoft Learn: DirectoryEntry.ObjectSecurity
- Microsoft Learn: DirectoryEntryConfiguration.SecurityMasks
- Microsoft Learn: DirectoryObjectSecurity.GetAccessRules
Explore the identity security pages that support this topic
