📄 ntlm.cxx
字号:
//+--------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File: ntlm.cxx
//
// Contents: main entrypoints for the ntlm security package
// SpLsaModeInitialize
// SpInitialize
// SpShutdown
// SpGetInfo
//
// Helper functions:
// NtLmSetPolicyInfo
// NtLmPolicyChangeCallback
// NtLmRegisterForPolicyChange
// NtLmUnregisterForPolicyChange
//
// History: ChandanS 26-Jul-1996 Stolen from kerberos\client2\kerberos.cxx
// ChandanS 16-Apr-1998 No reboot on domain name change
//
//---------------------------------------------------------------------
// Variables with the EXTERN storage class are declared here
#define NTLM_GLOBAL
#define DEBUG_ALLOCATE
#include <global.h>
// BUGBUG Should be in the SDK?
#define MSV1_0_PACKAGE_NAMEW L"MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"
BOOLEAN NtLmCredentialInitialized;
BOOLEAN NtLmContextInitialized;
BOOLEAN NtLmRNGInitialized;
//+--------------------------------------------------------------------
//
// Function: SpLsaModeInitialize
//
// Synopsis: This function is called by the LSA when this DLL is loaded.
// It returns security package function tables for all
// security packages in the DLL.
//
// Arguments: LsaVersion - Version number of the LSA
// PackageVersion - Returns version number of the package
// Tables - Returns array of function tables for the package
// TableCount - Returns number of entries in array of
// function tables.
//
// Returns: PackageVersion (as above)
// Tables (as above)
// TableCount (as above)
//
// Notes:
//
//---------------------------------------------------------------------
NTSTATUS NTAPI
SpLsaModeInitialize(
IN ULONG LsaVersion,
OUT PULONG PackageVersion,
OUT PSECPKG_FUNCTION_TABLE * Tables,
OUT PULONG TableCount
)
{
#if DBG
// SspGlobalDbflag = SSP_CRITICAL| SSP_API| SSP_API_MORE |SSP_INIT| SSP_MISC | SSP_NO_LOCAL;
SspGlobalDbflag = SSP_CRITICAL ;
InitializeCriticalSection(&SspGlobalLogFileCritSect);
#endif
SspPrint((SSP_API, "Entering SpLsaModeInitialize\n"));
SECURITY_STATUS Status = SEC_E_OK;
if (LsaVersion != SECPKG_INTERFACE_VERSION)
{
SspPrint((SSP_CRITICAL, "Invalid LSA version: %d\n", LsaVersion));
Status = STATUS_INVALID_PARAMETER;
goto CleanUp;
}
NtLmFunctionTable.InitializePackage = NULL;
NtLmFunctionTable.LogonUser = NULL;
NtLmFunctionTable.CallPackage = LsaApCallPackage;
NtLmFunctionTable.LogonTerminated = LsaApLogonTerminated;
NtLmFunctionTable.CallPackageUntrusted = LsaApCallPackageUntrusted;
NtLmFunctionTable.LogonUserEx = NULL;
NtLmFunctionTable.LogonUserEx2 = LsaApLogonUserEx2;
NtLmFunctionTable.Initialize = SpInitialize;
NtLmFunctionTable.Shutdown = SpShutdown;
NtLmFunctionTable.GetInfo = SpGetInfo;
NtLmFunctionTable.AcceptCredentials = SpAcceptCredentials;
NtLmFunctionTable.AcquireCredentialsHandle = SpAcquireCredentialsHandle;
NtLmFunctionTable.FreeCredentialsHandle = SpFreeCredentialsHandle;
NtLmFunctionTable.SaveCredentials = SpSaveCredentials;
NtLmFunctionTable.GetCredentials = SpGetCredentials;
NtLmFunctionTable.DeleteCredentials = SpDeleteCredentials;
NtLmFunctionTable.InitLsaModeContext = SpInitLsaModeContext;
NtLmFunctionTable.AcceptLsaModeContext = SpAcceptLsaModeContext;
NtLmFunctionTable.DeleteContext = SpDeleteContext;
NtLmFunctionTable.ApplyControlToken = SpApplyControlToken;
NtLmFunctionTable.GetUserInfo = SpGetUserInfo;
NtLmFunctionTable.QueryCredentialsAttributes = SpQueryCredentialsAttributes ;
NtLmFunctionTable.GetExtendedInformation = SpGetExtendedInformation ;
NtLmFunctionTable.SetExtendedInformation = SpSetExtendedInformation ;
NtLmFunctionTable.CallPackagePassthrough = LsaApCallPackagePassthrough;
*PackageVersion = SECPKG_INTERFACE_VERSION;
*Tables = &NtLmFunctionTable;
*TableCount = 1;
CleanUp:
SspPrint((SSP_API, "Leaving SpLsaModeInitialize\n"));
return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}
//+-------------------------------------------------------------------------
//
// Function: NtLmSetPolicyInfo
//
// Synopsis: Function to be called when policy changes
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
// if fInit is TRUE, this is called by the init routine in ntlm
//
//
//+-------------------------------------------------------------------------
NTSTATUS
NtLmSetPolicyInfo(
IN PUNICODE_STRING DnsComputerName,
IN PUNICODE_STRING ComputerName,
IN PUNICODE_STRING DnsDomainName,
IN PUNICODE_STRING DomainName,
IN PSID DomainSid,
IN POLICY_NOTIFICATION_INFORMATION_CLASS ChangedInfoClass,
IN BOOLEAN fInit
)
{
NTSTATUS Status = STATUS_SUCCESS;
// Buffers to delete on cleanup
CHAR *ComputerNameAnsi = NULL;
CHAR *DomainNameAnsi = NULL;
//
// Do this only if this is package init
//
EnterCriticalSection(&NtLmGlobalCritSect);
if (fInit)
{
if (ComputerName && ComputerName->Buffer != NULL)
{
ULONG cLength = ComputerName->Length / sizeof(WCHAR);
if ((ComputerName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeComputerName))
{
// Bad ComputerName
Status = STATUS_INVALID_COMPUTER_NAME;
SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad computer name length is %d\n", cLength));
goto CleanUp;
}
wcsncpy(NtLmGlobalUnicodeComputerName,
ComputerName->Buffer,
cLength);
NtLmGlobalUnicodeComputerName[cLength] = UNICODE_NULL;
// make NtlmGlobalUnicodeComputerNameString a string form
RtlInitUnicodeString( &NtLmGlobalUnicodeComputerNameString,
NtLmGlobalUnicodeComputerName );
// Save old buffers for deleting
ComputerNameAnsi = NtLmGlobalOemComputerNameString.Buffer;
Status = RtlUpcaseUnicodeStringToOemString(
&NtLmGlobalOemComputerNameString,
&NtLmGlobalUnicodeComputerNameString,
TRUE );
if ( !NT_SUCCESS(Status) ) {
Status = STATUS_SUCCESS;
//SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from RtlUpcaseUnicodeStringToOemString is %d\n", Status));
ComputerNameAnsi = NULL;
// goto CleanUp;
}
}
}
//
// Initialize various forms of the primary domain name of the local system
// Do this only if this is package init or it's DnsDomain info
//
if (fInit || (ChangedInfoClass == PolicyNotifyDnsDomainInformation))
{
if (DnsComputerName && DnsComputerName->Buffer != NULL ) {
ULONG cLength = DnsComputerName->Length / sizeof(WCHAR);
if((DnsComputerName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeDnsComputerName))
{
// Bad ComputerName
Status = STATUS_INVALID_COMPUTER_NAME;
SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad computer name length is %d\n", cLength));
goto CleanUp;
}
wcsncpy(NtLmGlobalUnicodeDnsComputerName,
DnsComputerName->Buffer,
cLength);
NtLmGlobalUnicodeDnsComputerName[cLength] = UNICODE_NULL;
// make NtlmGlobalUnicodeDnsComputerNameString a string form
RtlInitUnicodeString( &NtLmGlobalUnicodeDnsComputerNameString,
NtLmGlobalUnicodeDnsComputerName );
}
if (DnsDomainName && DnsDomainName->Buffer != NULL ) {
ULONG cLength = DnsDomainName->Length / sizeof(WCHAR);
if((DnsDomainName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodeDnsDomainName))
{
// Bad ComputerName
Status = STATUS_INVALID_COMPUTER_NAME;
SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad domain name length is %d\n", cLength));
goto CleanUp;
}
wcsncpy(NtLmGlobalUnicodeDnsDomainName,
DnsDomainName->Buffer,
cLength);
NtLmGlobalUnicodeDnsDomainName[cLength] = UNICODE_NULL;
// make NtlmGlobalUnicodeDnsDomainNameString a string form
RtlInitUnicodeString( &NtLmGlobalUnicodeDnsDomainNameString,
NtLmGlobalUnicodeDnsDomainName );
}
if (DomainName && DomainName->Buffer != NULL)
{
ULONG cLength = DomainName->Length / sizeof(WCHAR);
if ((DomainName->Length + sizeof(WCHAR)) > sizeof(NtLmGlobalUnicodePrimaryDomainName))
{
Status = STATUS_NAME_TOO_LONG;
SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Bad domain name length is %d\n", cLength));
goto CleanUp;
}
wcsncpy(NtLmGlobalUnicodePrimaryDomainName,
DomainName->Buffer,
cLength);
NtLmGlobalUnicodePrimaryDomainName[cLength] = UNICODE_NULL;
// make NtlmGlobalUnicodePrimaryDomainNameString a string form
RtlInitUnicodeString( &NtLmGlobalUnicodePrimaryDomainNameString,
NtLmGlobalUnicodePrimaryDomainName );
// Save old buffers for deleting
DomainNameAnsi = NtLmGlobalOemPrimaryDomainNameString.Buffer;
Status = RtlUpcaseUnicodeStringToOemString(
&NtLmGlobalOemPrimaryDomainNameString,
&NtLmGlobalUnicodePrimaryDomainNameString,
TRUE );
if ( !NT_SUCCESS(Status) ) {
// SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from RtlUpcaseUnicodeStringToOemString is %d\n", Status));
DomainNameAnsi = NULL;
// goto CleanUp;
Status = STATUS_SUCCESS;
}
}
}
//
// If this is a standalone windows NT workstation,
// use the computer name as the Target name.
//
if ( DomainSid != NULL)
{
NtLmGlobalUnicodeTargetName = NtLmGlobalUnicodePrimaryDomainNameString;
NtLmGlobalOemTargetName = NtLmGlobalOemPrimaryDomainNameString;
NtLmGlobalTargetFlags = NTLMSSP_TARGET_TYPE_DOMAIN;
}
else
{
NtLmGlobalUnicodeTargetName = NtLmGlobalUnicodeComputerNameString;
NtLmGlobalOemTargetName = NtLmGlobalOemComputerNameString;
NtLmGlobalTargetFlags = NTLMSSP_TARGET_TYPE_SERVER;
}
//
// initialize the GlobalNtlm3 targetinfo.
//
{
PMSV1_0_AV_PAIR pAV;
PUNICODE_STRING pDnsTargetName;
PUNICODE_STRING pDnsComputerName;
ULONG cbAV;
if( NtLmGlobalNtLm3TargetInfo.Buffer != NULL )
{
NtLmFree(NtLmGlobalNtLm3TargetInfo.Buffer);
}
if( NtLmGlobalTargetFlags == NTLMSSP_TARGET_TYPE_DOMAIN ) {
pDnsTargetName = &NtLmGlobalUnicodeDnsDomainNameString;
} else {
pDnsTargetName = &NtLmGlobalUnicodeDnsComputerNameString;
}
pDnsComputerName = &NtLmGlobalUnicodeDnsComputerNameString;
cbAV = NtLmGlobalUnicodeTargetName.Length +
NtLmGlobalUnicodeComputerNameString.Length +
pDnsComputerName->Length +
pDnsTargetName->Length +
64 ;
NtLmGlobalNtLm3TargetInfo.Buffer = (PWSTR)NtLmAllocate( cbAV );
if( NtLmGlobalNtLm3TargetInfo.Buffer == NULL )
{
Status = STATUS_INSUFFICIENT_RESOURCES;
SspPrint((SSP_CRITICAL, "NtLmSetPolicyInfo, Error from NtLmAllocate\n"));
goto CleanUp;
}
pAV = MsvpAvlInit( NtLmGlobalNtLm3TargetInfo.Buffer );
MsvpAvlAdd( pAV, MsvAvNbDomainName, &NtLmGlobalUnicodeTargetName, cbAV );
MsvpAvlAdd( pAV, MsvAvNbComputerName, &NtLmGlobalUnicodeComputerNameString, cbAV );
if( pDnsTargetName->Length != 0 && pDnsTargetName->Buffer != NULL )
MsvpAvlAdd( pAV, MsvAvDnsDomainName, pDnsTargetName, cbAV );
if( pDnsComputerName->Length != 0 && pDnsComputerName->Buffer != NULL )
MsvpAvlAdd( pAV, MsvAvDnsComputerName, &NtLmGlobalUnicodeDnsComputerNameString, cbAV );
NtLmGlobalNtLm3TargetInfo.Length = (USHORT)MsvpAvlLen( pAV, cbAV );
}
CleanUp:
LeaveCriticalSection(&NtLmGlobalCritSect);
if (ComputerNameAnsi)
{
NtLmFree(ComputerNameAnsi);
}
if (DomainNameAnsi)
{
NtLmFree(DomainNameAnsi);
}
return Status;
}
//+-------------------------------------------------------------------------
//
// Function: NtLmPolicyChangeCallback
//
// Synopsis: Function to be called when domain policy changes
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -