📄 subauth.c
字号:
/*++
Copyright (c) 1987-1994 Microsoft Corporation
Module Name:
subauth.c
Abstract:
Interface to SubAuthentication Package.
Author:
Cliff Van Dyke (cliffv) 23-May-1994
Environment:
User mode only.
Contains NT-specific code.
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
Chandana Surlu 21-Jul-96 Stolen from \\kernel\razzle3\src\security\msv1_0\subauth.c
--*/
#include "msp.h"
#include "nlp.h"
#include <winreg.h>
#include <kerberos.h>
//
// Prototype for subauthentication routines.
//
// the pre NT 5.0 Subauth routine
typedef NTSTATUS
(*PSUBAUTHENTICATION_ROUTINE)(
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
IN PVOID LogonInformation,
IN ULONG Flags,
IN PUSER_ALL_INFORMATION UserAll,
OUT PULONG WhichFields,
OUT PULONG UserFlags,
OUT PBOOLEAN Authoritative,
OUT PLARGE_INTEGER LogoffTime,
OUT PLARGE_INTEGER KickoffTime
);
// the NT 5.0 Subauth routine
typedef NTSTATUS
(*PSUBAUTHENTICATION_ROUTINEEX)(
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
IN PVOID LogonInformation,
IN ULONG Flags,
IN PUSER_ALL_INFORMATION UserAll,
IN SAM_HANDLE UserHandle,
IN OUT PMSV1_0_VALIDATION_INFO ValidationInfo,
OUT PULONG ActionsPerfomed
);
// the NT 5.0 Generic Subauth routine
typedef NTSTATUS
(*PSUBAUTHENTICATION_ROUTINEGENERIC)(
IN PVOID SubmitBuffer,
IN ULONG SubmitBufferLength,
OUT PULONG ReturnBufferLength,
OUT PVOID *ReturnBuffer
);
typedef enum _SUBAUTH_TYPE {
SubAuth = 1, // Pre NT 5.0 subAuth called using LogonUser
SubAuthEx, // NT 5.0 subAuth called during LogonUser
SubAuthGeneric // NT 5.0 subAuth called during LaCallAuthenticationPackage
} SUBAUTH_TYPE;
//
// Structure describing a loaded SubAuthentication DLL.
//
typedef struct _SUBAUTHENTICATION_DLL {
LIST_ENTRY Next;
ULONG DllNumber;
PSUBAUTHENTICATION_ROUTINE SubAuthenticationRoutine;
PSUBAUTHENTICATION_ROUTINEEX SubAuthenticationRoutineEx;
PSUBAUTHENTICATION_ROUTINEGENERIC SubAuthenticationRoutineGeneric;
} SUBAUTHENTICATION_DLL, *PSUBAUTHENTICATION_DLL;
//
// Global list of all loaded subauthentication DLLs
//
LIST_ENTRY SubAuthenticationDlls;
CRITICAL_SECTION SubAuthenticationCritSect;
VOID
Msv1_0SubAuthenticationInitialization(
VOID
)
/*++
Routine Description:
Initialization routine for this source file.
Arguments:
None.
Return Value:
None.
--*/
{
InitializeCriticalSection( &SubAuthenticationCritSect );
InitializeListHead( &SubAuthenticationDlls );
}
PSUBAUTHENTICATION_DLL ReferenceSubAuth (
IN ULONG DllNumber,
OUT PNTSTATUS SubStatus)
{
LONG RegStatus;
PSUBAUTHENTICATION_DLL SubAuthenticationDll = NULL;
HKEY ParmHandle = NULL;
HINSTANCE DllHandle = NULL;
CHAR ValueName[sizeof(MSV1_0_SUBAUTHENTICATION_VALUE)+3];
CHAR DllName[MAXIMUM_FILENAME_LENGTH+1];
DWORD DllNameSize;
DWORD DllNameType;
PSUBAUTHENTICATION_ROUTINE SubAuthenticationRoutine = NULL;
PSUBAUTHENTICATION_ROUTINEEX SubAuthenticationRoutineEx = NULL;
PSUBAUTHENTICATION_ROUTINEGENERIC SubAuthenticationRoutineGeneric = NULL;
PLIST_ENTRY ListEntry;
*SubStatus = STATUS_SUCCESS;
DllName[0] = 0;
// See if the SubAuthentication Dll is already loaded.
//
for ( ListEntry = SubAuthenticationDlls.Flink ;
ListEntry != &SubAuthenticationDlls ;
ListEntry = ListEntry->Flink) {
SubAuthenticationDll = CONTAINING_RECORD( ListEntry,
SUBAUTHENTICATION_DLL,
Next );
if ( SubAuthenticationDll->DllNumber == DllNumber ) {
break;
}
SubAuthenticationDll = NULL;
}
//
// If the Dll is not already loaded,
// load it.
//
if ( SubAuthenticationDll == NULL ) {
//
// Build the name of the registry value.
//
RtlCopyMemory( ValueName,
MSV1_0_SUBAUTHENTICATION_VALUE,
sizeof(MSV1_0_SUBAUTHENTICATION_VALUE) );
*SubStatus = RtlIntegerToChar(
DllNumber & KERB_SUBAUTHENTICATION_MASK,
10, // Base
4, // Length of buffer
&ValueName[sizeof(MSV1_0_SUBAUTHENTICATION_VALUE)-1] );
if ( !NT_SUCCESS(*SubStatus) ) {
goto Cleanup;
}
//
// Open the MSV1_0_SUBAUTHENTICATION_KEY registry key.
//
if ((DllNumber & KERB_SUBAUTHENTICATION_FLAG) == 0) {
RegStatus = RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
MSV1_0_SUBAUTHENTICATION_KEY,
0, //Reserved
KEY_QUERY_VALUE,
&ParmHandle );
} else {
RegStatus = RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
KERB_SUBAUTHENTICATION_KEY,
0, //Reserved
KEY_QUERY_VALUE,
&ParmHandle );
}
if ( RegStatus != ERROR_SUCCESS ) {
KdPrint(( "MSV1_0: Cannot open registry key %s %ld.\n",
MSV1_0_SUBAUTHENTICATION_KEY,
RegStatus ));
}
else
{
//
// Get the registry value.
//
DllNameSize = sizeof(DllName);
RegStatus = RegQueryValueExA(
ParmHandle,
ValueName,
NULL, // Reserved
&DllNameType,
DllName,
&DllNameSize );
if ( RegStatus != ERROR_SUCCESS ) {
KdPrint(( "MSV1_0: Cannot query registry value %s %ld, don't panic.\n",
ValueName,
RegStatus ));
}
else
{
if ( DllNameType != REG_SZ ) {
KdPrint(( "MSV1_0: Registry value %s isn't REG_SZ.\n",
ValueName ));
*SubStatus = STATUS_DLL_NOT_FOUND;
goto Cleanup;
}
//
// Load the DLL
//
DllHandle = LoadLibraryA( DllName );
if ( DllHandle == NULL ) {
KdPrint(( "MSV1_0: Cannot load dll %s %ld.\n",
DllName,
GetLastError() ));
*SubStatus = STATUS_DLL_NOT_FOUND;
goto Cleanup;
}
//
// Find the SubAuthenticationRoutine. For packages other than
// zero, this will be Msv1_0SubauthenticationRoutine. For packge
// zero it will be Msv1_0SubauthenticationFilter.
//
if ((DllNumber & KERB_SUBAUTHENTICATION_MASK) == 0)
{
SubAuthenticationRoutine = (PSUBAUTHENTICATION_ROUTINE)
GetProcAddress(DllHandle, "Msv1_0SubAuthenticationFilter");
}
else
{
SubAuthenticationRoutine = (PSUBAUTHENTICATION_ROUTINE)
GetProcAddress(DllHandle, "Msv1_0SubAuthenticationRoutine");
}
//
// Find the SubAuthenticationRoutine
//
SubAuthenticationRoutineEx = (PSUBAUTHENTICATION_ROUTINEEX)
GetProcAddress(DllHandle, "Msv1_0SubAuthenticationRoutineEx");
//
// Find the SubAuthenticationRoutineGeneric
//
SubAuthenticationRoutineGeneric = (PSUBAUTHENTICATION_ROUTINEGENERIC)
GetProcAddress(DllHandle, "Msv1_0SubAuthenticationRoutineGeneric");
}
}
//
// If we didn't find the DLL or any routines, bail out now.
//
if ((DllHandle == NULL) ||
((SubAuthenticationRoutine == NULL) &&
(SubAuthenticationRoutineEx == NULL) &&
(SubAuthenticationRoutineGeneric == NULL))) {
KdPrint(( "MSV1_0: Cannot find any of the subauth entry points in %s %ld.\n",
DllName,
GetLastError() ));
*SubStatus = STATUS_PROCEDURE_NOT_FOUND;
goto Cleanup;
}
//
// Cache the address of the procedure.
//
SubAuthenticationDll =
RtlAllocateHeap(MspHeap, 0, sizeof(SUBAUTHENTICATION_DLL));
if ( SubAuthenticationDll == NULL ) {
*SubStatus = STATUS_NO_MEMORY;
goto Cleanup;
}
SubAuthenticationDll->DllNumber = DllNumber;
SubAuthenticationDll->SubAuthenticationRoutine = SubAuthenticationRoutine;
SubAuthenticationDll->SubAuthenticationRoutineEx = SubAuthenticationRoutineEx;
SubAuthenticationDll->SubAuthenticationRoutineGeneric = SubAuthenticationRoutineGeneric;
InsertHeadList( &SubAuthenticationDlls, &SubAuthenticationDll->Next );
DllHandle = NULL;
}
//
// Cleanup up before returning.
//
Cleanup:
if ( ParmHandle != NULL ) {
RegCloseKey( ParmHandle );
}
if ( !NT_SUCCESS( *SubStatus) ) {
if ( DllHandle != NULL ) {
FreeLibrary( DllHandle );
}
}
return SubAuthenticationDll;
}
BOOLEAN
Msv1_0SubAuthenticationPresent(
IN ULONG DllNumber
)
/*++
Routine Description:
Returns TRUE if there is a subauthentication package with the given number
Arguments:
DllNumber - the number of the DLL to check
Return Value:
TRUE if there is a subauthentication DLL, otherwise FALSE.
--*/
{
NTSTATUS SubStatus;
return(ReferenceSubAuth ( DllNumber, &SubStatus) != NULL);
}
NTSTATUS
Msv1_0SubAuthenticationRoutineZero(
IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
IN PVOID LogonInformation,
IN ULONG Flags,
IN PUSER_ALL_INFORMATION UserAll,
OUT PULONG WhichFields,
OUT PULONG UserFlags,
OUT PBOOLEAN Authoritative,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -