301 lines
9.3 KiB
C++
301 lines
9.3 KiB
C++
// --------------------------------------------------------------------------
|
|
// 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 <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntlsa.h>
|
|
#include <ntmsv1_0.h>
|
|
#include <windows.h>
|
|
|
|
HANDLE g_hLSA = NULL;
|
|
|
|
// --------------------------------------------------------------------------
|
|
// CheckTCBPrivilege
|
|
//
|
|
// Arguments: <none>
|
|
//
|
|
// 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<TOKEN_PRIVILEGES*>(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: <none>
|
|
//
|
|
// 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: <none>
|
|
//
|
|
// 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<HMODULE>(-1);
|
|
static PFNIIL s_pfnIIL = NULL;
|
|
|
|
if (s_hModule == reinterpret_cast<HMODULE>(-1))
|
|
{
|
|
s_hModule = LoadLibrary(TEXT("shgina.dll"));
|
|
if (s_hModule != NULL)
|
|
{
|
|
s_pfnIIL = reinterpret_cast<PFNIIL>(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);
|
|
}
|
|
|