Part 1. Password Filter for OS
I. Password Filters. 1
1. Password Filter Functions
2. Password Filter Programming Considerations
3. Installing and Registering a Password Filter DLL
To install and register a Windows password filter DLL
II. Enforce Custom Password Policies in Windows
III. Configuring Security Policy
IV. The RegEx Password Filter Sample
V. Installing the Password Filter
VI. Source Code Compiler by VC++
– Download boots link:
– Error when Building:
I. Password Filters
Password filters provide a way for you to implement password policy and change notification.
When a password change request is made, the Local Security Authority (LSA) calls the password filters registered on the system. Each password filter is called twice: first to validate the new password and then, after all filters have validated the new password, to notify the filters that the change has been made. The following illustration shows this process.
Password change notification is used to synchronize password changes to foreign account databases.
Password filters are used to enforce password policy. Filters validate new passwords and indicate whether the new password conforms to the implemented password policy.
For an overview of using password filters, see Using Password Filters.
For a list of password filter functions, see Password Filter Functions.
The following topics provide more information about password filters:
The following password filter functions are implemented by custom password filter DLLs to provide password filtering and password change notification.
When implementing password filter export functions, keep the following considerations in mind:
- Take great care when working with plaintext passwords. Sending plaintext passwords over networks could compromise security. Network “sniffers” can easily watch for plaintext password traffic.
- Erase all memory used to store passwords by calling the SecureZeroMemory function before freeing memory.
- All buffers passed into password notification and filter routines should be treated as read-only. Writing data to these buffers may cause unstable behavior.
- All password notification and filter routines should be thread-safe. Use critical sections or other synchronous programming techniques to protect data where appropriate.
- Password notification and filtering take place only on the computer that houses the account.
- All domain controllers are writeable, therefore password filter packages must be present on all domain controllers.
Windows NT 4.0 domains: Notification on domain accounts takes place only on the primary domain controller. In addition to the primary domain controller, the password filter packages should be installed on all backup domain controllers to allow notifications to continue in the event of server role changes.
- All password filter DLLs run in the security context of the local system account.
You can use the Windows password filter to filter domain or local account passwords. To use the password filter for domain accounts, install and register the DLL on each domain controller in the domain.
Perform the following steps to install your password filter. You can perform these steps manually, or you can write an installer to perform these steps. You need to be an Administrator or belong to the Administrator Group to perform these steps.
1. Copy the DLL to the Windows installation directory on the domain controller or local computer. On standard installations, the default folder is \Windows\System32. Make sure that you create a 32-bit password filter DLL for 32-bit computers and a 64-bit password filter DLL for 64-bit computers, and then copy them to the appropriate location.
2. To register the password filter, update the following system registry key:
If the Notification Packages subkey exists, add the name of your DLL to the existing value data. Do not overwrite the existing values, and do not include the .dll extension.
If the Notification Packages subkey does not exist, add it, and then specify the name of the DLL for the value data. Do not include the .dll extension.
The Notification Packages subkey can add multiple packages.
7. Find the password complexity setting.
In Control Panel, click Performance and Maintenance, click Administrative Tools, double-click Local Security Policy, double-click Account Policies, and then double-click Password Policy.
8. To enforce both the default Windows password filter and the custom password filter, ensure that the Passwords must meet complexity requirements policy setting is enabled. Otherwise, disable the Passwords must meet complexity requirements policy setting.
Most people take the easy way out and use the default filter in order to validate passwords. But did you know you can employ authentication modules to customize your password policies to reflect your organization’s unique security requirements? Find out how in this article.
Microsoft Windows allows you to define various password policy rules. Specifically, it allows you to enable the “Password must meet complexity requirements” setting using the Policy Editor. This validates user passwords against password filter(s) (system DLL(s)). Usually, people use the default filter. However, many admins say they’d prefer a Linux-style validation, which would allow them to install various pluggable authentication modules (Linux-PAM modules) to filter user passwords (authentication tokens). You can easily adapt these modules to reflect your organization’s security policy with help of Linux configuration text files. The ability to add-on such modules creates more flexibility in composing password policies. With help of such custom modules (of course, these modules should be developed by a Linux programmers), Linux administrators may even author a regular expression for matching user passwords. Go to www.kernel.org/pub/linux/libs/pam/ for more detailed information about Linux-PAM and the available modules.
The Linux model described above may be employed on Windows machines as well.
What You Need: Windows NT/2000/XP
In this article, learn how to create a Custom Password Filter (DLL in C++) that validates passwords against a configurable regular expression. The RegEx functionality is implemented based on the Boost open source library because it has wide support for regular expressions.
Let’s start with an overview of the Windows Security system.
Windows Security is a policy-based system with a set of rules that compose security settings for a local machine or domain. The work of policy-based systems usually has three major stages:
- Creating rules to compose a policy.
- Searching for evidences.
- Enforcing policy based on the evidences.
There is a parallel between the above stages and real-life legal systems. Most countries have an authority (usually parliament or senate) that makes laws. This corresponds to the first stage—composing the policy). Police departments are the guards of the legal system, responsible for collecting evidence (e.g. measuring car speed on highways) and enforcing the existing laws based on evidences (e.g. canceling driving license in case of exceeding the speed limit). So, a police force corresponds to the second and third stages.
In Windows security, system administrators play the role of parliament. They dictate the policy for an organization domain. In some cases, regular users also design security policy (e.g. when choosing their own passwords). The police uniform is given to the local security authority (LSA) Windows sub-system. LSA collects evidences for decision-making and enforces the policies (laws). The LSA sub-system is represented by the lsass.exe Windows process and several system DLLs.
System Administrators are usually responsible for configuring Security Policy. Since this article is about password filters, I’ll use configuring Password Policy as the example.
Figure 1. The “Local Security Policy” Management Console: This shows the list of security settings that compose your password policy on the local machine.
As mentioned previously, regular users are involved in composing security settings when they choose their own log-on passwords. However, because a weak password can create vulnerable system and compromise organization security, system administrators need more control over this issue and disallow the use of too simple, short and vulnerable to dictionary attacks passwords. In other words, you need to compose a password policy that meets your organization’s security requirements.
To edit security policies, you can use either the secedit.exe command line utility or the “Domain Security Policy” graphical console available from Control Panel -> Administrative Tools on the domain controller machine. With this tool, you will govern the security policy for all the computers in the Windows domain. Note that in case of workstation machine, only the “Local Security Policy” console is installed (shown in Figure 1). Local policy affects settings on the local machines and it doesn’t override domain policy. Thus, the security settings will be effective for local machine users, but not for domain users. This article uses the graphical tool to alter security settings on the local machine.
Figure 2. Editing Password Policy Rules: Double-click the “Minimum password length” item to display the dialog window.
The left pane of the management console contains an Explorer-like tree. Each node represents a different Security Policy. In this example, you’ll make modifications to the Password Policy to require users to choose long enough passwords (at least 10 characters). Here’s how to do it:
Expand the “Account Policies” node and select “Password Policy.” On the right pane of the management console, you should see a list of security settings (rules) that compose the password policy as shown in Figure 1. Double-click the “Minimum password length” item to display the dialog window (Figure 2). Edit the text field, setting the minimum password length to 10 characters, and click OK.
Congratulations! The new rule is ready. From now on, LSA will not allow your users to choose passwords shorter than 10 characters.
An interesting rule from the Password Policy set is “Password must meet complexity requirements.” This rule may be either Disabled or Enabled. In the Disabled state it has no effect. Enabling this rule instructs LSA to validate each password against Password Filters. If you don’t provide any filter, the default is used (which is considered relatively strong). However, the default allows simple passwords, such as Paris123. You definitely want more powerful filters and this is where Custom Password Filters can be helpful.
What Is a Password Filter?
A Password Filter plays a primary role in decision-making regarding user passwords. By definition, a Password Filter is a system DLL that exports three functions with the following prototypes (note the __stdcall calling convention):
BOOLEAN __stdcall InitializeChangeNotify(void); // (1)
BOOLEAN __stdcall PasswordFilter( // (2)
NTSTATUS __stdcall PasswordChangeNotify( // (3)
How does LSA interact with Custom Password Filters by means of the above interface? First, assume that the “Password must meet complexity requirements” rule is Enabled. On the system startup, LSA loads all the available Password Filters and calls the InitializeChangeNotify() function. When LSA receives TRUE as a return value, this means that the Password Filter loaded successfully and functions properly. Upon this call, LSA also builds a chain of available Password Filters (those that returned TRUE).
When you’re giving a password to a new user or modifying an existing user’s password, LSA assures that every link in Password Filters Chain is satisfied with a new password. LSA invokes the PasswordFilter() function of each filter in the chain. If one filter in a chain returned FALSE, LSA does NOT continue calling the next filter. Instead, it asks the user to provide another password. If every call to PasswordFilter on every filter returns a TRUE value, a new password is approved and each filter is notified about it through the PasswordChangeNotify() function.
As you can see, the Password Filter is a handy tool for LSA (or, the Windows Police), acting as a speed trap for highway patrol, helping to collect evidence from the “field.” These evidences are useful in the third stage, where policies are enforced.
Before You Implement…
Consider the following issues before you start coding your own Password Filters:
Treat sensitive data carefully. The PasswordFilter and PasswordChangeNotify functions receive passwords in clear-text format. These passwords should be processed fast and shouldn’t leave any trails in your memory for malicious applications to capture. Introduced in Windows 2003, the SecureZeroMemory Win32 API cleans specified memory. Traditional ZeroMemory may be not enough, since “smart” compilers will optimize your code and remove calls to this API. To make sure there are no such “useful” optimizations, read a random byte from a password string after it was filled with zeros.
Make your filters fast and efficient. When LSA calls into the Password Filter function, most Windows processing stops, so make sure you don’t perform any lengthy operations.
Expect the unexpected. Because LSA loads password filters during start-up, if something goes wrong, your system may become inoperable or go into deadlock. To avoid this, develop and test your DLLs on machines that have at least two operating systems installed. I have Linux and XP on my box and I found it highly useful when preparing this article. When I encountered problems, I booted from Linux and deleted the Password Filter DLL.
Log your actions. Password Filters run in the context of the lsass.exe process. I don’t recommend debugging this process, because after you close the debugger and end the process, your system will shutdown. The best way to debug your already-running filter is to write the log files to disk and follow them to fix the bugs.
Pre-debug your DLL. While lsass.exe debugging is not recommended, you may test your fresh Password Filter by writing a small unit-test program. In this program, load your DLL with a call to LoadLibrary Win32 API and invoke exported functions (after getting their addresses within GetProcAddress Win 32 API calls). This way, you may check that your filter doesn’t crash and functions properly.
Now that you’re aware of all the possible pitfalls, it’s high time for code action. This section will walk you through the sample provided with this article. I’ve created a VS7 solution with the PasswordFilterRegEx VC project.
As the Password Filter definition requires, you export three functions. Here’s the code for the DEF file included within the sample project:
The PasswordFilterRegEx.cpp contains source code for the exported functions. The implementations of InitializeChangeNotify and PasswordChangeNotify are quite simple:
// Initialization of Password filter.
// This implementation just returns TRUE
// to let LSA know everything is fine
BOOLEAN __stdcall InitializeChangeNotify(void)
// This function is called by LSA when password
// was successfully changed.
// This implementation just returns 0 (Success)
NTSTATUS __stdcall PasswordChangeNotify(
The bulk of the work is done in the PasswordFilter function (shown in Listing 1). First, create a zero-terminating copy of a password string and assign it to an STL wstring object (STL is used in conjunction with the boost regex library):
wszPassword = new wchar_t[Password->Length + 1];
if (NULL == wszPassword)
wcsncpy(wszPassword, Password->Buffer, Password->Length);
wszPassword[Password->Length] = 0;
WriteToLog(“Going to check password”);
// Initialize STL string
wstrPassword = wszPassword;
Next, the regular expression is instantiated. The sample Password Filter reads the regular expression from the RegEx value of the following registry key:
If the value is not found in registry, the dummy default regular expression (“^(A)$”) is used.
Finally, validate the password against the regular expression and return the results to the caller (LSA):
WriteToLog(“Going to run match”);
// Prepare iterators
wstring::const_iterator start = wstrPassword.begin();
wstring::const_iterator end = wstrPassword.end();
unsigned int flags = match_default;
bMatch = regex_match(start, end, what, wrePassword);
WriteToLog(“Password matches specified RegEx”);
WriteToLog(“Password does NOT match specified RegEx”);
. . .
Just before you return the results to LSA, perform memory clean-up:
// Erase all temporary password data
// for security reasons
wstrPassword.replace(0, wstrPassword.length(), wstrPassword.length(),
if (NULL != wszPassword)
// Assure that there is no compiler optimizations and read random byte
// from cleaned password string
wchar_t wch = wszPassword[rand() % Password->Length];
delete  wszPassword;
wszPassword = NULL;
Note: In order to filter passwords for domain users, you should use the “Domain Security Policy” console on domain controller machine and install there your password filter. In this example, the entire configuration is done on the local machine. Hence, Password Filter will validate passwords for my local machine accounts. Follow this procedure to activate your fresh Password Filter (the same procedure is applicable for the domain controller):
Enable the “Password must meet complexity requirements” rule of the Password Policy.
Copy the Password Filter DLL to the %SystemRoot%\system32 folder on your machine.
Open the Registry Editor (regedit.exe) and locate the following registry key:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
Modify the “Notification Packages” multi-string value of the above key and add your Password Filter file name without the “.dll” extension. Add the PasswordFilterRegEx string as shown in Figure 3.
Figure 3. Editing “Notification Packages”: Add the PasswordFilterRegEx string.
Close Registry Editor and restart your machine.
Your Password Filter in Action
After you’ve installed Password Filter and restarted your machine, you’re ready for testing. The source code includes a simple regular expression for testing purposes. Find it in the RegEx value of the HKLM\Software\DevX\PasswordFilter key (the PasswordFilter.reg file is provided with the code for your convenience):
In other words, start with letters, have some digits in the middle and end up with letters again. This regular expression is not recommended as a strong Password Regular expression, but it is useful for assessing whether your Password Filter does its job.
Figure 4. Creating a New User: Select Expand Local Users and Groups, right-click on the Users node, and choose the New User menu item.
Remember that this filter stands after the default Windows filter in the chain. So, in order to have any effect, you’ll need tougher requirements than the default. The Paris2003 password will validate against the default filter, but the test regular expression won’t match it. To check this, create a new user. If you use Domain Controller, create a user with Active Directory. On the stand-alone Workstation machine, right-click on My Computer and choose the Manage item from the context menu. Select Expand Local Users and Groups, right-click on the Users node, and choose the New User menu item as shown in Figure 4.
Fill-in the new user’s details and assign a password. Try a simple one (e.g.: Paris2003) and you will get an error message from LSA (Figure 5). Try a different, more complex password (e.g.: Paris2003A) and it will be accepted.
The Secret Is Out
While there are several commercial products that implement Password Filters, it isn’t really all that difficult. Now, that you understand how they work, you can provide your own, customized solution.
Figure 5. Error!: This password doesn’t meet the complexity requirements.
– Download boots link: http://nchc.dl.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.zip
I writed project which uses <boost/thread/locks.hpp>, i added include directory to Additional Include directories, and lib folder to linker. But when i try to build solution, error:
Error 1 error LNK1104: cannot open file ‘libboost_thread-vc100-mt-sgd-1_50.lib’
I searched this file in lib directory, but no file with this name in lib directory. I found file with similar name libboost_thread-vc100-mt-gd-1_50.
To install Boost.Build from an official release or a nightly build, as available on the official web site, follow these steps:
1. Unpack the release. On the command line, go to the root of the unpacked tree.
2. Run either .\bootstrap.bat (on Windows), or ./bootstrap.sh (on other operating systems).
./b2 install –prefix=PREFIX
where PREFIX is a directory where you want Boost.Build to be installed.
4. Optionally, add PREFIX/bin to your PATH environment variable.
If you are not using a Boost.Build package, but rather the version bundled with the Boost C++ Libraries, the above commands should be run in the tools/build/v2 directory.
Now that Boost.Build is installed, you can try some of the examples. Copy PREFIX/share/boost-build/examples/hello to a different directory, then change to that directory and run:
A simple executable should be built.