// This is the main DLL file. #include "stdafx.h" #include #include #include #include "PasswordFilter.h" using namespace std; #define LOGFILE "c:\\users\\admin\\FilterLog.txt" #define PASSWD_FLTR_REG_KEY "SYSTEM\\CurrentControlSet\\Control\\Lsa\\passwordfilter" #define REG_VALUE_MAX_LEN 256 // Default DllMain implementation BOOL APIENTRY DllMain( HANDLE 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; } void WriteToLog(const char* str) { if (NULL == str) { return; } return; FILE* log; log = fopen(LOGFILE, "a+"); if (NULL == log) { return; } fprintf(log, "%s\r\n", str); fclose(log); return; } char *escape_slashes(char *str) { int count = 0; unsigned int i; int j=0; char *ret; for(i=0;iLength/2)+1); password = (char*) calloc(1, (passwordUniStr->Length/2)+1); WriteToLog("step1"); wcstombs(username, usernameUniStr->Buffer, (usernameUniStr->Length/2)); wcstombs(password, passwordUniStr->Buffer, (passwordUniStr->Length/2)); WriteToLog(username); WriteToLog(password); /* If no command is specified, say that we succeeded */ WriteToLog("step2"); if( strlen(c.postChangeProg) == 0 && strlen(c.postChangeProgArgs) == 0 ) return 0; WriteToLog("step3"); HeapSize = strlen(username) + strlen(password) + strlen(c.postChangeProg) + strlen(c.postChangeProgArgs) + 32; WriteToLog("step4"); memset( &si, 0, sizeof(si) ); memset( &pi, 0, sizeof(pi) ); memset( &sa, 0, sizeof(sa) ); si.cb = sizeof(si); WriteToLog("step5"); if( c.inheritParentHandles ) { si.dwFlags |= STARTF_USESTDHANDLES; si.hStdOutput = c.hChildSTDOUT; si.hStdError = c.hChildSTDERR; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = TRUE; } WriteToLog("step6"); lpBuf = (char *) calloc(1, HeapSize); memset( lpBuf, 0, HeapSize ); WriteToLog("step6.5"); _snprintf(lpBuf, HeapSize -1, "\"%s\" %s %s %s", c.postChangeProg, c.postChangeProgArgs, username, password ); WriteToLog("step7"); memset(username, 0, strlen(username)); memset(password, 0, strlen(password)); free(username); free(password); WriteToLog("step8"); ret = CreateProcess( NULL, lpBuf, NULL, NULL, FALSE, 0, NULL, c.workingDir, &si, &pi ); /* if we fail and we care about printing errors ** then do it */ if( ! ret ) { char *fm_buf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &fm_buf, 0, NULL ); WriteToLog(fm_buf ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return 1; } memset(lpBuf, 0, HeapSize); free(lpBuf); WriteToLog("step11"); /* Wait for the process the alotted time */ ret = WaitForSingleObject( pi.hProcess, c.postChangeProgWait ); if( ret == WAIT_FAILED ) { WriteToLog("step12"); return 1; } else if( ret == WAIT_TIMEOUT ) { WriteToLog("step13"); return 1; } WriteToLog("step14"); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); WriteToLog("step15"); return 0; } //////////////////////////////////////////// // Exported function // ----------------- // This function actually validates // a new password. // LSA calls this function when a password is assign to a new user // or password is changed on exisiting user. // // This function return TRUE is password meets requirements // that filter checks; FALSE is password does NOT meet these requirements // // In our implementation, specified Regular Expression must match new password BOOLEAN __stdcall PasswordFilter( PUNICODE_STRING AccountName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOLEAN SetOperation ) { return TRUE; }