locked
Having trouble setting up Password Filter for Windows 2012 r2 RRS feed

  • Question

  • I am having some trouble setting up Password Filter on Windows Server 2012 R2 64 bit. I've compiled a DLL per my requirement but the DLL does not load. I've used visual studio 2017 with c++ dll as my project template and built the dll as a x64 release

    I have modify the registry and put the dll in the right spot as per

    https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766(v=vs.85).aspx

    I have also installed visual c++ redistributable 2017 onto the machine.

    After restarting the machine, I should see the dll loaded in the modules section of system information, but with no avail, it is not there.

    Attached below is my code:

    #include "pch.h"
    #include <windows.h>
    #include <ntsecapi.h> 
    #include <stdio.h>
    
    BOOL APIENTRY DllMain(HMODULE /* hModule */, DWORD ul_reason_for_call, LPVOID /* lpReserved */)
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
    }
    
    
    #ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
    #endif
    
    extern "C" __declspec(dllexport) NTSTATUS NTAPI PasswordChangeNotify(PUNICODE_STRING UserName, ULONG RelativeId, PUNICODE_STRING Password)
    /*++
    
    Routine Description:
    
    This (optional) routine is notified of a password change.
    
    Arguments:
    
    UserName - Name of user whose password changed
    
    RelativeId - RID of the user whose password changed
    
    NewPassword - Cleartext new password for the user
    
    Return Value:
    
    STATUS_SUCCESS only - errors from packages are ignored.
    
    --*/
    {
    	FILE *fptr;
    	fopen_s(&fptr, "C:\\pass.txt", "a");
    	fprintf(fptr, "Went to PasswordChangeNotify");
    	fclose(fptr);
    	return STATUS_SUCCESS;
    }
    
    extern "C" __declspec(dllexport) BOOL __stdcall PasswordFilter(PUNICODE_STRING UserName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOL SetOperation)
    /*++
    
    Routine Description:
    
    This (optional) routine is notified of a password change.
    
    Arguments:
    
    UserName - Name of user whose password changed
    
    FullName - Full name of the user whose password changed
    
    NewPassword - Cleartext new password for the user
    
    SetOperation - TRUE if the password was SET rather than CHANGED
    
    Return Value:
    
    TRUE if the specified Password is suitable (complex, long, etc).
    The system will continue to evaluate the password update request
    through any other installed password change packages.
    
    FALSE if the specified Password is unsuitable. The password change
    on the specified account will fail.
    
    --*/
    {
    	BOOL bComplex = FALSE; // assume the password in not complex enough
    	DWORD cchPassword;
    	LPWORD CharType;
    	DWORD i;
    	DWORD dwNum = 0;
    	DWORD dwUpper = 0;
    	DWORD dwLower = 0;
    
    
    	//
    	// check if the password is complex enough for our liking by
    	// checking that at least two of the four character types are
    	// present.
    	//
    	FILE *fptr;
    	fopen_s(&fptr,"C:\\pass.txt", "a");
    	fprintf(fptr, "Went to PasswordFilter");
    	
    	CharType = (LPWORD)HeapAlloc(GetProcessHeap(), 0, Password->Length);
    	if (CharType == NULL) return FALSE;
    
    	cchPassword = Password->Length / sizeof(WCHAR);
    
    	if (GetStringTypeW(
    		CT_CTYPE1,
    		Password->Buffer,
    		cchPassword,
    		CharType
    	))
    	{
    
    		for (i = 0; i < cchPassword; i++)
    		{
    
    			//
    			// keep track of what type of characters we have encountered
    			//
    
    			if (CharType[i] & C1_DIGIT)
    			{
    				dwNum = 1;
    				continue;
    			}
    
    			if (CharType[i] & C1_UPPER)
    			{
    				dwUpper = 1;
    				continue;
    			}
    
    			if (CharType[i] & C1_LOWER)
    			{
    				dwLower = 1;
    				continue;
    			}
    
    			if (!(CharType[i] & (C1_ALPHA | C1_DIGIT)))
    			{
    
    				//
    				// any other character types make the password complex
    				//
    
    				dwNum = 2;
    
    				break;
    			}
    		} // for
    
    		  //
    		  // Indicate whether we encountered enough password complexity
    		  //
    
    		if ((dwNum + dwUpper + dwLower) >= 2)
    			bComplex = TRUE;
    
    		ZeroMemory(CharType, Password->Length);
    	} // if
    
    	HeapFree(GetProcessHeap(), 0, CharType);
    	fprintf(fptr, "Password is complex: %d", bComplex);
    	fclose(fptr);
    	return bComplex;
    }
    
    extern "C" __declspec(dllexport) BOOL __stdcall InitializeChangeNotify(void)
    /*++
    
    Routine Description:
    
    This (optional) routine is called when the password change package
    is loaded.
    
    Arguments:
    
    Return Value:
    
    TRUE if initialization succeeded.
    
    FALSE if initialization failed. This DLL will be unloaded by the
    system.
    
    --*/
    {
    	FILE *fptr;
    	fopen_s(&fptr, "C:\\pass.txt", "a");
    	fprintf(fptr, "Went to InitializeChangeNotify");
    	fclose(fptr);
    	return TRUE;
    }
    
    

    Thank you for your time

    Friday, April 6, 2018 7:18 PM