|
|
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1991 - 1992
//
// File: sputil.c
//
// Contents: Security package utility functions. Functions for maintaining
// the list of available packages are kept here.
//
//
//
// History: 9 Dec 91, richardw Created
// 11 Mar 92, RichardW Recreated, reworked, etc.
// 21 Mar 94, MikeSw Removed RPC stubs
//
//------------------------------------------------------------------------
#include <lsapch.hxx>
extern "C" { #include "sesmgr.h"
#include <stddef.h>
}
//
// Global variables and structures:
//
//
// Debug stuff:
//
#if DBG
ULONG NoUnload = 0; #endif
extern WCHAR szLsaPath[] ;
RTL_RESOURCE PackageListLock;
PDLL_BINDING * pPackageDllList; ULONG PackageDllCount; ULONG PackageDllTotal; PLSAP_SECURITY_PACKAGE * pPackageControlList; ULONG PackageControlCount; ULONG PackageControlTotal;
#define INITIAL_PACKAGE_DLL_SIZE 8
#define INITIAL_PACKAGE_CONTROL_SIZE 8
#define ReadLockPackageList() RtlAcquireResourceShared(&PackageListLock, TRUE)
#define WriteLockPackageList() RtlAcquireResourceExclusive(&PackageListLock, TRUE)
#define UnlockPackageList() RtlReleaseResource(&PackageListLock)
PDLL_BINDING SpmpFindDll( PWSTR DllName);
//+---------------------------------------------------------------------------
//
// Function: BindOldPackage
//
// Synopsis: Loads an old style authentication package DLL
//
// Arguments: [hDll] --
// [pTable] --
//
// History: 11-17-95 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL BindOldPackage( HANDLE hDll, PSECPKG_FUNCTION_TABLE pTable) {
pTable->InitializePackage = (PLSA_AP_INITIALIZE_PACKAGE) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_INITIALIZE_PACKAGE);
if (pTable->InitializePackage == NULL) { return(FALSE); }
//
// The package needs to support one of LogonUser, LogonUserEx, or LogonUserEx2
pTable->LogonUserEx2 = (PLSA_AP_LOGON_USER_EX2) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER_EX2);
//
// If this is NULL, then the package should have exported a LsaApLogonUser or Ex
//
if (pTable->LogonUserEx2 == NULL) { pTable->LogonUserEx = (PLSA_AP_LOGON_USER_EX) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER_EX); if (pTable->LogonUserEx == NULL) { pTable->LogonUser = (PLSA_AP_LOGON_USER) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_USER); if (pTable->LogonUser == NULL) { return(FALSE); } } }
pTable->CallPackage = (PLSA_AP_CALL_PACKAGE) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE); if (pTable->CallPackage == NULL) { return(FALSE); }
//
// CallPackageUntrusted is optional
//
pTable->CallPackageUntrusted = (PLSA_AP_CALL_PACKAGE_UNTRUSTED) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE_UNTRUSTED);
pTable->CallPackagePassthrough = (PLSA_AP_CALL_PACKAGE_PASSTHROUGH) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_CALL_PACKAGE_PASSTHROUGH);
pTable->LogonTerminated = (PLSA_AP_LOGON_TERMINATED) GetProcAddress((HMODULE)hDll, LSA_AP_NAME_LOGON_TERMINATED); if (pTable->LogonTerminated == NULL) { return(FALSE); }
//
// If the package supports accept credentials, great. Otherwise
// just leave this blank.
//
pTable->AcceptCredentials = (SpAcceptCredentialsFn *) GetProcAddress((HMODULE) hDll, SP_ACCEPT_CREDENTIALS_NAME);
return(TRUE); }
//+-------------------------------------------------------------------------
//
// Function: WLsaEnumeratePackages()
//
// Synopsis: Worker function for LsaEnumeratePackages
//
// Effects: Fills in an array of SecPkgInfo structures
//
// Arguments: pcEntries - receives the number of packages
//
// pPackages - receives all the SecPkgInfo structures
//
// Requires:
//
// Returns: success
//
// Notes:
//
//--------------------------------------------------------------------------
static LPWSTR szInvalidPackage = L"Invalid Package";
NTSTATUS WLsaEnumeratePackages( PULONG pcEntries, PSecPkgInfo * pPackages) { unsigned int i; PSession pSession = GetCurrentSession(); ULONG cbSize; PSecPkgInfo pInfo; PSecPkgInfo pLocalInfo = NULL, pClientInfo = NULL; LONG cbMark, cbLength; NTSTATUS scRet; PLSAP_SECURITY_PACKAGE pPackage; PLSA_CALL_INFO CallInfo ; ULONG Filter ;
Filter = SP_ORDINAL_GETINFO ;
CallInfo = LsapGetCurrentCall();
if ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT ) { Filter |= SP_ITERATE_FILTER_WOW ; }
cbSize = sizeof(SecPkgInfo) * lsState.cPackages; pInfo = (PSecPkgInfo) LsapAllocateLsaHeap(cbSize);
if (!pInfo) { return(SEC_E_INSUFFICIENT_MEMORY); }
pPackage = SpmpIteratePackagesByRequest( NULL, Filter );
i = 0;
while (pPackage) { SetCurrentPackageId( pPackage->dwPackageID );
__try { (VOID) pPackage->FunctionTable.GetInfo( &pInfo[i] ); cbSize += (wcslen(pInfo[i].Name) + 1) * sizeof(WCHAR); cbSize += (wcslen(pInfo[i].Comment) + 1) * sizeof(WCHAR); } __except (SP_EXCEPTION) { SPException( GetExceptionCode(), pPackage->dwPackageID );
//
// Catch it, kill the package, proceed...
//
}
pPackage = SpmpIteratePackagesByRequest( pPackage, Filter ); i ++;
}
*pcEntries = i;
pLocalInfo = (PSecPkgInfo) LsapAllocateLsaHeap(cbSize); if (!pLocalInfo) { scRet = SEC_E_INSUFFICIENT_MEMORY; goto Cleanup; } pClientInfo = (PSecPkgInfo) LsapClientAllocate(cbSize); if (!pClientInfo) { scRet = SEC_E_INSUFFICIENT_MEMORY; goto Cleanup; }
//
// Compute the offset to adjust the pointers by
//
cbMark = *pcEntries * sizeof(SecPkgInfo);
RtlCopyMemory(pLocalInfo,pInfo,cbMark);
for (i = 0; i < *pcEntries ; i++ ) {
cbLength = (wcslen(pInfo[i].Name)+1)*sizeof(WCHAR); RtlCopyMemory( (PBYTE) pLocalInfo + cbMark, pInfo[i].Name, cbLength);
pLocalInfo[i].Name = (LPWSTR) ((PBYTE) pClientInfo + cbMark); cbMark += cbLength;
cbLength = (wcslen(pInfo[i].Comment)+1)*sizeof(WCHAR); RtlCopyMemory( (PBYTE) pLocalInfo + cbMark, pInfo[i].Comment, cbLength);
pLocalInfo[i].Comment = (LPWSTR) ((PBYTE) pClientInfo + cbMark); cbMark += cbLength;
}
SetCurrentPackageId( SPMGR_ID );
scRet = LsapCopyToClient(pLocalInfo,pClientInfo,cbSize);
if (SUCCEEDED(scRet)) { *pPackages = pClientInfo; }
Cleanup: if (pLocalInfo != NULL) { LsapFreeLsaHeap(pLocalInfo); } if (FAILED(scRet) && (pClientInfo != NULL)) { LsapClientFree(pClientInfo); } if (pInfo != NULL) { LsapFreeLsaHeap(pInfo); }
return(scRet); }
//+-------------------------------------------------------------------------
//
// Function: WLsaGetBinding()
//
// Synopsis: Gets the full path/DLL name for a package, based on ID
//
// Effects:
//
// Arguments: dwPackageID - ID of the package the caller needs the path for
// pssPackageName - returns the name of package caller
//
// pszModuleName - Receives the name of the package.
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
NTSTATUS WLsaGetBinding( ULONG_PTR dwPackageID, PSEC_PACKAGE_BINDING_INFO BindingInfo, PULONG TotalSize, PWSTR * Base) { PLSAP_SECURITY_PACKAGE pPackage; PWSTR Buffer; PLSA_CALL_INFO CallInfo ; PSECURITY_STRING DllPath ; SECURITY_STRING NullString = { 0 };
ZeroMemory( BindingInfo, sizeof( SEC_PACKAGE_BINDING_INFO ) );
pPackage = SpmpValidateHandle(dwPackageID);
CallInfo = LsapGetCurrentCall();
if ( (pPackage != NULL ) && ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT ) != 0 ) { //
// If this is a WOW client, only return bindings for the packages
// that support WOW clients.
//
if ( ( pPackage->fPackage & SP_WOW_SUPPORT ) == 0 ) { pPackage = NULL ; } }
if (pPackage) { //
// Easy stuff:
//
BindingInfo->fCapabilities = pPackage->fCapabilities; BindingInfo->PackageIndex = pPackage->PackageIndex ; BindingInfo->Version = pPackage->Version ; BindingInfo->RpcId = pPackage->dwRPCID ; BindingInfo->TokenSize = pPackage->TokenSize ;
if (pPackage->fPackage & SPM_AUTH_PKG_FLAG) { BindingInfo->Flags = PACKAGEINFO_AUTHPKG; //
// Old style package: no remote binding
//
return( SEC_E_INVALID_HANDLE ); }
DllPath = &pPackage->pBinding->Filename ;
if ( pPackage->pBinding->Flags & DLL_BUILTIN ) { BindingInfo->Flags = PACKAGEINFO_BUILTIN ; DllPath = &NullString ; }
if ( pPackage->pBinding->Flags & DLL_SIGNED ) { BindingInfo->Flags |= PACKAGEINFO_SIGNED ; }
if ( ( pPackage->fPackage & SP_WOW_SUPPORT ) && ( CallInfo->CallInfo.Attributes & SECPKG_CALL_WOWCLIENT ) ) { DllPath = &pPackage->WowClientDll ; }
//
// If context thunks are present, copy them in:
//
if ( pPackage->Thunks ) { BindingInfo->ContextThunksCount = pPackage->Thunks->Info.ContextThunks.InfoLevelCount ;
if ( pPackage->Thunks->Info.ContextThunks.InfoLevelCount < PACKAGEINFO_THUNKS ) {
CopyMemory( BindingInfo->ContextThunks, pPackage->Thunks->Info.ContextThunks.Levels, BindingInfo->ContextThunksCount * sizeof(DWORD) ); } else { CopyMemory( BindingInfo->ContextThunks, pPackage->Thunks->Info.ContextThunks.Levels, PACKAGEINFO_THUNKS * sizeof( DWORD ) );
} } else { BindingInfo->ContextThunksCount = 0 ; }
//
// Compute Sizes:
//
*TotalSize = pPackage->Name.Length + 2 + pPackage->Comment.Length + 2 + DllPath->Length + 2 ;
Buffer = (PWSTR) LsapAllocateLsaHeap( *TotalSize );
if ( !Buffer ) { return( SEC_E_INSUFFICIENT_MEMORY ); }
BindingInfo->PackageName.Buffer = Buffer ; BindingInfo->PackageName.Length = pPackage->Name.Length ; BindingInfo->PackageName.MaximumLength = pPackage->Name.Length + 2;
CopyMemory( BindingInfo->PackageName.Buffer, pPackage->Name.Buffer, BindingInfo->PackageName.MaximumLength );
BindingInfo->Comment.Buffer = BindingInfo->PackageName.Buffer + BindingInfo->PackageName.MaximumLength / 2 ;
BindingInfo->Comment.Length = pPackage->Comment.Length; BindingInfo->Comment.MaximumLength = BindingInfo->Comment.Length + 2;
CopyMemory( BindingInfo->Comment.Buffer, pPackage->Comment.Buffer, BindingInfo->Comment.MaximumLength );
if ( DllPath->Buffer ) { BindingInfo->ModuleName.Buffer = BindingInfo->Comment.Buffer + BindingInfo->Comment.MaximumLength / 2;
BindingInfo->ModuleName.Length = DllPath->Length; BindingInfo->ModuleName.MaximumLength = BindingInfo->ModuleName.Length + 2;
CopyMemory( BindingInfo->ModuleName.Buffer, DllPath->Buffer, BindingInfo->ModuleName.MaximumLength );
}
*Base = Buffer ;
return( SEC_E_OK ); }
return( SEC_E_INVALID_HANDLE );
}
//+---------------------------------------------------------------------------
//
// Function: LsapFindPackage
//
// Synopsis: Internal function for the security DLL to reference packages
// by ID
//
// Arguments: [pPackage] -- name of package
// [pdwPackageId] -- returned id
//
// Returns: STATUS_SUCCESS -- Package found
// SEC_E_SECPKG_NOT_FOUND -- Package not found
//
// History: 5-26-93 RichardW Created
//
//----------------------------------------------------------------------------
NTSTATUS WLsaFindPackage(PUNICODE_STRING pPackageName, ULONG_PTR * pdwPackageId) { PLSAP_SECURITY_PACKAGE pPackage;
pPackage = SpmpLookupPackage(pPackageName); if (!pPackage) { *pdwPackageId = SPMGR_ID; return(SEC_E_SECPKG_NOT_FOUND); } else { *pdwPackageId = pPackage->dwPackageID; return(S_OK); } }
//+---------------------------------------------------------------------------
//
// Function: WLsaAddPackage
//
// Synopsis: Adds a security package to the system
//
// Arguments: [PackageName] -- Package Name
// [Options] -- Options
//
// History: 9-18-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS WLsaAddPackage( PSECURITY_STRING PackageName, PSECURITY_PACKAGE_OPTIONS Options) {
SECPKG_PARAMETERS Parameters; PLSAP_SECURITY_PACKAGE Package; SECPKG_EVENT_PACKAGE_CHANGE Event; BOOL Success; SECURITY_STATUS scRet; PLSAPR_POLICY_DNS_DOMAIN_INFO DnsDomainInfo = NULL; HKEY hKey ;
DebugLog(( DEB_TRACE, "Adding Package %ws\n", PackageName->Buffer ));
//
// Make sure the caller has the rights to do this by impersonating them,
// then opening the registry key.
//
scRet = LsapImpersonateClient();
if ( NT_SUCCESS( scRet ) ) { int err ;
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szLsaPath, 0, KEY_READ | KEY_WRITE, &hKey );
if ( err != 0 ) { scRet = NtCurrentTeb()->LastStatusValue ; } else { RegCloseKey( hKey ); }
RevertToSelf(); }
if ( !NT_SUCCESS( scRet ) ) { return scRet ; }
//
// Build up the initialization message, to give the packages a better idea
// of what is going on, and reduce their later calls for the same info.
//
Parameters.MachineState = (ULONG) 0; Parameters.SetupMode = SetupPhase;
//
// Make sure we haven't been through this already:
//
if ( SpmpFindDll( PackageName->Buffer ) ) { DebugLog(( DEB_TRACE, "AddPackage: DLL %ws already loaded\n", PackageName->Buffer )); return STATUS_SUCCESS ; }
scRet = LsaIQueryInformationPolicyTrusted( PolicyDnsDomainInformation, (PLSAPR_POLICY_INFORMATION *) &DnsDomainInfo );
if (!NT_SUCCESS(scRet)) { DebugLog((DEB_ERROR,"Failed to get primary domain info: 0x%x\n",scRet)); return(scRet); }
Parameters.DomainName = * (PUNICODE_STRING) &DnsDomainInfo->Name; Parameters.DnsDomainName = * (PUNICODE_STRING) &DnsDomainInfo->DnsDomainName; Parameters.DomainSid = (PSID) DnsDomainInfo->Sid;
DebugLog((DEB_TRACE_INIT, "Init Parameters = %d, %s\n", Parameters.MachineState, (Parameters.SetupMode ? "Setup" : "Normal") ));
if (SpmpLoadDll( PackageName->Buffer, &Parameters )) { //
// Successful Load! Update the registry!
//
if ( Options->Flags & SECPKG_OPTIONS_PERMANENT ) { Success = AddPackageToRegistry( PackageName ); } else { Success = TRUE ; }
if ( !Success ) { //
// Unload it!
//
} } else { Success = FALSE ; }
LsaIFree_LSAPR_POLICY_INFORMATION( PolicyDnsDomainInformation, (PLSAPR_POLICY_INFORMATION) DnsDomainInfo );
if ( Success ) { return( SEC_E_OK ); }
return( SEC_E_SECPKG_NOT_FOUND );
}
//+---------------------------------------------------------------------------
//
// Function: WLsaDeletePackage
//
// Synopsis: Delete a security package
//
// Arguments: [PackageName] --
//
// History: 9-18-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS WLsaDeletePackage( PSECURITY_STRING PackageName) { return( SEC_E_NOT_SUPPORTED ); }
//+-------------------------------------------------------------------------
//
// Function: SpmCreateEvent
//
// Synopsis: Just like the Win32 function, except that it allows
// for names at the root of the namespace.
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
HANDLE SpmCreateEvent( LPSECURITY_ATTRIBUTES lpsa, BOOL fManualReset, BOOL fInitialState, LPTSTR pszEventName) { HANDLE hEvent; OBJECT_ATTRIBUTES EventAttr; UNICODE_STRING usName; NTSTATUS Status; ULONG ulWin32Error;
RtlInitUnicodeString(&usName, pszEventName);
if (lpsa) { InitializeObjectAttributes(&EventAttr, &usName, (lpsa->bInheritHandle ? OBJ_INHERIT : 0), NULL, lpsa->lpSecurityDescriptor); } else { InitializeObjectAttributes(&EventAttr, &usName, 0, NULL, NULL); }
Status = NtCreateEvent( &hEvent, EVENT_ALL_ACCESS, &EventAttr, (fManualReset ? NotificationEvent : SynchronizationEvent), (BOOLEAN) fInitialState);
if (!NT_SUCCESS(Status)) { ulWin32Error = RtlNtStatusToDosError( Status ); SetLastError(ulWin32Error); return(NULL); } return(hEvent); }
//+-------------------------------------------------------------------------
//
// Function: SpmOpenEvent
//
// Synopsis: Just like Win32 OpenEvent, except that this supports \ in name
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
HANDLE SpmOpenEvent( ULONG fdwAccess, BOOL fInherit, LPTSTR pszEventName) { HANDLE hEvent; OBJECT_ATTRIBUTES EventAttr; UNICODE_STRING usName; NTSTATUS Status; ULONG ulWin32Error;
RtlInitUnicodeString(&usName, pszEventName);
InitializeObjectAttributes(&EventAttr, &usName, OBJ_CASE_INSENSITIVE | (fInherit ? OBJ_INHERIT : 0), NULL, NULL);
Status = NtOpenEvent( &hEvent, fdwAccess, &EventAttr);
if (!NT_SUCCESS(Status)) { ulWin32Error = RtlNtStatusToDosError( Status ); SetLastError(ulWin32Error); return(NULL); } return(hEvent);
}
////////////////////////////////////////////////////////////////////////////
//
//
// Package List Manipulation:
//
//
////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// Function: SpmpAddPackage
//
// Synopsis: Adds a package to the list.
//
// Arguments: [pPackage] -- Package to add
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
ULONG SpmpAddPackage( PLSAP_SECURITY_PACKAGE pPackage) { PLSAP_SECURITY_PACKAGE * pList; ULONG PackageId;
//
// Grab excluse access to the list:
//
WriteLockPackageList();
//
// If we don't have any left over space in the array, realloc it
//
if ( PackageControlCount == PackageControlTotal ) { pList = (PLSAP_SECURITY_PACKAGE *) LsapAllocateLsaHeap( sizeof(PLSAP_SECURITY_PACKAGE) * (PackageControlTotal + INITIAL_PACKAGE_CONTROL_SIZE)); if (!pList) { UnlockPackageList(); return( 0xFFFFFFFF ); }
CopyMemory( pList, pPackageControlList, sizeof( PLSAP_SECURITY_PACKAGE ) * PackageControlTotal );
PackageControlTotal += INITIAL_PACKAGE_CONTROL_SIZE;
LsapFreeLsaHeap( pPackageControlList );
pPackageControlList = pList; }
//
// Obtain a new package id (and slot)
//
PackageId = PackageControlCount++;
pPackageControlList[ PackageId ] = pPackage;
pPackage->pBinding->RefCount++;
pPackage->dwPackageID = PackageId;
UnlockPackageList();
return( PackageId ); }
//+---------------------------------------------------------------------------
//
// Function: SpmpRemovePackage
//
// Synopsis: Removes a package from the list
//
// Arguments: [PackageId] --
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID SpmpRemovePackage( ULONG PackageId) { WriteLockPackageList();
pPackageControlList[ PackageId ] = NULL;
//
// If the counter hasn't moved on, reclaim the index
//
if (PackageId == PackageControlCount - 1) { PackageControlCount--; }
UnlockPackageList();
}
//+---------------------------------------------------------------------------
//
// Function: SpmpAddDll
//
// Synopsis: Add a DLL binding
//
// Arguments: [pBinding] --
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpAddDll( PDLL_BINDING pBinding) { PDLL_BINDING * pList; ULONG DllId;
WriteLockPackageList();
if ( PackageDllCount == PackageDllTotal ) { pList = (PDLL_BINDING *) LsapAllocateLsaHeap( sizeof(PDLL_BINDING) * (PackageDllTotal + INITIAL_PACKAGE_DLL_SIZE)); if (!pList) { UnlockPackageList(); return( FALSE ); }
CopyMemory( pList, pPackageDllList, sizeof( PDLL_BINDING ) * PackageDllTotal );
PackageDllTotal += INITIAL_PACKAGE_DLL_SIZE;
LsapFreeLsaHeap( pPackageDllList );
pPackageDllList = pList; }
pPackageDllList[ PackageDllCount++ ] = pBinding;
UnlockPackageList();
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpRemoveDll
//
// Synopsis: Removes a DLL binding
//
// Arguments: [pBinding] --
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID SpmpRemoveDll( PDLL_BINDING pBinding) { ULONG i;
WriteLockPackageList();
if (pPackageDllList[PackageDllCount - 1] == pBinding ) { PackageDllCount --;
pPackageDllList[ PackageDllCount ] = NULL; } else {
for (i = 0; i < PackageDllCount ; i++ ) { if (pPackageDllList[ i ] == pBinding) { pPackageDllList[ i ] = NULL; break; } } }
UnlockPackageList();
}
//+---------------------------------------------------------------------------
//
// Function: SpmpFindDll
//
// Synopsis: Searches set of DLLs already loaded for a DLL name
//
// Arguments: [DllName] -- absolute or relative path name
//
// History: 9-20-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PDLL_BINDING SpmpFindDll( PWSTR DllName) { WCHAR DllPath[ MAX_PATH ]; PWSTR FilePart; DWORD Length; UNICODE_STRING Search; PDLL_BINDING pBinding; DWORD i;
pBinding = NULL ;
Length = SearchPath(NULL, DllName, TEXT(".DLL"), MAX_PATH, DllPath, &FilePart );
if ( Length ) { //
// Name hit, see if we've loaded it already:
//
Search.Buffer = DllPath; Search.Length = (USHORT) (Length * sizeof( WCHAR )); Search.MaximumLength = Search.Length + sizeof( WCHAR ) ;
ReadLockPackageList();
for ( i = 0 ; i < PackageDllCount ; i++ ) { if ( RtlEqualUnicodeString( &Search, &(pPackageDllList[i]->Filename), TRUE) ) { pBinding = pPackageDllList[ i ]; break; } }
UnlockPackageList();
}
return( pBinding );
}
//+---------------------------------------------------------------------------
//
// Function: LsapGetExtendedPackageInfo
//
// Synopsis: Wrapper to get extended information from a package
//
// Arguments: [Package] -- Package to query
// [Class] -- Information class
// [Info] -- returned data
//
// History: 3-04-97 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS LsapGetExtendedPackageInfo( PLSAP_SECURITY_PACKAGE Package, SECPKG_EXTENDED_INFORMATION_CLASS Class, PSECPKG_EXTENDED_INFORMATION * Info ) { NTSTATUS Status ;
if ( (Package->fPackage & SP_INFO) == 0 ) { return SEC_E_NOT_SUPPORTED ; }
DebugLog(( DEB_TRACE, "Getting extended information (%d) from %ws\n", Class, Package->Name.Buffer )); __try { Status = Package->FunctionTable.GetExtendedInformation( Class, Info ); } __except (SP_EXCEPTION) { Status = SPException(GetExceptionCode(), Package->dwPackageID); }
return Status ; }
NTSTATUS LsapSetExtendedPackageInfo( PLSAP_SECURITY_PACKAGE Package, SECPKG_EXTENDED_INFORMATION_CLASS Class, PSECPKG_EXTENDED_INFORMATION Info ) { NTSTATUS Status ;
if ( ((Package->fPackage & SP_INFO) == 0 ) || ( Package->FunctionTable.SetExtendedInformation == NULL ) ) { return SEC_E_NOT_SUPPORTED ; }
DebugLog(( DEB_TRACE, "Setting extended information (%d) from %ws\n", Class, Package->Name.Buffer )); __try { Status = Package->FunctionTable.SetExtendedInformation( Class, Info ); } __except (SP_EXCEPTION) { Status = SPException(GetExceptionCode(), Package->dwPackageID); }
return Status ; }
//+---------------------------------------------------------------------------
//
// Function: LsapAuditPackageBoot
//
// Synopsis: Audit a package boot (load)
//
// Arguments: [pPackage] --
//
// History: 5-06-97 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID LsapAuditPackageBoot( IN PLSAP_SECURITY_PACKAGE pPackage ) { WCHAR PackageAndDll[ MAX_PATH ]; UNICODE_STRING AuditName;
wcsncpy( PackageAndDll, pPackage->pBinding->Filename.Buffer, MAX_PATH );
wcsncat( PackageAndDll, L" : ", MAX_PATH - (pPackage->pBinding->Filename.Length / sizeof(WCHAR)) );
wcsncat( PackageAndDll, pPackage->Name.Buffer, MAX_PATH - ( pPackage->pBinding->Filename.Length / sizeof(WCHAR) + 4) );
RtlInitUnicodeString( &AuditName, PackageAndDll );
LsapAdtAuditPackageLoad( &AuditName ); }
//+---------------------------------------------------------------------------
//
// Function: SpmpBootPackage
//
// Synopsis: Initializes a package by calling it's entry points
//
// Arguments: [pPackage] -- Package to initialize
// [pParameters] -- Initialization parameters
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpBootPackage( IN PLSAP_SECURITY_PACKAGE pPackage, IN PSECPKG_PARAMETERS pParameters ) { SECURITY_STATUS scRetCode; SecPkgInfo spiPackage = { 0 }; UNICODE_STRING TempString; PSECPKG_EXTENDED_INFORMATION WowClient ;
//
// Break now so debugging people can set breakpoints in the newly loaded
// DLL.
//
BreakOnError(BREAK_ON_LOAD);
// Call the packages initialize function. This gives the package a chance
// to do whatever initialization it needs to do. E.g. the kerberos package
// runs out and finds the KDC.
//
// Set the session ID for tracking and so forth.
//
SetCurrentPackageId(pPackage->dwPackageID);
__try { scRetCode = pPackage->FunctionTable.Initialize( pPackage->dwPackageID, pParameters, &LsapSecpkgFunctionTable );
} __except (SP_EXCEPTION) { //
// Well, this is odd. The initialization function blew chunks. That
// means that the package itself can't be trusted. So, let's change
// this to an error return, and let the error logic blow away the
// package.
//
scRetCode = SEC_E_CANNOT_INSTALL;
}
//
// Let's see if the package loaded. Hmm.
//
if (FAILED(scRetCode)) { goto Cleanup; }
//
// Hey, a good one. Now, determine the capabilities of the package by
// calling it's getinfo function.
//
__try { scRetCode = pPackage->FunctionTable.GetInfo( &spiPackage ); } __except (SP_EXCEPTION) { //
// If it blows, catch it, and kill the package.
//
scRetCode = SPException(GetExceptionCode(), pPackage->dwPackageID); }
//
// Reset the session ID.
//
SetCurrentPackageId( SPMGR_ID );
//
// If it failed, note that and return. Note, if there was an exception
// then SPException() will have tagged the package appropriately.
//
if (FAILED(scRetCode)) { goto Cleanup; }
pPackage->fCapabilities = spiPackage.fCapabilities; pPackage->dwRPCID = spiPackage.wRPCID; pPackage->Version = spiPackage.wVersion ; pPackage->TokenSize = spiPackage.cbMaxToken ;
RtlInitUnicodeString( &TempString, spiPackage.Name );
scRetCode = LsapDuplicateString( &pPackage->Name, &TempString );
if (!NT_SUCCESS(scRetCode)) { goto Cleanup; }
RtlInitUnicodeString( &TempString, spiPackage.Comment );
scRetCode = LsapDuplicateString( &pPackage->Comment, &TempString );
if ( !NT_SUCCESS( scRetCode ) ) { goto Cleanup; }
//
// Find out if the package supports extended information. If so,
// find out what context attrs it wants thunked to LSA mode.
//
if ( pPackage->FunctionTable.GetExtendedInformation ) { pPackage->fPackage |= SP_INFO ;
scRetCode = LsapGetExtendedPackageInfo( pPackage, SecpkgContextThunks, &pPackage->Thunks );
if ( scRetCode != STATUS_SUCCESS ) { pPackage->Thunks = NULL ;
scRetCode = 0 ; }
if ( pPackage->Thunks ) { pPackage->fPackage |= SP_CONTEXT_INFO ; }
scRetCode = LsapGetExtendedPackageInfo( pPackage, SecpkgWowClientDll, &WowClient );
if ( scRetCode == STATUS_SUCCESS ) { scRetCode = LsapDuplicateString( &pPackage->WowClientDll, &WowClient->Info.WowClientDll.WowClientDllPath);
if ( NT_SUCCESS( scRetCode ) ) { pPackage->fPackage |= SP_WOW_SUPPORT ; }
} }
DebugLog((DEB_TRACE_INIT | DEB_TRACE, "Loaded %ws, assigned ID %d, flags %#x\n", spiPackage.Name, pPackage->dwPackageID, pPackage->fPackage ));
lsState.cPackages++; if ((pPackage->fPackage & SPM_AUTH_PKG_FLAG) == 0) { lsState.cNewPackages ++; }
//
// And write the audit
//
LsapAuditPackageBoot( pPackage );
return( TRUE );
Cleanup:
return( FALSE ); }
//+---------------------------------------------------------------------------
//
// Function: SpmpBootAuthPackage
//
// Synopsis: Initializes an old-style authentication package.
//
// Arguments: [pPackage] --
//
// History: 5-06-97 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS SpmpBootAuthPackage( PLSAP_SECURITY_PACKAGE pPackage) { NTSTATUS scRet; PSTRING pNlsName; char * pszTemp;
DebugLog((DEB_TRACE_LSA_AU, "Initializing package %d\n", pPackage->dwPackageID));
__try { scRet = pPackage->FunctionTable.InitializePackage( (ULONG) pPackage->dwPackageID, (PLSA_DISPATCH_TABLE) &LsapSecpkgFunctionTable, NULL, NULL, &pNlsName);
if (NT_SUCCESS(scRet)) {
// TODO: why is this alloc+copy here?
pszTemp = (char *)LsapAllocateLsaHeap(pNlsName->Length + 1); if (pszTemp != NULL) { strncpy(pszTemp, pNlsName->Buffer, pNlsName->Length);
scRet = RtlAnsiStringToUnicodeString( &pPackage->Name, pNlsName, TRUE // allocate destination
);
LsapFreeLsaHeap(pszTemp); } else { scRet = STATUS_INSUFFICIENT_RESOURCES; }
//
// NTBUG 395189
// Do not free the returned name. There is no correct way to do
// this, and some vendors do not separately allocate the string
// and structure, and some might use some other part of memory.
// So allow this potential leak, but since they are loaded only once
// and at boot time, that's ok.
//
#if 0
//
// Free the returned name
//
LsapFreeLsaHeap(pNlsName->Buffer); LsapFreeLsaHeap(pNlsName); #endif
}
} __except (SP_EXCEPTION) { scRet = SPException(GetExceptionCode(), pPackage->dwPackageID); }
if (SUCCEEDED(scRet)) { lsState.cPackages ++;
LsapAuditPackageBoot( pPackage ); }
return(scRet); }
//+---------------------------------------------------------------------------
//
// Function: SpmpLoadPackage
//
// Synopsis: Loads a specific package from a DLL binding
//
// Arguments: [pBinding] -- Binding to work from
// [Package] -- Package index to load
// [pParameters] -- Parameters to pass for initialization
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpLoadPackage( PDLL_BINDING pBinding, ULONG Package, PSECPKG_PARAMETERS pParameters) { ULONG PackageId; PLSAP_SECURITY_PACKAGE pPackage; SECPKG_EVENT_PACKAGE_CHANGE Event;
//
// Get the package dispatch table:
//
pPackage = &pBinding->Packages[Package];
//
// Update its binding entry
//
pPackage->pBinding = pBinding;
pPackage->PackageIndex = Package ;
//
// Add it as a package to run
//
PackageId = SpmpAddPackage( pPackage );
if ( PackageId != 0xFFFFFFFF ) { //
// Boot it, so it is initialized
//
if ( SpmpBootPackage(pPackage, pParameters) ) { //
// Notify any listeners:
//
Event.ChangeType = SECPKG_PACKAGE_CHANGE_LOAD ; Event.PackageName = pPackage->Name ; Event.PackageId = PackageId ;
LsapEventNotify( NOTIFY_CLASS_PACKAGE_CHANGE, 0, sizeof( Event ), &Event );
return( TRUE ); }
SpmpRemovePackage( PackageId ); }
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpLoadDll
//
// Synopsis: Loads a new DLL, determines the packages, and loads them
//
// Arguments: [pszDll] -- DLL name
// [pParameters] -- Parameters for initialization
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpLoadDll( PWSTR pszDll, PSECPKG_PARAMETERS pParameters) { HANDLE hDll; DLL_BINDING * pBinding = NULL ; PDLL_BINDING * pList; SpLsaModeInitializeFn Init; ULONG PackageVersion; SECURITY_STATUS scRet; PSECPKG_FUNCTION_TABLE pTables; HINSTANCE hInstance = NULL ; ULONG PackageCount; PWSTR pszPath; ULONG cchPath; ULONG i; ULONG SuccessCount; BOOL IsSigned ;
hInstance = LoadLibrary( pszDll ); if (hInstance) {
Init = (SpLsaModeInitializeFn) GetProcAddress( hInstance, SECPKG_LSAMODEINIT_NAME);
if (Init) { scRet = Init( SECPKG_INTERFACE_VERSION, &PackageVersion, &pTables, &PackageCount );
if (SUCCEEDED(scRet)) { pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) + (PackageCount - 1) * sizeof( LSAP_SECURITY_PACKAGE ) );
if (pBinding) { pBinding->hInstance = hInstance;
pszPath = (PWSTR) LsapAllocateLsaHeap( MAX_PATH * 2 * 2 ); if (pszPath) { UNICODE_STRING TempString; cchPath = GetModuleFileName( hInstance, pszPath, MAX_PATH * 2 );
RtlInitUnicodeString( &TempString, pszPath ); scRet = LsapDuplicateString( &pBinding->Filename, &TempString );
LsapFreeLsaHeap( pszPath );
if (!NT_SUCCESS(scRet)) { //
// Bail out:
//
goto LoadDll_Error; }
#ifdef LSA_IGNORE_SIGNATURE
IsSigned = TRUE; #else
IsSigned = FALSE;
{ const LPWSTR ExclusionList[] = { L"msv1_0", L"kerberos", L"schannel", L"wdigest", NULL }; ULONG ExclusionIndex = 0;
while( ExclusionList[ExclusionIndex] != NULL ) { if( lstrcmpiW( pszDll, ExclusionList[ExclusionIndex] ) == 0 ) { IsSigned = TRUE; break; } ExclusionIndex++; } }
if( !IsSigned ) { IsSigned = RtlCheckSignatureInFile( pBinding->Filename.Buffer ); } #endif
if ( IsSigned ) { pBinding->Flags |= DLL_SIGNED ; } }
pBinding->PackageCount = PackageCount;
SuccessCount = 0;
for (i = 0 ; i < PackageCount ; i++ ) {
//
// Old auth packages contain all functions up to but not including
// SetContextAttributes.
//
if ( PackageVersion == SECPKG_INTERFACE_VERSION ) {
//
// Copy the exported table and zero the rest.
//
CopyMemory( &pBinding->Packages[i].FunctionTable, &pTables[i], offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes ) );
ZeroMemory( ((LPBYTE)(&pBinding->Packages[i].FunctionTable)) + offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes), sizeof(SECPKG_FUNCTION_TABLE) - offsetof(SECPKG_FUNCTION_TABLE, SetContextAttributes) );
} else {
CopyMemory( &pBinding->Packages[i].FunctionTable, &pTables[i], sizeof(SECPKG_FUNCTION_TABLE) ); }
if (SpmpLoadPackage( pBinding, i, pParameters )) { SuccessCount ++; } }
if (SuccessCount) { SpmpAddDll( pBinding );
return( TRUE );
}
}
}
}
}
LoadDll_Error :
if ( pBinding != NULL ) { LsapFreeLsaHeap( pBinding ); }
if ( hInstance != NULL ) { FreeLibrary( hInstance ); }
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpLoadAuthPkgDll
//
// Synopsis: Loads an old (msv1_0 style) DLL
//
// Arguments: [pszDll] --
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpLoadAuthPkgDll( PWSTR pszDll) { SECURITY_STATUS scRet; HINSTANCE hInstance; PDLL_BINDING pBinding = NULL ; PLSAP_SECURITY_PACKAGE pPackage; ULONG PackageId; UNICODE_STRING PackageDll ; PWSTR pszPath ;
DebugLog((DEB_TRACE_INIT, "Loading Old package %ws\n", pszDll));
hInstance = LoadLibrary( pszDll );
if ( hInstance ) { pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) ); if (pBinding) {
pszPath = (PWSTR) LsapAllocateLsaHeap( MAX_PATH * 2 * 2 );
if (pszPath) { UNICODE_STRING TempString; DWORD cchPath ;
cchPath = GetModuleFileName( hInstance, pszPath, MAX_PATH * 2 );
RtlInitUnicodeString( &TempString, pszPath ); scRet = LsapDuplicateString( &pBinding->Filename, &TempString );
LsapFreeLsaHeap( pszPath );
if (!NT_SUCCESS(scRet)) { goto LoadAuthDll_Error ; }
}
pBinding->Flags = DLL_AUTHPKG; pBinding->hInstance = hInstance; pPackage = pBinding->Packages; pPackage->pBinding = pBinding; pBinding->PackageCount = 1;
if (BindOldPackage( hInstance, &pPackage->FunctionTable)) { pPackage->fPackage = SPM_AUTH_PKG_FLAG; pPackage->fCapabilities = SPM_AUTH_PKG_FLAG; pPackage->dwRPCID = SECPKG_ID_NONE;
PackageId = SpmpAddPackage( pPackage ); if (PackageId != (ULONG) 0xFFFFFFFF) { if ( SpmpAddDll( pBinding ) ) { BreakOnError(BREAK_ON_LOAD);
scRet = SpmpBootAuthPackage( pPackage );
if (SUCCEEDED(scRet)) { return( TRUE ); }
SpmpRemoveDll( pBinding );
}
LsapFreeString( &pBinding->Filename );
pBinding->Filename.Buffer = NULL ;
SpmpRemovePackage( PackageId ); }
}
}
}
LoadAuthDll_Error:
if ( pBinding ) { if ( pBinding->Filename.Buffer ) { LsapFreeString( &pBinding->Filename );
}
LsapFreeLsaHeap( pBinding ); }
if ( hInstance ) { FreeLibrary( hInstance ); }
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpLoadBuiltin
//
// Synopsis: Loads a builtin package
//
// Arguments: [Flags] -- Flags for the package
// [pTable] -- Dispatch table
// [pParameters] -- init parameters
//
// History: 7-26-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpLoadBuiltin( ULONG Flags, PSECPKG_FUNCTION_TABLE pTable, PSECPKG_PARAMETERS pParameters) { PDLL_BINDING pBinding; PLSAP_SECURITY_PACKAGE pPackage; SECURITY_STATUS scRetCode; SecPkgInfo spiPackage; ULONG PackageId; SECPKG_EVENT_PACKAGE_CHANGE Event; WCHAR Path[ MAX_PATH ]; SECURITY_STRING TempString ;
pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) );
if (pBinding) { ZeroMemory( pBinding, sizeof( DLL_BINDING ) );
pBinding->Flags = DLL_BUILTIN; pBinding->PackageCount = 1; pBinding->hInstance = GetModuleHandle( L"lsasrv.dll" ); GetModuleFileName( (HINSTANCE) pBinding->hInstance, Path, MAX_PATH );
RtlInitUnicodeString( &TempString, Path ); scRetCode = LsapDuplicateString( &pBinding->Filename, &TempString );
if ( NT_SUCCESS( scRetCode ) ) { pPackage = pBinding->Packages; pPackage->pBinding = pBinding; pPackage->fPackage = Flags | SP_WOW_SUPPORT ;
CopyMemory( &pPackage->FunctionTable, pTable, sizeof(SECPKG_FUNCTION_TABLE) );
//
// Fake up the DLL binding:
//
if ( SpmpAddDll( pBinding ) ) { //
// Add the package to the table:
//
PackageId = SpmpAddPackage( pPackage );
if ( PackageId != 0xFFFFFFFF ) { //
// Initialize the package
//
if (SpmpBootPackage(pPackage, pParameters)) {
//
// Notify any listeners:
//
Event.PackageName = pPackage->Name ; Event.PackageId = PackageId ; Event.ChangeType = SECPKG_PACKAGE_CHANGE_LOAD ;
LsapEventNotify( NOTIFY_CLASS_PACKAGE_CHANGE, 0, sizeof( Event ), &Event );
return( TRUE ); }
SpmpRemovePackage( PackageId ); }
SpmpRemoveDll( pBinding );
}
}
LsapFreeLsaHeap( pBinding->Filename.Buffer );
LsapFreeLsaHeap( pBinding );
}
return( FALSE ); }
BOOL SpmpLoadBuiltinAuthPkg( PSECPKG_FUNCTION_TABLE pTable) { PDLL_BINDING pBinding; ULONG PackageId; PLSAP_SECURITY_PACKAGE pPackage; SECURITY_STATUS scRet; WCHAR Path[ MAX_PATH ]; SECURITY_STRING TempString ;
pBinding = (PDLL_BINDING) LsapAllocateLsaHeap( sizeof( DLL_BINDING ) ); if (pBinding) { pBinding->Flags = DLL_AUTHPKG | DLL_BUILTIN; pBinding->PackageCount = 1; pBinding->hInstance = GetModuleHandle( L"lsasrv.dll" ); GetModuleFileName( (HINSTANCE) pBinding->hInstance, Path, MAX_PATH );
RtlInitUnicodeString( &TempString, Path ); scRet = LsapDuplicateString( &pBinding->Filename, &TempString );
if ( NT_SUCCESS( scRet ) ) { pPackage = pBinding->Packages; pPackage->pBinding = pBinding;
CopyMemory( &pPackage->FunctionTable, pTable, sizeof( SECPKG_FUNCTION_TABLE ) );
pPackage->fPackage = SPM_AUTH_PKG_FLAG; pPackage->fCapabilities = SPM_AUTH_PKG_FLAG; pPackage->dwRPCID = SECPKG_ID_NONE;
PackageId = SpmpAddPackage( pPackage ); if (PackageId != (ULONG) 0xFFFFFFFF) { if ( SpmpAddDll( pBinding ) ) { BreakOnError(BREAK_ON_LOAD);
scRet = SpmpBootAuthPackage( pPackage );
if (SUCCEEDED(scRet)) { return( TRUE ); }
SpmpRemoveDll( pBinding );
}
SpmpRemovePackage( PackageId );
}
LsapFreeLsaHeap( pBinding ); } }
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpLocatePackage
//
// Synopsis: Locates the package
//
// Arguments: [PackageId] --
//
// History: 11-15-95 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpLocatePackage( ULONG_PTR PackageId) { PLSAP_SECURITY_PACKAGE pControl = NULL;
ReadLockPackageList();
if( (ULONG)PackageId < PackageControlCount ) { pControl = pPackageControlList[PackageId]; }
UnlockPackageList();
return( pControl );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpValidateHandle
//
// Synopsis: Validates a package handle
//
// Arguments: [PackageHandle] --
//
// History: 11-15-95 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpValidateHandle( ULONG_PTR PackageHandle) { PLSAP_SECURITY_PACKAGE pControl = NULL;
ReadLockPackageList();
if ( PackageHandle < PackageControlCount ) { pControl = pPackageControlList[ PackageHandle ]; }
UnlockPackageList();
return( pControl ); }
//+---------------------------------------------------------------------------
//
// Function: SpmpValidRequest
//
// Synopsis: Validates package handle, requested API code.
//
// Arguments: [PackageHandle] --
// [ApiCode] --
//
// History: 11-15-95 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpValidRequest( ULONG_PTR PackageHandle, ULONG ApiCode) { PLSAP_SECURITY_PACKAGE pControl = NULL; PVOID * pTable;
ReadLockPackageList();
if ( PackageHandle < PackageControlCount ) { pControl = pPackageControlList[ PackageHandle ]; }
UnlockPackageList();
if (pControl) { if (pControl->fPackage & (SP_INVALID | SP_SHUTDOWN) ) { pControl = NULL; } }
if (pControl) { pTable = (PVOID *) &pControl->FunctionTable; if (pTable[ApiCode]) { return( pControl ); }
pControl = NULL; }
return( pControl );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpLookupPackage
//
// Synopsis: Looks up a package based on name
//
// Arguments: [pssPackageName] --
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpLookupPackage( PUNICODE_STRING pssPackageName) { ULONG iPack; PLSAP_SECURITY_PACKAGE pPackage; PVOID * pTable;
ReadLockPackageList();
for (iPack = 0; iPack < PackageControlCount ; iPack++ ) { pPackage = pPackageControlList[ iPack ];
if ( pPackage ) {
if (RtlEqualUnicodeString( pssPackageName, &pPackageControlList[ iPack ]->Name, TRUE)) // case insensitive
{ UnlockPackageList();
return( pPackage ); } } }
UnlockPackageList(); return(NULL); }
//+---------------------------------------------------------------------------
//
// Function: SpmpLookupPackageByRpcId
//
// Synopsis: Looks up a package based on RPC ID
//
// Arguments: [RpcId] --
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpLookupPackageByRpcId( ULONG RpcId) { ULONG iPack; PLSAP_SECURITY_PACKAGE pPackage; PVOID * pTable;
ReadLockPackageList();
for (iPack = 0; iPack < PackageControlCount ; iPack++ ) { pPackage = pPackageControlList[ iPack ];
if ( pPackage ) { if (RpcId == pPackageControlList[iPack]->dwRPCID) { UnlockPackageList();
return( pPackage ); } } }
UnlockPackageList(); return(NULL); }
//+---------------------------------------------------------------------------
//
// Function: SpmpLookupPackageAndRequest
//
// Synopsis: Returns a package pointer based on a name and the API code
//
// Arguments: [pssPackageName] -- Package name
// [ApiCode] -- Code
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpLookupPackageAndRequest( PUNICODE_STRING pssPackageName, ULONG ApiCode) { ULONG iPack; PLSAP_SECURITY_PACKAGE pPackage; PVOID * pTable;
ReadLockPackageList();
for (iPack = 0; iPack < PackageControlCount ; iPack++ ) { pPackage = pPackageControlList[ iPack ];
if ( pPackage ) {
if (RtlEqualUnicodeString( pssPackageName, &pPackageControlList[ iPack ]->Name, TRUE)) // case insensitive
{ UnlockPackageList(); if ((pPackage->fPackage & ( SP_INVALID | SP_SHUTDOWN )) == 0) { pTable = (PVOID *) &pPackage->FunctionTable;
if (pTable[ApiCode]) { return( pPackage ); } } return( NULL ); } } }
UnlockPackageList(); return(NULL); }
//+---------------------------------------------------------------------------
//
// Function: SpmpIteratePackagesByRequest
//
// Synopsis: Cycle through packages by request code, returning packages
// that support supplied API
//
// Arguments: [pInitialPackage] --
// [ApiCode] --
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpIteratePackagesByRequest( PLSAP_SECURITY_PACKAGE pInitialPackage, ULONG ApiCode) { ULONG_PTR NextPackage; PLSAP_SECURITY_PACKAGE pPackage = NULL; PVOID * pTable; ULONG Ordinal ; ULONG FlagMaskOn = 0 ; ULONG FlagMaskOff = SP_INVALID | SP_SHUTDOWN ;
Ordinal = ApiCode & SP_ORDINAL_MASK ;
if ( ApiCode & SP_ITERATE_FILTER_WOW ) { FlagMaskOn |= SP_WOW_SUPPORT ; }
ReadLockPackageList();
if (pInitialPackage) { NextPackage = pInitialPackage->dwPackageID + 1; } else { NextPackage = 0; }
//
// Walk through the list of packages, filtering on package flags
// and whether the package supported the requested function
//
while (NextPackage < PackageControlCount) { pPackage = pPackageControlList[ NextPackage ];
if ( pPackage ) { if ( ( pPackage->fPackage & FlagMaskOff ) == 0 ) { if ( ( pPackage->fPackage & FlagMaskOn ) == FlagMaskOn ) { pTable = (PVOID *) &pPackage->FunctionTable;
if ( pTable[ Ordinal ] ) { //
// Found one!
//
break; } } }
pPackage = NULL;
}
NextPackage++;
}
UnlockPackageList();
return( pPackage );
}
//+---------------------------------------------------------------------------
//
// Function: SpmpIteratePackages
//
// Synopsis: Safe iteration of the packages
//
// Arguments: [pInitialPackage] -- Prior package
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
PLSAP_SECURITY_PACKAGE SpmpIteratePackages( PLSAP_SECURITY_PACKAGE pInitialPackage) { ULONG_PTR NextPackage; PLSAP_SECURITY_PACKAGE pPackage = NULL;
ReadLockPackageList();
if (pInitialPackage) { NextPackage = pInitialPackage->dwPackageID + 1; } else { NextPackage = 0; }
while (NextPackage < PackageControlCount) { pPackage = pPackageControlList[ NextPackage ];
if ( pPackage ) { break; }
NextPackage++;
}
UnlockPackageList();
return( pPackage ); }
//+---------------------------------------------------------------------------
//
// Function: SpmpCurrentPackageCount
//
// Synopsis: Returns the current package count
//
// Arguments: (none)
//
// History: 7-30-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
ULONG SpmpCurrentPackageCount( VOID) { ULONG Count;
ReadLockPackageList();
Count = PackageControlCount;
UnlockPackageList();
return( Count );
}
//+---------------------------------------------------------------------------
//
// Function: LsapAddPackageHandle
//
// Synopsis: Increases the package handle count
//
// Arguments: [PackageId] --
//
// History: 10-08-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID LsapAddPackageHandle( ULONG_PTR PackageId, BOOL IsContext ) { #if DBG
PLSAP_SECURITY_PACKAGE Package ;
Package = pPackageControlList[ PackageId ];
if ( IsContext ) { InterlockedIncrement( (PLONG)&Package->ContextHandles ); } else { InterlockedIncrement( (PLONG)&Package->CredentialHandles ); }
#else
UNREFERENCED_PARAMETER( PackageId ); UNREFERENCED_PARAMETER( IsContext ); #endif
}
//+---------------------------------------------------------------------------
//
// Function: LsapDelPackageHandle
//
// Synopsis: Decrements the package handle count
//
// Arguments: [PackageId] --
//
// History: 10-08-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID LsapDelPackageHandle( PLSAP_SECURITY_PACKAGE Package, BOOL IsContext ) { #ifdef DBG
if ( IsContext ) { InterlockedDecrement( (PLONG)&Package->ContextHandles ); } else { InterlockedDecrement( (PLONG)&Package->CredentialHandles ); }
#else
UNREFERENCED_PARAMETER( Package ); UNREFERENCED_PARAMETER( IsContext ); #endif
}
//+---------------------------------------------------------------------------
//
// Function: SpmpInitializePackageControl
//
// Synopsis: Initialize the package controls
//
// Arguments: (none)
//
// History: 11-15-95 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL SpmpInitializePackageControl( VOID) { RtlInitializeResource( &PackageListLock );
WriteLockPackageList();
pPackageDllList = (PDLL_BINDING *) LsapAllocateLsaHeap( sizeof(PDLL_BINDING) * INITIAL_PACKAGE_DLL_SIZE );
if (pPackageDllList) { PackageDllCount = 0; PackageDllTotal = INITIAL_PACKAGE_DLL_SIZE;
pPackageControlList = (PLSAP_SECURITY_PACKAGE *) LsapAllocateLsaHeap( sizeof(PLSAP_SECURITY_PACKAGE) * INITIAL_PACKAGE_CONTROL_SIZE );
if (pPackageControlList) { PackageControlCount = 0; PackageControlTotal = INITIAL_PACKAGE_CONTROL_SIZE;
UnlockPackageList();
return( TRUE ); }
LsapFreeLsaHeap( pPackageDllList );
}
//
// KEEP the lock, so that nothing else tries to use the package list
//
return( FALSE );
}
|