//+----------------------------------------------------------------------- // // File: PARAM.C // // Contents: Parameter code // // // History: 28 Feb 92 RichardW Created // //------------------------------------------------------------------------ #include 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 ); }