I want to set "Password Must Change at Next Login" flag

15,490

Solution 1

How about using System.DirectoryServices.AccountManagement instead, in which case you can call the following code:

UserPrincipal.Current.ExpirePasswordNow();

Solution 2

The code below should work:

de.Properties["pwdLastSet"][0] = 0;

From User Must Change Password at Next Logon (LDAP Provider):

To force a user to change their password at next logon, set the pwdLastSet attribute to zero (0). To remove this requirement, set the pwdLastSet attribute to -1. The pwdLastSet attribute cannot be set to any other value except by the system.

Share:
15,490
jchoudhury
Author by

jchoudhury

I am a Senior Software Developer of IPDC Finance Ltd. I have been doing programming in .NET environment.

Updated on July 06, 2022

Comments

  • jchoudhury
    jchoudhury almost 2 years

    In my application, I am doing things that a user can control his/her local Windows User account from my app i.e. creating user, set/remove password, change password and also invoking password expiration policy is possible from my app. Now, at this point, I need to figure out If user wants to change his password at next login, then what happens. As many forums and blogs say about this, I did coding accordingly:

    Invoke Password Expire at Next Login

     public bool InvokePasswordExpiredPolicy()
        {
            try
            {
                string path = GetDirectoryPath();
                string attribute = "PasswordExpired";
                DirectoryEntry de = new DirectoryEntry(path);
                de.RefreshCache(new string[] { attribute });
                if(de.Properties.Contains("PasswordExpired"))
                de.Properties[attribute].Value = 1;
                de.CommitChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    

    Provoke Password Expire at Next Login. Reset the flag

    public bool ProvokePasswordExpiredPolicy()
        {
            try
            {
                string path = GetDirectoryPath();
                string attribute = "PasswordExpired";
                DirectoryEntry de = new DirectoryEntry(path);
                de.RefreshCache(new string[] { attribute });
                de.Properties[attribute].Value = -1;
                de.CommitChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    

    Checking for whether concerned flag is set or not

    public bool isPasswordPolicyInvoked()
        {
            try
            {
                string path = GetDirectoryPath();
                string attribute = "PasswordExpired";
                DirectoryEntry de = new DirectoryEntry(path);
                de.RefreshCache(new string[] { attribute });
                int value = Convert.ToInt32(de.Properties[attribute].Value);
    
                if (value == 1)
                    return true;
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }
        }
    

    I am using WinNT to get the directory path rather than LDAP. I used the following method to get the directory path.

    private String GetDirectoryPath()
        {
            String uName = this.userName;
            String mName = this.userMachine;
    
            String directoryPath = "WinNT://" + mName + "/" + uName;
    
            return directoryPath;
        }
    

    is there anything I am missing? Help me out here.

    Note: Firstly, I used pwdLastSet attribute to be set to 0(for on) and -1(for off) that throws an exception "Directory Property Not found in Property Cache", later I discovered that WinNT doesn't support this attribute rather it supports PasswordExpired which needs to be 1 to set the flag. That's what I did.