Managing User Passwords

This topic includes information and code examples for managing user passwords.

The following C# code example shows how to set the user password by invoking the IADsUser::SetPassword method. For more information about IADsUser::SetPassword, see "IADsUser::SetPassword" in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

usr.Invoke("SetPassword", SecurelyStoredPassword);

The following C# code example shows how to change the user password by invoking the IADsUser::ChangePassword method. For more information about IADsUser::ChangePassword, see "IADsUser::ChangePassword" in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

usr.Invoke("ChangePassword", OldSecurelyStoredPassword, NewSecurelyStoredPassword);

The following C# code example shows how to set the user password so that it must be changed at the next logon. It sets the pwdLastSet property to off (-1). For more information about the adschema pwdLastSet attribute, see "pwdLastSet" or "Pwd-Last-Set attribute" in the MSDN Library at https://go.microsoft.com/fwlink/?LinkID=27252.

usr.Properties["pwdLastSet"].Value = -1; // To turn on, set this value to 0.
usr.CommitChanges();

The following Visual Basic .NET code example shows a function that sets an ACE to deny a user the right to change their password. It uses Using COM Interop to Access ADSI to access the IADsSecurityDescriptor to get the ntSecurityDescriptor property. It then uses the IADsAccessControlList to get the DACL from the security descriptor and IADsAccessControlEntry to get the AceType, AceFlags, Trustee, Flags, ObjectType and AccessMask properties. The AceType flags are defined in ADS_ACETYPE_ENUM. The AceFlags are defined in the ADS_FLAGTYPE_ENUM. AccessMask flags are defined in the ADS_RIGHTS_ENUM.

Imports System
Imports System.DirectoryServices
Imports ActiveDs

Shared Sub DenyChangePassword(User As DirectoryEntry)
    Const PASSWORD_GUID As String = "{ab721a53-1e2f-11d0-9819-00aa0040529b}"
    
    Dim trustees() As String = {"NT AUTHORITY\SELF", "EVERYONE"}
    
    Dim sd As ActiveDs.IADsSecurityDescriptor = CType(User.Properties("ntSecurityDescriptor").Value, 
        ActiveDs.IADsSecurityDescriptor)
    Dim acl As ActiveDs.IADsAccessControlList = CType(sd.DiscretionaryAcl, 
        ActiveDs.IADsAccessControlList)
    Dim ace As New ActiveDs.AccessControlEntry()
    
    Dim trustee As String
    For Each trustee In  trustees
         ace.Trustee = trustee
         ace.AceFlags = 0
         ace.AceType = Fix(ActiveDs.ADS_ACETYPE_ENUM.ADS_ACETYPE_ACCESS_DENIED_OBJECT)
         ace.Flags = Fix(ActiveDs.ADS_FLAGTYPE_ENUM.ADS_FLAG_OBJECT_TYPE_PRESENT)
         ace.ObjectType = PASSWORD_GUID
         ace.AccessMask = Fix(ActiveDs.ADS_RIGHTS_ENUM.ADS_RIGHT_DS_CONTROL_ACCESS)
         acl.AddAce(ace)
    Next trustee
    sd.DiscretionaryAcl = acl
    User.Properties("ntSecurityDescriptor").Value = sd
    User.CommitChanges()
End Sub 'DenyChangePassword

The following Visual Basic .NET example shows a function that sets an ACE to deny a user the right to change their password. This example uses the managed ACL functionality available in .NET Framework 2.0.

Imports System
Imports System.DirectoryServices
Imports System.Security.Principal
Imports System.Security.AccessControl

Sub DenyChangePassword(ByVal user As DirectoryEntry)
    ' Create a Guid that identifies the Change Password right.
    Dim changePasswordGuid As New Guid("{AB721A53-1E2F-11D0-9819-00AA0040529B}")

    ' Get the ActiveDirectorySecurity for the user.
    Dim userSecurity As ActiveDirectorySecurity = user.ObjectSecurity

    ' Create a SecurityIdentifier object for "everyone".
    Dim everyoneSid As New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing)

    ' Create a SecurityIdentifier object for "self".
    Dim selfSid As New SecurityIdentifier(WellKnownSidType.SelfSid, Nothing)

    ' Create an access rule to allow everyone the change password 
    ' right. 
    ' This is used to remove any existing access rules.
    Dim allowEveryone As New ActiveDirectoryAccessRule(everyoneSid, _
        ActiveDirectoryRights.ExtendedRight, _
        AccessControlType.Allow, _
        changePasswordGuid)

    ' Create an access rule to deny everyone the change password right.
    Dim denyEveryone As New ActiveDirectoryAccessRule(everyoneSid, _
        ActiveDirectoryRights.ExtendedRight, _
        AccessControlType.Deny, _
        changePasswordGuid)

    ' Create an access rule to allow self the change password right.
    ' This is used to remove any existing access rules.
    Dim allowSelf As New ActiveDirectoryAccessRule(selfSid, _
        ActiveDirectoryRights.ExtendedRight, _
        AccessControlType.Allow, _
        changePasswordGuid)

    ' Create an access rule to deny self the change password right.
    Dim denySelf As New ActiveDirectoryAccessRule(selfSid, _
        ActiveDirectoryRights.ExtendedRight, _
        AccessControlType.Deny, _
        changePasswordGuid)

    ' Remove any existing rule that gives "everyone" the change 
    ' password right.
    userSecurity.RemoveAccessRuleSpecific(allowEveryone)

    ' Add a new access rule to deny "everyone" the change password 
    ' right.
    userSecurity.AddAccessRule(denyEveryone)

    ' Remove any existing rule that gives "self" the change password 
    ' right.
    userSecurity.RemoveAccessRuleSpecific(allowSelf)

    ' Add a new access rule to deny "self" the change password right.
    userSecurity.AddAccessRule(denySelf)

    ' Commit the changes.
    user.CommitChanges()

End Sub 'DenyChangePassword

The following C# code example shows a function that sets an ACE to deny a user the right to change their password. It uses Using COM Interop to Access ADSI to access the IADsSecurityDescriptor to get the ntSecurityDescriptor property. It then uses the IADsAccessControlList to get the DACL from the security descriptor and IADsAccessControlEntry to get the AceType, AceFlags, Trustee, Flags, ObjectType and AccessMask properties. The AceType flags are defined in ADS_ACETYPE_ENUM. The AceFlags are defined in the ADS_FLAGTYPE_ENUM. AccessMask flags are defined in the ADS_RIGHTS_ENUM.

using System;
using System.DirectoryServices;
using ActiveDs;

static void DenyChangePassword(DirectoryEntry User)
{
    const string PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}";
    const int ADS_UF_PASSWORD_EXPIRED=0x800000;
    const int ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION=0x1000000;
    string[] trustees = new string[]{@"NT AUTHORITY\SELF","EVERYONE"};

    ActiveDs.IADsSecurityDescriptor sd = (ActiveDs.IADsSecurityDescriptor)
        User.Properties["ntSecurityDescriptor"].Value;
    ActiveDs.IADsAccessControlList acl = (ActiveDs.IADsAccessControlList) sd.DiscretionaryAcl;
    ActiveDs.IADsAccessControlEntry ace = new ActiveDs.AccessControlEntry();

    foreach(string trustee in trustees)
    {
        ace.Trustee = trustee;
        ace.AceFlags = 0;
        ace.AceType = (int)ActiveDs.ADS_ACETYPE_ENUM.ADS_ACETYPE_ACCESS_DENIED_OBJECT;
        ace.Flags = (int)ActiveDs.ADS_FLAGTYPE_ENUM.ADS_FLAG_OBJECT_TYPE_PRESENT;
        ace.ObjectType = PASSWORD_GUID;
        ace.AccessMask = (int)ActiveDs.ADS_RIGHTS_ENUM.ADS_RIGHT_DS_CONTROL_ACCESS;
        acl.AddAce(ace);
    }
    sd.DiscretionaryAcl = acl;
    User.Properties["ntSecurityDescriptor"].Value = sd;
    User.CommitChanges();
}

The following C# example shows a function that sets an ACE to deny a user the right to change their password. This example uses the managed ACL functionality available in .NET Framework 2.0.

using System;
using System.DirectoryServices;
using System.Security.Principal;
using System.Security.AccessControl;

static void DenyChangePassword(DirectoryEntry user)
{
    // Create a Guid that identifies the Change Password right.
    Guid changePasswordGuid = 
        new Guid("{AB721A53-1E2F-11D0-9819-00AA0040529B}");

    // Get the ActiveDirectorySecurity for the user.
    ActiveDirectorySecurity userSecurity = user.ObjectSecurity;

    // Create a SecurityIdentifier object for "everyone".
    SecurityIdentifier everyoneSid = 
        new SecurityIdentifier(WellKnownSidType.WorldSid, null);

    // Create a SecurityIdentifier object for "self".
    SecurityIdentifier selfSid = 
        new SecurityIdentifier(WellKnownSidType.SelfSid, null);

    // Create an access rule to allow everyone the change password 
    // right. 
    // This is used to remove any existing access rules.
    ActiveDirectoryAccessRule allowEveryone = 
        new ActiveDirectoryAccessRule(
            everyoneSid,
            ActiveDirectoryRights.ExtendedRight, 
            AccessControlType.Allow, 
            changePasswordGuid);

    // Create an access rule to deny everyone the change password right.
    ActiveDirectoryAccessRule denyEveryone =
        new ActiveDirectoryAccessRule(
            everyoneSid,
            ActiveDirectoryRights.ExtendedRight,
            AccessControlType.Deny,
            changePasswordGuid);

    // Create an access rule to allow self the change password right.
    // This is used to remove any existing access rules.
    ActiveDirectoryAccessRule allowSelf =
        new ActiveDirectoryAccessRule(
            selfSid,
            ActiveDirectoryRights.ExtendedRight,
            AccessControlType.Allow,
            changePasswordGuid);

    // Create an access rule to deny self the change password right.
    ActiveDirectoryAccessRule denySelf =
        new ActiveDirectoryAccessRule(
            selfSid,
            ActiveDirectoryRights.ExtendedRight,
            AccessControlType.Deny,
            changePasswordGuid);

    // Remove any existing rule that gives "everyone" the change 
    // password right.
    userSecurity.RemoveAccessRuleSpecific(allowEveryone);

    // Add a new access rule to deny "everyone" the change password 
    // right.
    userSecurity.AddAccessRule(denyEveryone);

    // Remove any existing rule that gives "self" the change password 
    // right.
    userSecurity.RemoveAccessRuleSpecific(allowSelf);

    // Add a new access rule to deny "self" the change password right.
    userSecurity.AddAccessRule(denySelf);

    // Commit the changes.
    user.CommitChanges();
}

The following code example shows how to set the password to never expire. It uses the Properties method to access the userAccountControl property to set the ADS_UF_DONT_EXPIRE_PASSWD flag defined in the ADS_USER_FLAG_ENUM.

Shared Sub DontExpirePassword(User As DirectoryEntry)
    Dim val As Integer
    Const ADS_UF_DONT_EXPIRE_PASSWD As Integer = &H10000
    val = Fix(User.Properties("userAccountControl").Value)
    User.Properties("userAccountControl").Value = val Or ADS_UF_DONT_EXPIRE_PASSWD
    User.CommitChanges()
End Sub 'DontExpirePassword
using System;
using System.DirectoryServices;
using ActiveDs;

static void DontExpirePassword(DirectoryEntry User)
{
    int val;
    const int ADS_UF_DONT_EXPIRE_PASSWD =0x10000;
    val = (int) User.Properties["userAccountControl"].Value;
    User.Properties["userAccountControl"].Value = val | 
        ADS_UF_DONT_EXPIRE_PASSWD;
    User.CommitChanges();
}

See Also

Reference

System.DirectoryServices

Concepts

User Management
Using COM Interop to Access ADSI

Send comments about this topic to Microsoft.

Copyright © 2007 by Microsoft Corporation. All rights reserved.