Platform SDK: Active Directory, ADSI, and Directory Services |
To determine whether the user is allowed to change his or her own password, read the ADS_UF_PASSWD_CANT_CHANGE (0x0040) bit on the userFlags attribute of the user's object. This flag is defined in the ADS_USER_FLAG_ENUM enumeration. You cannot set this flag directly.
To prevent a user from changing their password, you must set two ACEs in the security descriptor DACL of the user's object. One ACE denies the right to the user and another ACE denies the right to the Everyone group. Both ACEs are object-specific deny ACEs that specify the GUID of the extended right for changing passwords.
The following subroutine adds these two ACEs to prevent the user from changing the password. To change this right so the user can once again set their password, you must modify or delete the ACEs that deny access.
Sub UserCannotChange(oUserObject As IADsUser) Dim oSecDescriptor As SecurityDescriptor Dim oDACL As AccessControlList Dim oACE As New AccessControlEntry Dim oACE2 As New AccessControlEntry Const CHANGE_PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}" 'In order to preven the user from changing his/her own password we place a 'disallow access control entry on the object for that permission '-- Create the Access Control Entry for Self--- oACE.Trustee = "NT AUTHORITY\SELF" oACE.AceFlags = 0 oACE.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT oACE.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT oACE.ObjectType = CHANGE_PASSWORD_GUID oACE.AccessMask = ADS_RIGHT_DS_CONTROL_ACCESS ' --- Create the Access Control Entry for Everyone--- oACE2.Trustee = "EVERYONE" oACE2.AceFlags = 0 oACE2.AceType = ADS_ACETYPE_ACCESS_DENIED_OBJECT oACE2.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT oACE2.ObjectType = CHANGE_PASSWORD_GUID oACE2.AccessMask = ADS_RIGHT_DS_CONTROL_ACCESS '--- Get this objects Security Descriptor Set oSecDescriptor = oUserObject.Get("ntSecurityDescriptor") '--- Get the Discretionary ACL --- Set oDACL = oSecDescriptor.DiscretionaryAcl '-- Add our new ACEs and replace DACL--- oDACL.AddAce oACE oDACL.AddAce oACE2 ' -- Put the Security Descriptor back on the object -- oUserObject.Put "ntSecurityDescriptor", oSecDescriptor oUserObject.SetInfo ' -- Clean up -- Set oACE = Nothing Set oACE2 = Nothing Set oDACL = Nothing Set oSecDescriptor = Nothing End Sub