At work, we’ve never used the “normal” way of changing Windows passwords. Historically, this is because computers were not members of the domain … so you couldn’t use Ctrl-Alt-Del to change your domain password. Now that computers are members of the domain, changing Active Directory passwords using an external method creates a lot of account lockouts. The Windows workstation is logged in using the old credentials, the password gets changed without it knowing (although you can use ctrl-alt-del, lock the workstation unlock with the new password and update the local workstation creds), and the workstation continues using the old credentials and locks the account.
This is incredibly disruptive to business, and quite a burden on the help desk … so we are going to hook the AD-initiated password changes and feed them into the Identity Management platform. Except … the password policies don’t match. But AD doesn’t know the policy on the other end … so the AD password gets changed and then the new password fails to be committed into the IDM system. And then the user gets locked out of something else because they keep trying to use their new password (and it isn’t like a user knows which directory is the back-end authentication source for a web app to use password n in AD and n-1 in DSEE).
A long time ago, back when I knew some military IT folks who were migrating to Windows 2000 and needed to implement Rainbow series compliant passwords in AD – which was possible using a custom password filter. This meant a custom coded DLL that accepted or rejected the proposed password based on custom-coded rules. Never got into the code behind it – I just knew they would grab the DLL & how to register it on the domain controller.
This functionality was exactly what we needed — and Microsoft still has a provision to use a custom password filter. Now all we needed was, well, a custom password filter. The password rules prohibit the use of your user ID, your name, and a small set of words that are globally applied to all users. Microsoft’s passfilt.dll takes care of the first two — although with subtle differences from the IDM system’s rules. So my requirement became a custom password filter that prohibits passwords containing case insensitive substrings from a list of words.
I based my project on OpenPasswordFilter on GitHub — the source code prohibits exact string matches. Close, but not quite 🙂 I modified the program to check the proposed password for case insensitive substrings. I also changed the application binding to localhost from all IP address since there’s no need for the program to be accessed from outside the box. For troubleshooting purposes, I removed the requirement that the binary be run as a service and instead allowed it to be run from a command prompt or as a service. I’m still adding some more robust error handling, but we’re ready to test! I’ve asked them to baseline changing passwords without the custom filter, using a custom filter that has the banned word list hard coded into the binary, and using a custom filter that sources its banned words list from a text file. Hopefully we’ll find there isn’t a significant increase in the time it takes a user to change their password.
My updated code is available at http://lisa.rushworth.us/OpenPasswordFilter-Edited.zip
Hello Lisa,
I installed your built version on windows server 2008 (my dc) but I have the error “the service on local computer started and then stopped..”.
any idea?
Thanks!
I’ve had to use perfmon/filemon in conjunction with starting the service to find out what I was missing before. IIRC, it was the redistributable .net framework of a specific version. Since the company I work for has an EA and uses ADFS … we started using on-prem Azure AD password protection (https://docs.microsoft.com/en-us/azure/active-directory/authentication/howto-password-ban-bad-on-premises-deploy).
Hello all,
thanks for your site Lisa.
I installed your compiled program, but have the error “service could not be started”.
Any idea?
Hello, i can`t find the archive OpenPasswordFilter.dll, where is the file?
Build the project in Visual Studio — the DLL and exe’s will end up in the build target (the console will tell you the exact location). Under heavy load, I’ve had problems with the password filter and have updated the filter code https://github.com/ljr55555/OpenPasswordFilter
Hello
I’ve been using this filter for almost a year and it was flawlessly working. However, latest Windows Patch for Feb 2019 might have caused it not to work.
Have you tested this with the latest windows security patch?
Hi, i’m trying to first run the original OPF and later i’ll try to do like the way is here. But i’m having an issue that the password filter only works with ctrl+alt+del. If i force a change by the server, the password filter is completely ignored. Could you know what it would be ?
Hmmm … Since the policy is being applied in some cases, you’ve got the password complexity requirements set properly (last step of https://docs.microsoft.com/en-us/windows/desktop/secmgmt/installing-and-registering-a-password-filter-dll). Do you have more than one domain controller? The filter needs to be installed and registered on each domain controller within the domain.
I ran a load simulation using admin-initiated password resets (dsmod user \”$strUID\” -pwd $strPassword -mustchpwd no -s $strDomainController -u $strAdminUID -p $strAdminPassword) so can confirm that admin-initiated resets should invoke the filter.
I had a problem with the OPF code several iterations back — the domain controller would sometimes OK a password it should have failed. If I ran the dsmod command with should-be-failed passwords against the same domain controller ten times, it would approve the password one or two times. Through a great deal of debugging (documented on this site), I isolated the problem down to the DLL failing to make a call out to the external service. In the course of my troubleshooting, I’ve added quite a bit of Windows Event logging to my newest iteration of the project on GitHub. There is a debugging level you can set on the dllmain.cpp to compile a DLL that is very verbose in its event logging. You can then tell the difference between LSA not invoking the filter with its PasswordFilter call, the custom DLL not communicating to the service, or the service returning something unexpected.
This site is absolutely fabulous!
hello lisa,
How can I use your edited cose with the installer.
Which path can i manually copy the files to… or can i just replace the files on the original with your edited copies.
Thanks,
Solar
The zip file contains the Visual Studio project – you can build the project or grab the version I built from http://lisa.rushworth.us/BuiltPasswordFilter.zip (md5sum b0f7ab3aba71f3b9b80273d6b86d06d0)
There are three files needed for installation: OpenPasswordFilter.dll, OPFService.exe, and opfdict.txt (when you build the project yourself, just make this notepad and add whatever words you want to exclude from user passwords). The filter needs to be installed on ALL domain controllers in the domain. If one is missing, users can set a password on that domain controller to something that is not compliant.
Installing:
Have you in the mean time perhaps evaluated which version is the quickest and in how far user experience is impacted?
I’m thinking about using your code, adding MySQL capabilities and using it at work, would this be okay with you?
Thanks and best regards
Chris
Sorry, ignore my comment.
Feel free to use and adapt it however you would like (the OpenSource license, GNUv2, is included with the zipped code file). I’ve used it at a Fortune 500 company (~13,000 users) for about six months now and haven’t seen any adverse impact on the DCs or user experience.
Happy Friday!
–Lisa
Thanks a lot for your support.
I solved the issue, was a mistake in Group Policy Configuration, now is working fine.
Thanks
Best Regards
Francesco
Hello,
I very interisting article. I am trying to use your password filter but I seems that lsass doesn’t invoke passwordfilter dll.
DLL is loaded, but if I try to change password it doesn’t call dll.
I have a PC on my domain and trying to change password using CTRL+ALT+DEL, is it correct ?
Could you help ?
Thanks
The call is made regardless of the password change source – using ctrl-alt-del or an admin password reset should run the proposed password through the custom filter. Did you add the filter into the Notification Packages list (https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766(v=vs.85).aspx)? I’ve needed to reboot each domain controller after the change is made for the DLL to be called.
If the DLL has been registered as a notification package, you might use something like Process Monitor (https://docs.microsoft.com/en-us/sysinternals/downloads/procmon) to watch the calls. While this is not something I’d do on a production domain controller in the middle of the day, it’s a great tool to use on sandbox servers. If prod is your only choice and there are multiple domain controllers in a site, you could create a firewall rule to temporarily restrict access from devices other than your testing workstation.