// -------------------------------------------------------------------------- // Module Name: BioLogon.cpp // // Copyright (c) 2001, Microsoft Corporation // // File that implements a publicly declared import that forwards to an // implementation in shgina.dll // // History: 2001-04-10 vtan created // -------------------------------------------------------------------------- #include #include #include #include #include #include HANDLE g_hLSA = NULL; // -------------------------------------------------------------------------- // CheckTCBPrivilege // // Arguments: // // Returns: BOOL // // Purpose: Returns whether the thread impersonation token or the process // level token has SE_TCB_PRIVILEGE. // // History: 2001-06-04 vtan created // -------------------------------------------------------------------------- BOOL CheckTCBPrivilege (void) { BOOL fResult; HANDLE hToken; fResult = FALSE; if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken) == FALSE) { if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == FALSE) { hToken = NULL; } } if (hToken != NULL) { DWORD dwReturnLength; dwReturnLength = 0; (BOOL)GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwReturnLength); if (dwReturnLength != 0) { TOKEN_PRIVILEGES *pTokenPrivileges; pTokenPrivileges = static_cast(LocalAlloc(LMEM_FIXED, dwReturnLength)); if (pTokenPrivileges != NULL) { if (GetTokenInformation(hToken, TokenPrivileges, pTokenPrivileges, dwReturnLength, &dwReturnLength) != FALSE) { bool fFound; DWORD dwIndex; LUID luidPrivilege; luidPrivilege.LowPart = SE_TCB_PRIVILEGE; luidPrivilege.HighPart = 0; for (fFound = false, dwIndex = 0; !fFound && (dwIndex < pTokenPrivileges->PrivilegeCount); ++dwIndex) { fFound = RtlEqualLuid(&pTokenPrivileges->Privileges[dwIndex].Luid, &luidPrivilege); } if (fFound) { fResult = TRUE; } else { SetLastError(ERROR_PRIVILEGE_NOT_HELD); } } (HLOCAL)LocalFree(pTokenPrivileges); } } (BOOL)CloseHandle(hToken); } return(fResult); } // -------------------------------------------------------------------------- // ::EnableBlankPasswords // // Arguments: // // Returns: BOOL // // Purpose: Uses the MSV1_0 package via LSA to enable blank passwords for // this process. // // History: 2001-06-04 vtan created // -------------------------------------------------------------------------- BOOL EnableBlankPasswords (void) { NTSTATUS status; if (g_hLSA == NULL) { LSA_OPERATIONAL_MODE LSAOperationalMode; STRING strLogonProcess; RtlInitString(&strLogonProcess, "BioLogon"); status = LsaRegisterLogonProcess(&strLogonProcess, &g_hLSA, &LSAOperationalMode); if (NT_SUCCESS(status)) { ULONG ulPackageID; STRING strMSVPackage; RtlInitString(&strMSVPackage, MSV1_0_PACKAGE_NAME); status = LsaLookupAuthenticationPackage(g_hLSA, &strMSVPackage, &ulPackageID); if (NT_SUCCESS(status)) { NTSTATUS statusProtocol; ULONG ulResponseSize; MSV1_0_SETPROCESSOPTION_REQUEST request; void* pResponse; ZeroMemory(&request, sizeof(request)); request.MessageType = MsV1_0SetProcessOption; request.ProcessOptions = MSV1_0_OPTION_ALLOW_BLANK_PASSWORD; request.DisableOptions = FALSE; status = LsaCallAuthenticationPackage(g_hLSA, ulPackageID, &request, sizeof(request), &pResponse, &ulResponseSize, &statusProtocol); if (NT_SUCCESS(status)) { status = statusProtocol; } } } if (!NT_SUCCESS(status)) { SetLastError(RtlNtStatusToDosError(status)); } } else { SetLastError(ERROR_ALREADY_INITIALIZED); status = STATUS_UNSUCCESSFUL; } return(NT_SUCCESS(status)); } // -------------------------------------------------------------------------- // ::InitializeBioLogon // // Arguments: // // Returns: BOOL // // Purpose: Initialize the biologon DLL. This call is required if you // want to be able to use blank passwords. This will check that // the caller has SE_TCB_PRIVILEGE. // // History: 2001-06-04 vtan created // -------------------------------------------------------------------------- EXTERN_C BOOL WINAPI InitializeBioLogon (void) { return(CheckTCBPrivilege() && EnableBlankPasswords()); } // -------------------------------------------------------------------------- // ::InitiateInteractiveLogonWithTimeout // // Arguments: pszUsername = User name. // pszPassword = Password. // dwTimeout = Time out in milliseconds. // // Returns: BOOL // // Purpose: External entry point function exported by name to initiate // an interactive logon with specified timeout. // // History: 2001-06-04 vtan created // -------------------------------------------------------------------------- EXTERN_C BOOL WINAPI InitiateInteractiveLogonWithTimeout (const WCHAR *pszUsername, WCHAR *pszPassword, DWORD dwTimeout) { typedef BOOL (WINAPI * PFNIIL) (const WCHAR *pszUsername, WCHAR *pszPassword, DWORD dwTimeout); BOOL fResult; static HMODULE s_hModule = reinterpret_cast(-1); static PFNIIL s_pfnIIL = NULL; if (s_hModule == reinterpret_cast(-1)) { s_hModule = LoadLibrary(TEXT("shgina.dll")); if (s_hModule != NULL) { s_pfnIIL = reinterpret_cast(GetProcAddress(s_hModule, MAKEINTRESOURCEA(6))); if (s_pfnIIL != NULL) { fResult = s_pfnIIL(pszUsername, pszPassword, dwTimeout); } else { fResult = FALSE; } } else { fResult = FALSE; } } else if (s_pfnIIL != NULL) { fResult = s_pfnIIL(pszUsername, pszPassword, dwTimeout); } else { fResult = FALSE; SetLastError(ERROR_CALL_NOT_IMPLEMENTED); } return(fResult); } // -------------------------------------------------------------------------- // ::InitiateInteractiveLogon // // Arguments: pszUsername = User name. // pszPassword = Password. // // Returns: BOOL // // Purpose: External entry point function exported by name to initiate // an interactive logon. This passes an INFINITE timeout. Use // this function with care. // // History: 2001-06-04 vtan created // -------------------------------------------------------------------------- EXTERN_C BOOL WINAPI InitiateInteractiveLogon (const WCHAR *pszUsername, WCHAR *pszPassword) { return(InitiateInteractiveLogonWithTimeout(pszUsername, pszPassword, INFINITE)); } // -------------------------------------------------------------------------- // ::DllMain // // Arguments: See the platform SDK under DllMain. // // Returns: BOOL // // Purpose: DllMain for the DLL. Recognizes only DLL_PROCESS_DETACH to do // some clean up. // // History: 2001-06-05 vtan created // -------------------------------------------------------------------------- EXTERN_C BOOL WINAPI DllMain (HINSTANCE hInstance, DWORD dwReason, void *pvReserved) { UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(pvReserved); switch (dwReason) { case DLL_PROCESS_DETACH: if (g_hLSA != NULL) { (BOOL)CloseHandle(g_hLSA); g_hLSA = NULL; } break; default: break; } return(TRUE); }