Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

401 lines
11 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
init.c
Abstract:
Dll initialization for sspi digest package.
Author:
Adriaan Canter (adriaanc) 01-Aug-1998
--*/
#include "include.hxx"
#include "digestui.hxx"
#include "resource.h"
//
// Downlevel delay load support (we forward to shlwapi)
//
#include <delayimp.h>
PfnDliHook __pfnDliFailureHook;
// Serializes access to all globals in module
CRITICAL_SECTION DllCritSect;
// Per process credential cache.
CCredCache *g_pCache = NULL;
// Per process cache init flag
BOOL g_fCredCacheInit = FALSE;
// Global module handle.
HMODULE g_hModule = NULL;
// Global handle to shlwapi.
HMODULE g_hShlwapi = NULL;
// Status of cred persist services on machine.
DWORD g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN;
DWORD_PTR g_pHeap = NULL;
//--------------------------------------------------------------------
// DigestServicesExist
//--------------------------------------------------------------------
BOOL DigestServicesExist()
{
INIT_SECURITY_INTERFACE addrProcISI = NULL;
PSecurityFunctionTable pFuncTbl = NULL;
PSecPkgInfoA pSecPkgInfo;
SECURITY_STATUS ssResult;
DWORD cPackages;
OSVERSIONINFO VerInfo;
CHAR szDLL[MAX_PATH];
HINSTANCE hSecLib;
BOOL fDigest = FALSE;
// Get the OS version.
VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
GetVersionEx (&VerInfo);
// Load the appropriate dll.
if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
lstrcpy (szDLL, SSP_SPM_NT_DLL);
else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
lstrcpy (szDLL, SSP_SPM_WIN95_DLL);
else
goto exit;
hSecLib = LoadLibrary (szDLL);
if (!hSecLib)
goto exit;
// Get the dispatch table.
addrProcISI = (INIT_SECURITY_INTERFACE) GetProcAddress( hSecLib,
SECURITY_ENTRYPOINT_ANSI);
pFuncTbl = (*addrProcISI)();
if (!pFuncTbl)
goto exit;
// Enumerate security pkgs and determine if digest is installed.
ssResult = (*(pFuncTbl->EnumerateSecurityPackagesA))(&cPackages, &pSecPkgInfo);
if (ssResult == SEC_E_OK)
{
for (DWORD i = 0; i < cPackages; i++)
{
if (lstrcmpi(pSecPkgInfo[i].Name, "Digest") == 0)
{
fDigest = TRUE;
break;
}
}
}
exit:
return fDigest;
}
//--------------------------------------------------------------------
// DLLInstall
//--------------------------------------------------------------------
STDAPI
DllInstall
(
IN BOOL bInstall, // Install or Uninstall
IN LPCWSTR pwStr
)
{
HKEY hKey;
DWORD dwError, dwRegDisp, cbSP = MAX_PATH;
CHAR *ptr, *ptrNext, szSP[MAX_PATH];
BOOL bHKLM = FALSE;
// Determine if full install (provide client digest sspi svcs)
// or just passport install (server pkg delegating to client)
if (!pwStr || !*pwStr || (!wcscmp(pwStr, L"HKLM")))
{
bHKLM = TRUE;
}
// Add "digest.dll" to comma delimited Service Providers list in
// HKLM\System\CurrentControlSet\Control\SecurityProviders only if
// no digest security providers currently exist.
if (bInstall && bHKLM && !DigestServicesExist())
{
// Open or create SecurityProviders key.
dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
SECURITY_PROVIDERS_REG_KEY, 0, NULL,
0, KEY_READ | KEY_WRITE, NULL, &hKey, &dwRegDisp);
// Successfully opened/created key.
if (dwError == ERROR_SUCCESS)
{
cbSP = MAX_PATH;
dwError = RegQueryValueEx(hKey, SECURITY_PROVIDERS_SZ,
NULL, NULL, (LPBYTE) szSP, &cbSP);
// SecurityProviders value might not be
// found which is ok since we will create it.
if (dwError == ERROR_SUCCESS || dwError == ERROR_FILE_NOT_FOUND)
{
// Value not found same as value existed but no string.
if (dwError == ERROR_FILE_NOT_FOUND)
{
ptr = NULL;
cbSP = 0;
}
// Otherwise if value found -> check if "digest.dll" exists.
else
{
// We can use the handy FindToken from the CParams object
// to determine if a token occurs in a comma delmited list.
if (!CParams::FindToken(szSP, cbSP, "digest.dll",
sizeof("digest.dll") - 1, &ptr))
{
ptr = NULL;
}
}
// Only add "digest.dll" if doesn't already exist.
if (!ptr)
{
// If we found value/data append "digest.dll"
if (cbSP > 1)
strcat(szSP, ", digest.dll");
// Otherwise "digest.dll" is only data
else
memcpy(szSP, "digest.dll", sizeof("digest.dll"));
// Write the value back.
dwError = RegSetValueEx(hKey, SECURITY_PROVIDERS_SZ, 0,
REG_SZ, (LPBYTE) szSP, strlen(szSP));
}
}
// Close SecurityProviders reg key.
RegCloseKey(hKey);
}
}
// Remove "digest.dll" from the comma delimited Service Providers list in
// HKLM\System\CurrentControlSet\Control\SecurityProviders
if (!bInstall && bHKLM)
{
// Open the Security Providers reg key.
dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
SECURITY_PROVIDERS_REG_KEY, NULL, KEY_READ | KEY_WRITE, &hKey);
if (dwError == ERROR_SUCCESS)
{
// Get the SecurityProviders value data string.
dwError = RegQueryValueEx(hKey, SECURITY_PROVIDERS_SZ,
NULL, NULL, (LPBYTE) szSP, &cbSP);
if (dwError == ERROR_SUCCESS)
{
// Only remove "digest.dll" if exists.
if (!CParams::FindToken(szSP, cbSP, "digest.dll",
sizeof("digest.dll") - 1, &ptr))
{
ptr = NULL;
}
if (ptr)
{
// Point to next item in list, might be '\0'
ptrNext = ptr + sizeof("digest.dll") - 1;
// Digest.dll is only entry.
if ((ptr == szSP) && cbSP == sizeof("digest.dll"))
{
*szSP = '\0';
}
// "digest.dll" is last entry.
else if (*ptrNext == '\0')
{
*(ptr - (sizeof (", ") - 1)) = '\0';
}
else if (*ptrNext == ',' && *(ptrNext+1) == ' ')
{
ptrNext+=2;
memcpy(ptr, ptrNext, (size_t)(cbSP - (ptrNext - szSP)));
}
dwError = RegSetValueEx(hKey, SECURITY_PROVIDERS_SZ, 0,
REG_SZ, (LPBYTE) szSP, *szSP ? strlen(szSP) : 1);
}
}
RegCloseKey(hKey);
}
}
return S_OK;
}
//--------------------------------------------------------------------
// MakeFullAccessSA
//--------------------------------------------------------------------
//Commenting this function as it doesn't seem to be used anywhere in the sources
/*
SECURITY_ATTRIBUTES *MakeFullAccessSA (void)
{
static SECURITY_ATTRIBUTES sa;
static BYTE SDBuf[SECURITY_DESCRIPTOR_MIN_LENGTH];
// Don't bother on Win95/Win98 which don't support security.
OSVERSIONINFO versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
if (!GetVersionEx(&versionInfo)
|| (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
return NULL;
// Create a security descriptor with ACE to allow full access to all.
SECURITY_DESCRIPTOR* pSD = (SECURITY_DESCRIPTOR*) SDBuf;
if (!InitializeSecurityDescriptor (pSD, SECURITY_DESCRIPTOR_REVISION))
return NULL;
if (!SetSecurityDescriptorDacl (pSD, TRUE, NULL, FALSE))
return NULL;
// Initialize the security attributes.
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;
return &sa;
}*/
//--------------------------------------------------------------------
// NewString
//--------------------------------------------------------------------
LPSTR NewString(LPSTR szString)
{
if (!szString)
return NULL;
DWORD cbString = strlen(szString);
LPSTR szNew = new CHAR[cbString+1];
if (!szNew)
{
DIGEST_ASSERT(FALSE);
return NULL;
}
memcpy(szNew, szString, cbString+1);
return szNew;
}
//--------------------------------------------------------------------
// InitGlobals
//--------------------------------------------------------------------
BOOL InitGlobals()
{
// Return success if we've already
// initialized.
if (g_fCredCacheInit)
return TRUE;
// Serialize per-process calls.
LOCK_GLOBALS();
// Recheck global flag in the case
// the cache was initialized while
// this thread was descheduled.
if (g_fCredCacheInit)
{
goto exit;
}
// Global cred persist status.
g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN;
// Create the credential cache.
g_pCache = new CCredCache();
if (!g_pCache || g_pCache->GetStatus() != ERROR_SUCCESS)
{
g_fCredCacheInit = FALSE;
goto exit;
}
g_fCredCacheInit = TRUE;
exit:
UNLOCK_GLOBALS();
return g_fCredCacheInit;
}
void SetupDelayloadErrorHandler()
{
__pfnDliFailureHook = (PfnDliHook)GetProcAddress(GetModuleHandleA("shlwapi.dll"), "DelayLoadFailureHook");
}
//--------------------------------------------------------------------
// DllMain
//--------------------------------------------------------------------
#if defined(__cplusplus)
extern "C"
#endif
BOOL
WINAPI
DllMain(
IN PVOID DllHandle,
IN ULONG Reason,
IN PCONTEXT Context OPTIONAL
)
{
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(DllHandle );
switch (Reason)
{
// Process attach.
case DLL_PROCESS_ATTACH:
{
// BUGBUG - DislableThreadLibraryCalls and
// don't do any work.
g_hModule = (HMODULE) DllHandle;
InitializeCriticalSection( &DllCritSect );
SetupDelayloadErrorHandler();
if ((hDigest = CreateMutex (NULL,
FALSE,
NULL)) == NULL)
return FALSE;
break;
}
// Process detatch.
// Deinitialize the credential cache.
// Delete the critical section.
case DLL_PROCESS_DETACH:
{
if (g_pCache)
delete g_pCache;
DeleteCriticalSection( &DllCritSect );
CloseHandle (hDigest);
break;
}
}
return TRUE;
}