Since we manage passwords centrally, we don't want user to be able to change their password locallyand so we want to make sure that the "User cant change password" account option is set, and if not, set it. Unfortunately from a sysadmin programmer's point of view, it's an ntSecurityDescriptor ACL and not simply a bit flag in the userAccountControl word. O'Reilly's Active Directory Cookbook (p194) gives a nice exampleof how to set the ACL, and it works quite nicely. Can anybody tell me how to check the ACL to see if it's already set.
Re: How can I tell if an ntSecurityDesc ACL is set?
Here is what MSDN had to say about the subject
Reading User Cannot Change Password (LDAP Provider)
The ability of a user to change their password is a permission that can be granted or denied.
To determine if the change password permission is granted or denied
Bind to the user object.
Obtain the IADsSecurityDescriptor object from the ntSecurityDescriptor property of the user object.
Obtain an IADsAccessControlList interface for the security descriptor from the IADsSecurityDescriptor.DiscretionaryAcl property.
Enumerate the access control entries (ACE) for the object and search for the ACEs that have the change password GUID ({AB721A53-1E2F-11D0-9819-00AA0040529B}) for the IADsAccessControlEntry.ObjectType property and "Everyone" or "NT AUTHORITY\SELF" well-known security principals for the IADsAccessControlEntry.Trustee property.
Note The "Everyone" and "NT AUTHORITY\SELF" strings are localized based on the language of the first domain controller in the domain. Therefore, the strings should not be used directly. The account names should be obtained at run time by calling the LookupAccountSid function with the SID for the "Everyone" ("S-1-1-0") and "NT AUTHORITY\SELF" ("S-1-5-10") well-known security principals. The following C++ GetSidAccountName, GetSidAccountName_Everyone, and GetSidAccountName_Self code examples show how to do this.
If both the "Everyone" and "NT AUTHORITY\SELF" ACEs have the ADS_ACETYPE_ACCESS_DENIED_OBJECT value for the IADsAccessControlEntry.AceType property, then the permission is denied.
Here a the VB sample from MSDN - I have not tried it. The C++ sample is in the attached file, which I have not tried as well.
HTH.
Code:
Const CHANGE_PASSWORD_GUID = "{AB721A53-1E2F-11D0-9819-00AA0040529B}"
Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &H6
Function UserCannotChangePassword(strUserDN As String, strUsername As String, strPassword As String) As Boolean
UserCannotChangePassword = False
Dim oUser As IADs
Dim oSecDesc As IADsSecurityDescriptor
Dim oACL As IADsAccessControlList
Dim oACE As IADsAccessControlEntry
Dim fEveryone As Boolean
Dim fSelf As Boolean
fEveryone = False
fSelf = False
If "" <> strUsername Then
Dim dso As IADsOpenDSObject
' Bind to the group with the specified username and password.
Set dso = GetObject("LDAP:")
Set oUser = dso.OpenDSObject(strUserDN, strUsername, strPassword, 1)
Else
' Bind to the group with the current credentials.
Set oUser = GetObject(strUserDN)
End If
Set oSecDesc = oUser.Get("ntSecurityDescriptor")
Set oACL = oSecDesc.DiscretionaryAcl
For Each oACE In oACL
If UCase(oACE.ObjectType) = UCase(CHANGE_PASSWORD_GUID) Then
If oACE.Trustee = "Everyone" And oACE.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT Then
fEveryone = True
End If
If oACE.Trustee = "NT AUTHORITY\SELF" And oACE.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT Then
fSelf = True
End If
End If
Next
If fSelf And fEveryone Then
UserCannotChangePassword = True
Else
UserCannotChangePassword = False
End If
End Function
Last edited by f1shrman; April 5th, 2005 at 09:38 PM.
Reason: Added C++ sample
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.