638 lines
14 KiB
C++
638 lines
14 KiB
C++
|
|
//+-----------------------------------------------------------------------
|
|
//
|
|
// File: PARAM.C
|
|
//
|
|
// Contents: Parameter code
|
|
//
|
|
//
|
|
// History: 28 Feb 92 RichardW Created
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
#include <lsapch.hxx>
|
|
extern "C"
|
|
{
|
|
extern PWSTR pszPreferred;
|
|
}
|
|
|
|
#define MACHINERIDKEY L"MACHINERID"
|
|
|
|
WCHAR szLsaPath[] = L"System\\CurrentControlSet\\Control\\Lsa";
|
|
WCHAR szOthersValue[] = L"Security Packages";
|
|
WCHAR szOldValue[] = L"Authentication Packages";
|
|
WCHAR szNonceLagValue[] = L"Clock Skew";
|
|
WCHAR szHowMuchValue[] = L"How Much";
|
|
WCHAR szDisableSupPopups[] = L"DisablePopups";
|
|
WCHAR szPreferredPackage[] = L"Preferred";
|
|
WCHAR szGeneralThreadLifespan[] = L"GeneralThreadLifespan";
|
|
WCHAR szDedicatedThreadLifespan[] = L"DedicatedThreadLifespan";
|
|
|
|
HKEY hDSKey;
|
|
HANDLE hRegNotifyEvent;
|
|
PVOID pvParamScav;
|
|
|
|
|
|
PWSTR ppszDefault[] = {L"Kerberos", L"NTLM", NULL};
|
|
|
|
// Will build an argv style array of DLLs to load as packages here:
|
|
extern PWSTR * ppszPackages;
|
|
extern PWSTR * ppszOldPkgs;
|
|
extern PWSTR pszPreferred;
|
|
|
|
#if DBG
|
|
extern DWORD BreakFlags;
|
|
extern DWORD NoUnload;
|
|
#endif
|
|
|
|
|
|
SECURITY_STRING ssMachineRid;
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetRegistryString
|
|
//
|
|
// Synopsis: Gets a string from the registry
|
|
//
|
|
// Effects: If type is REG_EXPAND_SZ, string is expanded.
|
|
// If type is REG_MULTI_SZ, string is (left alone?)
|
|
//
|
|
// Arguments: hRootKey -- HKEY to start at
|
|
// pszSubKey -- Key to look at
|
|
// pszValue -- Value to look at
|
|
// pszData -- Buffer to place string
|
|
// pcbData -- Size (in/out) of buffer
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
NTSTATUS
|
|
GetRegistryString( HKEY hRootKey,
|
|
PWSTR pszSubkey,
|
|
PWSTR pszValue,
|
|
PWSTR pszData,
|
|
PDWORD pcbData)
|
|
{
|
|
HKEY hKey;
|
|
int Status;
|
|
ULONG type;
|
|
DWORD dwSize = *pcbData;
|
|
|
|
|
|
Status = RegOpenKey(hRootKey, pszSubkey, &hKey);
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
DebugLog((DEB_ERROR, "Open of %ws failed, %d\n", pszSubkey, Status));
|
|
|
|
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
|
}
|
|
|
|
|
|
// First, call query value and make sure this is a correct type
|
|
|
|
|
|
Status = RegQueryValueEx( hKey,
|
|
pszValue,
|
|
NULL,
|
|
&type,
|
|
NULL,
|
|
&dwSize);
|
|
|
|
if ((Status != ERROR_SUCCESS) && (Status != ERROR_MORE_DATA))
|
|
{
|
|
DebugLog((DEB_TRACE, "QueryValueEx of %ws failed, %d\n", pszValue, Status));
|
|
(void) RegCloseKey(hKey);
|
|
if (Status == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
|
}
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
|
|
if ((type != REG_SZ) && (type != REG_MULTI_SZ) && (type != REG_EXPAND_SZ) )
|
|
{
|
|
DebugLog((DEB_ERROR, "Type = %d, returning now\n", type));
|
|
|
|
(void) RegCloseKey(hKey);
|
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
|
|
|
|
Status = RegQueryValueEx( hKey,
|
|
pszValue,
|
|
NULL,
|
|
&type,
|
|
(PBYTE) pszData,
|
|
pcbData);
|
|
|
|
|
|
(void) RegCloseKey(hKey);
|
|
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
if (Status == ERROR_INSUFFICIENT_BUFFER)
|
|
{
|
|
return(STATUS_BUFFER_TOO_SMALL);
|
|
}
|
|
|
|
DebugLog((DEB_ERROR, "QueryValueEx of %ws returned %d\n", pszValue, Status));
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
|
|
if (type == REG_EXPAND_SZ)
|
|
{
|
|
*pcbData = ExpandEnvironmentStrings(pszData, pszData, dwSize);
|
|
}
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetRegistryDword
|
|
//
|
|
// Synopsis: Gets a DWORD from the registry
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: [hPrimaryKey] -- Key to start from
|
|
// [pszKey] -- Name of the subkey
|
|
// [pszValue] -- Name of the value
|
|
// [pdwValue] -- returned DWORD
|
|
//
|
|
// Returns: S_OK, or SEC_E_INVALID_HANDLE
|
|
//
|
|
// History: 3-31-93 RichardW Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
GetRegistryDword(HKEY hPrimaryKey,
|
|
PWSTR pszKey,
|
|
PWSTR pszValue,
|
|
DWORD * pdwValue)
|
|
{
|
|
HKEY hKey;
|
|
DWORD cbDword = sizeof(DWORD);
|
|
DWORD dwType;
|
|
int err;
|
|
|
|
|
|
err = RegOpenKey(hPrimaryKey, pszKey, &hKey);
|
|
|
|
if (err) {
|
|
return(SEC_E_INVALID_HANDLE);
|
|
}
|
|
|
|
|
|
err = RegQueryValueEx( hKey,
|
|
pszValue,
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE) pdwValue,
|
|
&cbDword);
|
|
|
|
(void) RegCloseKey(hKey);
|
|
|
|
if (err || (dwType != REG_DWORD))
|
|
{
|
|
return(SEC_E_INVALID_HANDLE);
|
|
}
|
|
|
|
return(S_OK);
|
|
|
|
}
|
|
|
|
|
|
HRESULT
|
|
SpmGetMachineName(void)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
WCHAR wszMachName [MAX_COMPUTERNAME_LENGTH + 1];
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
|
|
|
if (!GetComputerName(
|
|
wszMachName,
|
|
&dwSize))
|
|
{
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
MachineName.Buffer = (LPWSTR) LsapAllocateLsaHeap((wcslen(wszMachName)+1) * sizeof(WCHAR));
|
|
if (MachineName.Buffer == NULL)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
wcscpy(MachineName.Buffer, wszMachName);
|
|
RtlInitUnicodeString(
|
|
&MachineName,
|
|
MachineName.Buffer
|
|
);
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ParameterNotify
|
|
//
|
|
// Synopsis: Function called when the registry key for DS is changed
|
|
//
|
|
// Arguments: [pvEntry] -- ignored
|
|
//
|
|
// History: 6-08-93 RichardW Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
DWORD
|
|
ParameterNotify(PVOID pvEntry)
|
|
{
|
|
ULONG NewState;
|
|
HANDLE hThread = 0;
|
|
DWORD tid;
|
|
int err;
|
|
|
|
|
|
err = RegNotifyChangeKeyValue( hDSKey, FALSE,
|
|
REG_NOTIFY_CHANGE_LAST_SET,
|
|
hRegNotifyEvent,
|
|
TRUE);
|
|
|
|
if (err)
|
|
{
|
|
DebugLog((DEB_WARN, "Got %d from trying to start RegNotifyChangeKeyValue again\n",
|
|
err));
|
|
}
|
|
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LoadParameters
|
|
//
|
|
// Synopsis: Loads operating parameters from the registry
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: [void] --
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Signals:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// Algorithm:
|
|
//
|
|
// History: 3-31-93 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
LoadParameters(
|
|
VOID
|
|
)
|
|
{
|
|
int lcPackages = 0;
|
|
int cOldPkgs = 0;
|
|
int iPackage = 0;
|
|
PWSTR pszAlternate;
|
|
PWSTR pszOldPkgs;
|
|
PWSTR pszScan;
|
|
DWORD dwBuffer = 64;
|
|
HRESULT scRet;
|
|
|
|
//
|
|
// Get the parameters that can change during a boot.
|
|
//
|
|
|
|
|
|
|
|
//
|
|
// Get the machine name
|
|
//
|
|
|
|
scRet = SpmGetMachineName();
|
|
|
|
if (!NT_SUCCESS(scRet)) {
|
|
return(scRet);
|
|
}
|
|
|
|
//
|
|
// Get the preferred package
|
|
//
|
|
|
|
dwBuffer = 128 ;
|
|
|
|
pszPreferred = (PWSTR) LsapAllocateLsaHeap( dwBuffer );
|
|
|
|
if ( !pszPreferred )
|
|
{
|
|
dwBuffer = 0 ;
|
|
}
|
|
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szPreferredPackage,
|
|
pszPreferred,
|
|
&dwBuffer);
|
|
|
|
if (scRet == STATUS_BUFFER_TOO_SMALL)
|
|
{
|
|
LsapFreeLsaHeap(pszPreferred);
|
|
|
|
pszPreferred = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
|
|
|
|
if ( pszPreferred )
|
|
{
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szPreferredPackage,
|
|
pszPreferred,
|
|
&dwBuffer);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( pszPreferred )
|
|
{
|
|
LsapFreeLsaHeap( pszPreferred );
|
|
|
|
pszPreferred = NULL ;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Set the default packages
|
|
//
|
|
|
|
ppszPackages = ppszDefault;
|
|
|
|
|
|
//
|
|
// Now, find out all the other ones. First, NT5 packages:
|
|
//
|
|
|
|
dwBuffer = 128;
|
|
|
|
pszAlternate = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
|
|
if (!pszAlternate)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
*pszAlternate = L'\0';
|
|
|
|
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szOthersValue,
|
|
pszAlternate,
|
|
&dwBuffer);
|
|
|
|
if (scRet == STATUS_BUFFER_TOO_SMALL)
|
|
{
|
|
LsapFreeLsaHeap(pszAlternate);
|
|
|
|
pszAlternate = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
|
|
if (!pszAlternate)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
*pszAlternate = L'\0';
|
|
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szOthersValue,
|
|
pszAlternate,
|
|
&dwBuffer);
|
|
|
|
if (FAILED(scRet)) {
|
|
return(scRet);
|
|
}
|
|
|
|
}
|
|
if (NT_SUCCESS(scRet))
|
|
{
|
|
|
|
pszScan = pszAlternate;
|
|
|
|
while (*pszScan)
|
|
{
|
|
while (*pszScan) {
|
|
pszScan++;
|
|
}
|
|
|
|
lcPackages++;
|
|
pszScan++;
|
|
}
|
|
|
|
} else if (scRet != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
LsapFreeLsaHeap(pszAlternate);
|
|
pszAlternate = NULL;
|
|
return(scRet);
|
|
} else {
|
|
LsapFreeLsaHeap(pszAlternate);
|
|
pszAlternate = NULL;
|
|
}
|
|
|
|
dwBuffer = 128;
|
|
pszOldPkgs = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
|
|
if (!pszOldPkgs)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
*pszOldPkgs = L'\0';
|
|
|
|
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szOldValue,
|
|
pszOldPkgs,
|
|
&dwBuffer);
|
|
|
|
if (scRet == STATUS_BUFFER_TOO_SMALL)
|
|
{
|
|
LsapFreeLsaHeap(pszOldPkgs);
|
|
|
|
pszOldPkgs = (PWSTR)LsapAllocateLsaHeap(dwBuffer);
|
|
if (!pszOldPkgs)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
*pszOldPkgs = L'\0';
|
|
scRet = GetRegistryString( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
szOldValue,
|
|
pszOldPkgs,
|
|
&dwBuffer);
|
|
|
|
if (!NT_SUCCESS(scRet)) {
|
|
return(scRet);
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(scRet))
|
|
{
|
|
pszScan = pszOldPkgs;
|
|
|
|
while (*pszScan)
|
|
{
|
|
while (*pszScan) {
|
|
pszScan++;
|
|
}
|
|
|
|
cOldPkgs++;
|
|
pszScan++;
|
|
}
|
|
} else if (scRet != STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
LsapFreeLsaHeap(pszOldPkgs);
|
|
pszOldPkgs = NULL;
|
|
return(scRet);
|
|
} else {
|
|
LsapFreeLsaHeap(pszOldPkgs);
|
|
pszOldPkgs = NULL;
|
|
}
|
|
|
|
ppszPackages = (PWSTR *)LsapAllocateLsaHeap((lcPackages + 1) * sizeof(PWSTR));
|
|
if (!ppszPackages)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
|
|
//
|
|
// Add any alternate packages
|
|
//
|
|
|
|
if (pszAlternate != NULL)
|
|
{
|
|
pszScan = pszAlternate;
|
|
|
|
while (*pszScan)
|
|
{
|
|
ppszPackages[iPackage++] = pszScan;
|
|
while (*pszScan++);
|
|
}
|
|
}
|
|
|
|
ppszPackages[iPackage] = NULL;
|
|
|
|
//
|
|
// Note: we don't allocate one extra, since we don't actually include
|
|
// the MSV package name here (we simulate the package in msvlayer.c)
|
|
//
|
|
|
|
ppszOldPkgs = (PWSTR *)LsapAllocateLsaHeap((cOldPkgs+1) * sizeof(PWSTR));
|
|
if (!ppszOldPkgs)
|
|
{
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
iPackage = 0;
|
|
if (pszOldPkgs != NULL)
|
|
{
|
|
pszScan = pszOldPkgs;
|
|
|
|
|
|
while (*pszScan)
|
|
{
|
|
ppszOldPkgs[iPackage++] = pszScan;
|
|
while (*pszScan++);
|
|
}
|
|
}
|
|
|
|
cOldPkgs = iPackage;
|
|
ppszOldPkgs[iPackage] = NULL;
|
|
|
|
return(S_OK);
|
|
|
|
}
|
|
|
|
BOOL
|
|
AddPackageToRegistry(
|
|
PSECURITY_STRING Package
|
|
)
|
|
{
|
|
PWSTR Buffer;
|
|
DWORD Length;
|
|
DWORD Type;
|
|
int err;
|
|
HKEY hKey;
|
|
|
|
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
szLsaPath,
|
|
0,
|
|
KEY_READ | KEY_WRITE,
|
|
&hKey );
|
|
|
|
if ( err )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
Length = 0;
|
|
|
|
err = RegQueryValueEx( hKey,
|
|
szOthersValue,
|
|
0,
|
|
&Type,
|
|
NULL,
|
|
&Length );
|
|
|
|
Buffer = (PWSTR) LsapAllocateLsaHeap( Length + Package->Length + 2 );
|
|
|
|
if ( !Buffer )
|
|
{
|
|
RegCloseKey( hKey );
|
|
|
|
return FALSE ;
|
|
}
|
|
|
|
RegQueryValueEx( hKey,
|
|
szOthersValue,
|
|
0,
|
|
&Type,
|
|
(PUCHAR) Buffer,
|
|
&Length );
|
|
|
|
CopyMemory( &Buffer[Length + 1],
|
|
Package->Buffer,
|
|
Package->Length + 2 );
|
|
|
|
Length = Length + Package->Length + 2;
|
|
|
|
RegSetValueEx( hKey,
|
|
szOthersValue,
|
|
0,
|
|
REG_MULTI_SZ,
|
|
(PUCHAR) Buffer,
|
|
Length );
|
|
|
|
RegCloseKey( hKey );
|
|
|
|
return( TRUE );
|
|
|
|
|
|
}
|