/*******************************************************************/ /* Copyright(c) 1992 Microsoft Corporation */ /*******************************************************************/ //*** // // Filename: registry.c // // Description: This module contains the code for DDM parameters // initialization and loading from the registry. // // Author: Stefan Solomon (stefans) May 18, 1992. // //*** #include "ddm.h" #include <string.h> #include <stdlib.h> #include <ddmparms.h> #include <rasauth.h> #include <util.h> typedef struct _DDM_REGISTRY_PARAMS { LPWSTR pszValueName; DWORD * pValue; DWORD dwDefValue; DWORD Min; DWORD Max; } DDM_REGISTRY_PARAMS, *PDDM_REGISTRY_PARAMS; // // DDM parameter descriptor table // DDM_REGISTRY_PARAMS DDMRegParams[] = { // authenticateretries DDM_VALNAME_AUTHENTICATERETRIES, &gblDDMConfigInfo.dwAuthenticateRetries, DEF_AUTHENTICATERETRIES, MIN_AUTHENTICATERETRIES, MAX_AUTHENTICATERETRIES, // authenticatetime DDM_VALNAME_AUTHENTICATETIME, &gblDDMConfigInfo.dwAuthenticateTime, DEF_AUTHENTICATETIME, MIN_AUTHENTICATETIME, MAX_AUTHENTICATETIME, // callbacktime DDM_VALNAME_CALLBACKTIME, &gblDDMConfigInfo.dwCallbackTime, DEF_CALLBACKTIME, MIN_CALLBACKTIME, MAX_CALLBACKTIME, // Autodisconnect Time DDM_VALNAME_AUTODISCONNECTTIME, &gblDDMConfigInfo.dwAutoDisconnectTime, DEF_AUTODISCONNECTTIME, MIN_AUTODISCONNECTTIME, MAX_AUTODISCONNECTTIME, // Clients per process DDM_VALNAME_CLIENTSPERPROC, &gblDDMConfigInfo.dwClientsPerProc, DEF_CLIENTSPERPROC, MIN_CLIENTSPERPROC, MAX_CLIENTSPERPROC, // Time for 3rd party security DLL to complete DDM_VALNAME_SECURITYTIME, &gblDDMConfigInfo.dwSecurityTime, DEF_SECURITYTIME, MIN_SECURITYTIME, MAX_SECURITYTIME, // Logging level DDM_VALNAME_LOGGING_LEVEL, &gblDDMConfigInfo.dwLoggingLevel, DEF_LOGGINGLEVEL, MIN_LOGGINGLEVEL, MAX_LOGGINGLEVEL, // Number of callback retries DDM_VALNAME_NUM_CALLBACK_RETRIES, &gblDDMConfigInfo.dwCallbackRetries, DEF_NUMCALLBACKRETRIES, MIN_NUMCALLBACKRETRIES, MAX_NUMCALLBACKRETRIES, DDM_VALNAME_SERVERFLAGS, &gblDDMConfigInfo.dwServerFlags, DEF_SERVERFLAGS, 0, 0xFFFFFFFF, // End NULL, NULL, 0, 0, 0 }; //*** // // Function: GetKeyMax // // Descr: returns the nr of values in this key and the maximum // size of the value data. // //*** DWORD GetKeyMax( IN HKEY hKey, OUT LPDWORD MaxValNameSize_ptr, // longest valuename OUT LPDWORD NumValues_ptr, // nr of values OUT LPDWORD MaxValueDataSize_ptr // max size of data ) { DWORD NumSubKeys; DWORD MaxSubKeySize; DWORD dwRetCode; dwRetCode = RegQueryInfoKey( hKey, NULL, NULL, NULL, &NumSubKeys, &MaxSubKeySize, NULL, NumValues_ptr, MaxValNameSize_ptr, MaxValueDataSize_ptr, NULL, NULL ); (*MaxValNameSize_ptr)++; return( dwRetCode ); } //*** // // Function: LoadDDMParameters // // Descr: Opens the registry, reads and sets specified supervisor // parameters. If fatal error reading parameters writes the // error log. // // Returns: NO_ERROR - success // else - fatal error. // //*** DWORD LoadDDMParameters( IN HKEY hkeyParameters, OUT BOOL* pfIpAllowed ) { DWORD dwIndex; DWORD dwRetCode; DWORD cbValueBuf; DWORD dwType; DWORD fIpxAllowed; // // Initialize Global values // gblDDMConfigInfo.fRemoteListen = TRUE; gblDDMConfigInfo.dwAnnouncePresenceTimer = ANNOUNCE_PRESENCE_TIMEOUT; // // Let us not allow any protocol if DdmFindBoundProtocols fails. // gblDDMConfigInfo.dwServerFlags &= ~( PPPCFG_ProjectNbf | PPPCFG_ProjectIp | PPPCFG_ProjectIpx | PPPCFG_ProjectAt ); dwRetCode = DdmFindBoundProtocols( pfIpAllowed, &fIpxAllowed, &gblDDMConfigInfo.fArapAllowed ); if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); } if ( !*pfIpAllowed && !fIpxAllowed && !gblDDMConfigInfo.fArapAllowed ) { DDMLogError( ROUTERLOG_NO_PROTOCOLS_CONFIGURED, 0, NULL, 0 ); return( dwRetCode ); } // // Run through and get all the DDM values // for ( dwIndex = 0; DDMRegParams[dwIndex].pszValueName != NULL; dwIndex++ ) { cbValueBuf = sizeof( DWORD ); dwRetCode = RegQueryValueEx( hkeyParameters, DDMRegParams[dwIndex].pszValueName, NULL, &dwType, (LPBYTE)(DDMRegParams[dwIndex].pValue), &cbValueBuf ); if ((dwRetCode != NO_ERROR) && (dwRetCode != ERROR_FILE_NOT_FOUND)) { DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } if ( dwRetCode == ERROR_FILE_NOT_FOUND ) { *(DDMRegParams[dwIndex].pValue) = DDMRegParams[dwIndex].dwDefValue; dwRetCode = NO_ERROR; } else { if ( ( dwType != REG_DWORD ) ||(*(DDMRegParams[dwIndex].pValue) > DDMRegParams[dwIndex].Max) ||( *(DDMRegParams[dwIndex].pValue)<DDMRegParams[dwIndex].Min)) { WCHAR * pChar = DDMRegParams[dwIndex].pszValueName; DDMLogWarning( ROUTERLOG_REGVALUE_OVERIDDEN,1,&pChar); *(DDMRegParams[dwIndex].pValue) = DDMRegParams[dwIndex].dwDefValue; } } } if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); } else { // // Insert allowed protocols in the ServerFlags which will be sent to // PPP engine // if ( *pfIpAllowed ) { gblDDMConfigInfo.dwServerFlags |= PPPCFG_ProjectIp; } if ( fIpxAllowed ) { gblDDMConfigInfo.dwServerFlags |= PPPCFG_ProjectIpx; } if ( gblDDMConfigInfo.fArapAllowed ) { gblDDMConfigInfo.dwServerFlags |= PPPCFG_ProjectAt; } if ( gblDDMConfigInfo.dwServerFlags & PPPCFG_RequireStrongEncryption ) { ModifyDefPolicyToForceEncryption( TRUE ); } else if ( gblDDMConfigInfo.dwServerFlags & PPPCFG_RequireEncryption ) { ModifyDefPolicyToForceEncryption( FALSE ); } gblDDMConfigInfo.dwServerFlags &= ~PPPCFG_RequireStrongEncryption; gblDDMConfigInfo.dwServerFlags &= ~PPPCFG_RequireEncryption; } return( NO_ERROR ); } //*** // // Function: LoadSecurityModule // // Descr: Opens the registry, reads and sets specified supervisor // parameters for the secuirity module. If fatal error reading // parameters writes the error log. // // Returns: NO_ERROR - success // otherwise - fatal error. // //*** DWORD LoadSecurityModule( VOID ) { HKEY hKey; DWORD dwRetCode = NO_ERROR; DWORD MaxValueDataSize; DWORD MaxValNameSize; DWORD NumValues; DWORD dwType; WCHAR * pDllPath = NULL; WCHAR * pDllExpandedPath = NULL; DWORD cbSize; // // get handle to the RAS key // dwRetCode = RegOpenKey( HKEY_LOCAL_MACHINE, DDM_SEC_KEY_PATH, &hKey); if ( dwRetCode == ERROR_FILE_NOT_FOUND ) { return( NO_ERROR ); } else if ( dwRetCode != NO_ERROR ) { DDMLogErrorString( ROUTERLOG_CANT_OPEN_SECMODULE_KEY, 0, NULL, dwRetCode, 0); return ( dwRetCode ); } do { // // get the length of the path. // if (( dwRetCode = GetKeyMax( hKey, &MaxValNameSize, &NumValues, &MaxValueDataSize))) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode); break; } if ((pDllPath = LOCAL_ALLOC(LPTR,MaxValueDataSize+sizeof(WCHAR)))==NULL) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode); break; } // // Read in the path // dwRetCode = RegQueryValueEx( hKey, DDM_VALNAME_DLLPATH, NULL, &dwType, (LPBYTE)pDllPath, &MaxValueDataSize ); if ( dwRetCode != NO_ERROR ) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode); break; } if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) ) { dwRetCode = ERROR_REGISTRY_CORRUPT; DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } // // Replace the %SystemRoot% with the actual path. // cbSize = ExpandEnvironmentStrings( pDllPath, NULL, 0 ); if ( cbSize == 0 ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) ); if ( pDllExpandedPath == (LPWSTR)NULL ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode ); break; } cbSize = ExpandEnvironmentStrings( pDllPath, pDllExpandedPath, cbSize ); if ( cbSize == 0 ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } gblDDMConfigInfo.hInstSecurityModule = LoadLibrary( pDllExpandedPath ); if ( gblDDMConfigInfo.hInstSecurityModule == (HINSTANCE)NULL ) { dwRetCode = GetLastError(); if( (ERROR_INVALID_EXE_SIGNATURE == dwRetCode) || (ERROR_BAD_EXE_FORMAT == dwRetCode) || (ERROR_EXE_MARKED_INVALID == dwRetCode)) { DDMLogError(ROUTERLOG_CANT_LOAD_SECDLL_EXPLICIT, 1, &pDllExpandedPath, 0); } else { DDMLogErrorString(ROUTERLOG_CANT_LOAD_SECDLL, 0, NULL, dwRetCode,0); } break; } gblDDMConfigInfo.lpfnRasBeginSecurityDialog = (PVOID)GetProcAddress( gblDDMConfigInfo.hInstSecurityModule, "RasSecurityDialogBegin" ); if ( gblDDMConfigInfo.lpfnRasBeginSecurityDialog == NULL ) { dwRetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_SECDLL,0,NULL,dwRetCode,0); break; } gblDDMConfigInfo.lpfnRasEndSecurityDialog = (PVOID)GetProcAddress( gblDDMConfigInfo.hInstSecurityModule, "RasSecurityDialogEnd" ); if ( gblDDMConfigInfo.lpfnRasEndSecurityDialog == NULL ) { dwRetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_SECDLL,0,NULL,dwRetCode,0); break; } }while(FALSE); if ( pDllPath != NULL ) { LOCAL_FREE( pDllPath ); } if ( pDllExpandedPath != NULL ) { LOCAL_FREE( pDllExpandedPath ); } RegCloseKey( hKey ); return( dwRetCode ); } //*** // // Function: LoadAdminModule // // Descr: Opens the registry, reads and sets specified supervisor // parameters for the admin module. If fatal error reading // parameters writes the error log. // // Returns: NO_ERROR - success // otherwise - fatal error. // //*** DWORD LoadAdminModule( VOID ) { DWORD RetCode = NO_ERROR; DWORD MaxValueDataSize; DWORD MaxValNameSize; DWORD NumValues; DWORD dwType; WCHAR * pDllPath = NULL; WCHAR * pDllExpandedPath = NULL; DWORD cbSize; HKEY hKey; DWORD (*lpfnRasAdminInitializeDll)(); WCHAR *pDelimiter, *pStartDllPath, *pEndDllPath; DWORD NumAdminDlls; BOOL bDone; HANDLE hAdminDll=NULL; gblDDMConfigInfo.NumAdminDlls = 0; // get handle to the RAS key RetCode = RegOpenKey( HKEY_LOCAL_MACHINE, DDM_ADMIN_KEY_PATH, &hKey); if ( RetCode == ERROR_FILE_NOT_FOUND ) { return( NO_ERROR ); } else if ( RetCode != NO_ERROR ) { DDMLogErrorString(ROUTERLOG_CANT_OPEN_ADMINMODULE_KEY,0,NULL,RetCode,0); return ( RetCode ); } do { // get the length of the path. if (( RetCode = GetKeyMax(hKey, &MaxValNameSize, &NumValues, &MaxValueDataSize))) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, RetCode); break; } if (( pDllPath = LOCAL_ALLOC(LPTR,MaxValueDataSize+sizeof(WCHAR))) == NULL) { DDMLogError(ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, 0); break; } // // Read in the path // RetCode = RegQueryValueEx( hKey, DDM_VALNAME_DLLPATH, NULL, &dwType, (LPBYTE)pDllPath, &MaxValueDataSize ); // min size should be greater than 2 (2 for null) if (MaxValueDataSize <= 2) return NO_ERROR; if ( RetCode != NO_ERROR ) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, RetCode); break; } if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) ) { RetCode = ERROR_REGISTRY_CORRUPT; DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, RetCode ); break; } // // Replace the %SystemRoot% with the actual path. // cbSize = ExpandEnvironmentStrings( pDllPath, NULL, 0 ); if ( cbSize == 0 ) { RetCode = GetLastError(); DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, RetCode ); break; } pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize*sizeof(WCHAR) ); if ( pDllExpandedPath == (LPWSTR)NULL ) { RetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, RetCode ); break; } cbSize = ExpandEnvironmentStrings( pDllPath, pDllExpandedPath, cbSize ); if ( cbSize == 0 ) { RetCode = GetLastError(); DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, RetCode ); break; } // // locate each dll and load its callbacks // // get number of dlls. NumAdminDlls can be more by 1 if ending in ';' pStartDllPath = pDllExpandedPath; pEndDllPath = pDllExpandedPath + cbSize - 1; for (NumAdminDlls=1; NULL!=(pDelimiter = wcschr(pStartDllPath, L';')); NumAdminDlls++, pStartDllPath=pDelimiter+1); pStartDllPath = pDllExpandedPath; // allocate array for all Dlls' callbacks gblDDMConfigInfo.AdminDllCallbacks = (PADMIN_DLL_CALLBACKS) LOCAL_ALLOC(LPTR, sizeof(ADMIN_DLL_CALLBACKS)*NumAdminDlls); if (gblDDMConfigInfo.AdminDllCallbacks == NULL) { RetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, RetCode); break; } bDone = FALSE; while (TRUE) { PADMIN_DLL_CALLBACKS AdminDllCallbacks = &gblDDMConfigInfo.AdminDllCallbacks[gblDDMConfigInfo.NumAdminDlls]; hAdminDll = NULL; pDelimiter = wcschr(pStartDllPath, L';'); if (pDelimiter) *pDelimiter = L'\0'; else bDone = TRUE; if (*pStartDllPath == L' ') break; // load the dll AdminDllCallbacks->hInstAdminModule = hAdminDll = LoadLibrary( pStartDllPath ); if ( AdminDllCallbacks->hInstAdminModule == (HINSTANCE)NULL ) { RetCode = GetLastError(); if( (ERROR_INVALID_EXE_SIGNATURE == RetCode) || (ERROR_BAD_EXE_FORMAT == RetCode) || (ERROR_EXE_MARKED_INVALID == RetCode)) { DDMLogError(ROUTERLOG_CANT_LOAD_ADMINDLL_EXPLICIT, 1, &pDllExpandedPath, 0); } else { DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL, 0, NULL, RetCode,0); } break; } lpfnRasAdminInitializeDll = (DWORD(*)(VOID))GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminInitializeDll" ); AdminDllCallbacks->lpfnRasAdminTerminateDll = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminTerminateDll" ); AdminDllCallbacks->lpfnRasAdminAcceptNewConnection = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminAcceptNewConnection" ); AdminDllCallbacks->lpfnRasAdminAcceptNewConnection2 = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminAcceptNewConnection2" ); // // At least one of these 2 must be available // if ( ( AdminDllCallbacks->lpfnRasAdminAcceptNewConnection == NULL ) && ( AdminDllCallbacks->lpfnRasAdminAcceptNewConnection2 == NULL ) ) { RetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL,0,NULL,RetCode,0); break; } AdminDllCallbacks->lpfnRasAdminAcceptNewLink = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminAcceptNewLink" ); if ( AdminDllCallbacks->lpfnRasAdminAcceptNewLink == NULL ) { RetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL,0,NULL,RetCode,0); break; } AdminDllCallbacks->lpfnRasAdminConnectionHangupNotification = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminConnectionHangupNotification" ); AdminDllCallbacks->lpfnRasAdminConnectionHangupNotification2 = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminConnectionHangupNotification2" ); // // At least one of these 2 entrypoints must be available // if ( (AdminDllCallbacks->lpfnRasAdminConnectionHangupNotification==NULL) && (AdminDllCallbacks->lpfnRasAdminConnectionHangupNotification2==NULL)) { RetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL,0,NULL,RetCode,0); break; } if ( lpfnRasAdminInitializeDll != NULL ) { RetCode = (*lpfnRasAdminInitializeDll)(); if(ERROR_SUCCESS != RetCode) { DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL, 0,NULL,RetCode,0); break; } } AdminDllCallbacks->lpfnRasAdminLinkHangupNotification = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminLinkHangupNotification" ); if ( AdminDllCallbacks->lpfnRasAdminLinkHangupNotification == NULL ) { RetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL,0,NULL,RetCode,0); break; } AdminDllCallbacks->lpfnMprAdminGetIpAddressForUser = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminGetIpAddressForUser" ); AdminDllCallbacks->lpfnMprAdminReleaseIpAddress = (PVOID)GetProcAddress( AdminDllCallbacks->hInstAdminModule, "MprAdminReleaseIpAddress" ); if ( ( (AdminDllCallbacks->lpfnMprAdminGetIpAddressForUser != NULL) && ( AdminDllCallbacks->lpfnMprAdminReleaseIpAddress == NULL )) || ( (AdminDllCallbacks->lpfnMprAdminGetIpAddressForUser == NULL) && ( AdminDllCallbacks->lpfnMprAdminReleaseIpAddress != NULL )) ) { RetCode = GetLastError(); DDMLogErrorString(ROUTERLOG_CANT_LOAD_ADMINDLL,0,NULL,RetCode,0); break; } if(ERROR_SUCCESS != RetCode) break; // one more admin dll successfully loaded gblDDMConfigInfo.NumAdminDlls++; if (bDone) { break; } pStartDllPath = pDelimiter + 1; if (pStartDllPath >= pEndDllPath) break; } if ( (ERROR_SUCCESS != RetCode) && (hAdminDll!=NULL) ) { FreeLibrary(hAdminDll); } }while(FALSE); //breakout block if ( pDllPath != NULL ) { LOCAL_FREE( pDllPath ); } if ( pDllExpandedPath != NULL ) { LOCAL_FREE( pDllExpandedPath ); } RegCloseKey( hKey ); return( RetCode ); } //** // // Call: LoadAndInitAuthOrAcctProvider // // Returns: NO_ERROR - Success // Non-zero returns - Failure // // Description: // DWORD LoadAndInitAuthOrAcctProvider( IN BOOL fAuthenticationProvider, IN DWORD dwNASIpAddress, OUT DWORD * lpdwStartAccountingSessionId, OUT LPVOID * plpfnRasAuthProviderAuthenticateUser, OUT LPVOID * plpfnRasAuthProviderFreeAttributes, OUT LPVOID * plpfnRasAuthConfigChangeNotification, OUT LPVOID * plpfnRasAcctProviderStartAccounting, OUT LPVOID * plpfnRasAcctProviderInterimAccounting, OUT LPVOID * plpfnRasAcctProviderStopAccounting, OUT LPVOID * plpfnRasAcctProviderFreeAttributes, OUT LPVOID * plpfnRasAcctConfigChangeNotification ) { HKEY hKeyProviders = NULL; HKEY hKeyCurrentProvider = NULL; LPWSTR pDllPath = (LPWSTR)NULL; LPWSTR pDllExpandedPath = (LPWSTR)NULL; LPWSTR pProviderName = (LPWSTR)NULL; HINSTANCE hinstProviderModule = NULL; DWORD dwRetCode; WCHAR chSubKeyName[100]; DWORD cbSubKeyName; DWORD dwNumSubKeys; DWORD dwMaxSubKeySize; DWORD dwNumValues; DWORD cbMaxValNameLen; DWORD cbMaxValueDataSize; DWORD cbSize; DWORD dwType; CHAR chComputerName[MAX_COMPUTERNAME_LENGTH + 1]; RAS_AUTH_ATTRIBUTE ServerAttributes[3]; CHAR szAcctSessionId[20]; do { dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, fAuthenticationProvider ? RAS_AUTHPROVIDER_REGISTRY_LOCATION : RAS_ACCTPROVIDER_REGISTRY_LOCATION, 0, KEY_READ, &hKeyProviders ); if ( dwRetCode != NO_ERROR ) { LPWSTR lpStr = fAuthenticationProvider ? RAS_AUTHPROVIDER_REGISTRY_LOCATION : RAS_ACCTPROVIDER_REGISTRY_LOCATION; DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &lpStr, dwRetCode ); break; } // // Find out the size of the provider value // dwRetCode = RegQueryInfoKey( hKeyProviders, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeySize, NULL, &dwNumValues, &cbMaxValNameLen, &cbMaxValueDataSize, NULL, NULL ); if ( dwRetCode != NO_ERROR ) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } // // One extra for the NULL terminator // cbMaxValueDataSize += sizeof(WCHAR); pProviderName = (LPWSTR)LOCAL_ALLOC( LPTR, cbMaxValueDataSize ); if ( pProviderName == NULL ) { dwRetCode = GetLastError(); break; } // // Find out the provider to use // dwRetCode = RegQueryValueEx( hKeyProviders, RAS_VALNAME_ACTIVEPROVIDER, NULL, &dwType, (BYTE*)pProviderName, &cbMaxValueDataSize ); if ( dwRetCode != NO_ERROR ) { DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } if ( dwType != REG_SZ ) { dwRetCode = ERROR_REGISTRY_CORRUPT; DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } if ( wcslen( pProviderName ) == 0 ) { dwRetCode = fAuthenticationProvider ? ERROR_REGISTRY_CORRUPT : NO_ERROR; break; } else { if ( !fAuthenticationProvider ) { HKEY hKeyAccounting; dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, RAS_KEYPATH_ACCOUNTING, 0, KEY_READ, &hKeyAccounting ); if ( dwRetCode == NO_ERROR ) { cbMaxValueDataSize = sizeof( DWORD ); dwRetCode = RegQueryValueEx( hKeyAccounting, RAS_VALNAME_ACCTSESSIONID, NULL, &dwType, (BYTE*)lpdwStartAccountingSessionId, &cbMaxValueDataSize ); if ( ( dwRetCode != NO_ERROR ) || ( dwType != REG_DWORD ) ) { *lpdwStartAccountingSessionId = 0; } RegCloseKey( hKeyAccounting ); } if ( wcscmp( pProviderName, TEXT("{1AA7F840-C7F5-11D0-A376-00C04FC9DA04}") ) == 0 ) { gblDDMConfigInfo.fFlags |= DDM_USING_RADIUS_ACCOUNTING; } } else { if ( wcscmp( pProviderName, TEXT("{1AA7F83F-C7F5-11D0-A376-00C04FC9DA04}") ) == 0 ) { gblDDMConfigInfo.fFlags |= DDM_USING_RADIUS_AUTHENTICATION; } else if ( wcscmp( pProviderName, TEXT("{1AA7F841-C7F5-11D0-A376-00C04FC9DA04}") ) == 0 ) { gblDDMConfigInfo.fFlags |= DDM_USING_NT_AUTHENTICATION; } } } dwRetCode = RegOpenKeyEx( hKeyProviders, pProviderName, 0, KEY_READ, &hKeyCurrentProvider ); if ( dwRetCode != NO_ERROR ) { LPWSTR lpStr = RAS_ACCTPROVIDER_REGISTRY_LOCATION; DDMLogError( ROUTERLOG_CANT_OPEN_REGKEY, 1, &lpStr, dwRetCode ); break; } // // Find out the size of the path value. // dwRetCode = RegQueryInfoKey( hKeyCurrentProvider, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeySize, NULL, &dwNumValues, &cbMaxValNameLen, &cbMaxValueDataSize, NULL, NULL ); if ( dwRetCode != NO_ERROR ) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } // // Allocate space for path and add one for NULL terminator // cbMaxValueDataSize += sizeof(WCHAR); pDllPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbMaxValueDataSize ); if ( pDllPath == (LPWSTR)NULL ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode); break; } // // Read in the path // dwRetCode = RegQueryValueEx( hKeyCurrentProvider, RAS_PROVIDER_VALUENAME_PATH, NULL, &dwType, (PBYTE)pDllPath, &cbMaxValueDataSize ); if ( dwRetCode != NO_ERROR ) { DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } if ( ( dwType != REG_EXPAND_SZ ) && ( dwType != REG_SZ ) ) { dwRetCode = ERROR_REGISTRY_CORRUPT; DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } // // Replace the %SystemRoot% with the actual path. // cbSize = ExpandEnvironmentStrings( pDllPath, NULL, 0 ); if ( cbSize == 0 ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_CANT_GET_REGKEYVALUES, 0, NULL, dwRetCode ); break; } cbSize *= sizeof( WCHAR ); pDllExpandedPath = (LPWSTR)LOCAL_ALLOC( LPTR, cbSize ); if ( pDllExpandedPath == (LPWSTR)NULL ) { dwRetCode = GetLastError(); DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode); break; } cbSize = ExpandEnvironmentStrings( pDllPath, pDllExpandedPath, cbSize ); if ( cbSize == 0 ) { dwRetCode = GetLastError(); DDMLogError(ROUTERLOG_CANT_GET_REGKEYVALUES,0,NULL,dwRetCode); break; } hinstProviderModule = LoadLibrary( pDllExpandedPath ); if ( hinstProviderModule == (HINSTANCE)NULL ) { dwRetCode = GetLastError(); break; } // // Get server attributes that will be used to initialize authentication // and accounting providers // if ( dwNASIpAddress == 0 ) { DWORD dwComputerNameLen = sizeof( chComputerName); // // Failed to get the LOCAL IP address, use computer name instead. // if ( !GetComputerNameA( chComputerName, &dwComputerNameLen ) ) { dwRetCode = GetLastError(); break; } ServerAttributes[0].raaType = raatNASIdentifier; ServerAttributes[0].dwLength = strlen(chComputerName); ServerAttributes[0].Value = chComputerName; } else { ServerAttributes[0].raaType = raatNASIPAddress; ServerAttributes[0].dwLength = 4; ServerAttributes[0].Value = UlongToPtr(dwNASIpAddress); } if ( !fAuthenticationProvider ) { ZeroMemory( szAcctSessionId, sizeof( szAcctSessionId ) ); _itoa( (*lpdwStartAccountingSessionId)++, szAcctSessionId, 10 ); ServerAttributes[1].raaType = raatAcctSessionId; ServerAttributes[1].dwLength = strlen( szAcctSessionId ); ServerAttributes[1].Value = (PVOID)szAcctSessionId; ServerAttributes[2].raaType = raatMinimum; ServerAttributes[2].dwLength = 0; ServerAttributes[2].Value = NULL; } else { ServerAttributes[1].raaType = raatMinimum; ServerAttributes[1].dwLength = 0; ServerAttributes[1].Value = NULL; } if ( fAuthenticationProvider ) { DWORD (*RasAuthProviderInitialize)( RAS_AUTH_ATTRIBUTE *, HANDLE, DWORD ); gblDDMConfigInfo.hinstAuthModule = hinstProviderModule; RasAuthProviderInitialize = (DWORD(*)(RAS_AUTH_ATTRIBUTE*, HANDLE, DWORD)) GetProcAddress( hinstProviderModule, "RasAuthProviderInitialize" ); if ( RasAuthProviderInitialize == NULL ) { dwRetCode = GetLastError(); break; } dwRetCode = RasAuthProviderInitialize( (RAS_AUTH_ATTRIBUTE *)ServerAttributes, gblDDMConfigInfo.hLogEvents, gblDDMConfigInfo.dwLoggingLevel ); if ( dwRetCode != NO_ERROR ) { break; } gblDDMConfigInfo.lpfnRasAuthProviderTerminate = (DWORD(*)(VOID)) GetProcAddress( hinstProviderModule, "RasAuthProviderTerminate" ); if ( gblDDMConfigInfo.lpfnRasAuthProviderTerminate == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAuthProviderAuthenticateUser = GetProcAddress( hinstProviderModule, "RasAuthProviderAuthenticateUser" ); if ( *plpfnRasAuthProviderAuthenticateUser == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAuthProviderFreeAttributes = GetProcAddress( hinstProviderModule, "RasAuthProviderFreeAttributes" ); if ( *plpfnRasAuthProviderFreeAttributes == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAuthConfigChangeNotification = GetProcAddress( hinstProviderModule, "RasAuthConfigChangeNotification" ); if ( *plpfnRasAuthConfigChangeNotification == NULL ) { dwRetCode = GetLastError(); break; } } else { DWORD (*RasAcctProviderInitialize)( RAS_AUTH_ATTRIBUTE *, HANDLE, DWORD ); gblDDMConfigInfo.hinstAcctModule = hinstProviderModule; RasAcctProviderInitialize = (DWORD(*)(RAS_AUTH_ATTRIBUTE*, HANDLE, DWORD)) GetProcAddress( hinstProviderModule, "RasAcctProviderInitialize" ); if ( RasAcctProviderInitialize == NULL ) { dwRetCode = GetLastError(); break; } dwRetCode = RasAcctProviderInitialize( (RAS_AUTH_ATTRIBUTE *)ServerAttributes, gblDDMConfigInfo.hLogEvents, gblDDMConfigInfo.dwLoggingLevel ); if ( dwRetCode != NO_ERROR ) { break; } gblDDMConfigInfo.lpfnRasAcctProviderTerminate = (DWORD(*)(VOID)) GetProcAddress( hinstProviderModule, "RasAcctProviderTerminate" ); if ( gblDDMConfigInfo.lpfnRasAcctProviderTerminate == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAcctProviderStartAccounting = GetProcAddress( hinstProviderModule, "RasAcctProviderStartAccounting" ); if ( *plpfnRasAcctProviderStartAccounting == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAcctProviderStopAccounting = GetProcAddress( hinstProviderModule, "RasAcctProviderStopAccounting" ); if ( *plpfnRasAcctProviderStopAccounting == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAcctProviderInterimAccounting = GetProcAddress( hinstProviderModule, "RasAcctProviderInterimAccounting"); if ( *plpfnRasAcctProviderInterimAccounting == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAcctProviderFreeAttributes = GetProcAddress( hinstProviderModule, "RasAcctProviderFreeAttributes" ); if ( *plpfnRasAcctProviderFreeAttributes == NULL ) { dwRetCode = GetLastError(); break; } *plpfnRasAcctConfigChangeNotification = GetProcAddress( hinstProviderModule, "RasAcctConfigChangeNotification" ); if ( *plpfnRasAcctConfigChangeNotification == NULL ) { dwRetCode = GetLastError(); break; } } }while( FALSE ); if ( hKeyProviders != NULL ) { RegCloseKey( hKeyProviders ); } if ( hKeyCurrentProvider != NULL ) { RegCloseKey( hKeyCurrentProvider ); } if ( pDllPath != NULL ) { LOCAL_FREE( pDllPath ); } if ( pDllExpandedPath != NULL ) { LOCAL_FREE( pDllExpandedPath ); } if ( pProviderName != NULL ) { LOCAL_FREE( pProviderName ); } return( dwRetCode ); } LONG RegQueryDword (HKEY hkey, LPCTSTR szValueName, LPDWORD pdwValue) { // Get the value. // DWORD dwType; DWORD cbData = sizeof(DWORD); LONG lr = RegQueryValueEx (hkey, szValueName, NULL, &dwType, (LPBYTE)pdwValue, &cbData); // It's type should be REG_DWORD. (duh). // if ((ERROR_SUCCESS == lr) && (REG_DWORD != dwType)) { lr = ERROR_INVALID_DATATYPE; } // Make sure we initialize the output value on error. // (We don't know for sure that RegQueryValueEx does this.) // if (ERROR_SUCCESS != lr) { *pdwValue = 0; } return lr; } DWORD lProtocolEnabled( IN HKEY hKey, IN DWORD dwPid, IN BOOL fRasSrv, IN BOOL fRouter, IN BOOL * pfEnabled ) { static const TCHAR c_szRegValEnableIn[] = TEXT("EnableIn"); static const TCHAR c_szRegValEnableRoute[] = TEXT("EnableRoute"); static const TCHAR c_szRegSubkeyIp[] = TEXT("Ip"); static const TCHAR c_szRegSubkeyIpx[] = TEXT("Ipx"); static const TCHAR c_szRegSubkeyATalk[] = TEXT("AppleTalk"); DWORD dwValue; DWORD lr; HKEY hkeyProtocol = NULL; const TCHAR * pszSubkey; switch ( dwPid ) { case PID_IP: pszSubkey = c_szRegSubkeyIp; break; case PID_IPX: pszSubkey = c_szRegSubkeyIpx; break; case PID_ATALK: pszSubkey = c_szRegSubkeyATalk; break; default: return( FALSE ); } *pfEnabled = FALSE; lr = RegOpenKey( hKey, pszSubkey, &hkeyProtocol ); if ( 0 != lr ) { goto done; } if (fRasSrv) { lr = RegQueryDword(hkeyProtocol, c_szRegValEnableIn, &dwValue); if ( (ERROR_FILE_NOT_FOUND == lr) || ((ERROR_SUCCESS == lr) && (dwValue != 0))) { lr = ERROR_SUCCESS; *pfEnabled = TRUE; goto done; } } if (fRouter) { lr = RegQueryDword(hkeyProtocol, c_szRegValEnableRoute, &dwValue); if ( (ERROR_FILE_NOT_FOUND == lr) || ((ERROR_SUCCESS == lr) && (dwValue != 0))) { lr = ERROR_SUCCESS; *pfEnabled = TRUE; goto done; } } done: if(NULL != hkeyProtocol) { RegCloseKey ( hkeyProtocol ); } return lr; } DWORD DdmFindBoundProtocols( OUT BOOL * pfBoundToIp, OUT BOOL * pfBoundToIpx, OUT BOOL * pfBoundToATalk ) { static const TCHAR c_szRegKeyRemoteAccessParams[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Parameters"); RASMAN_GET_PROTOCOL_INFO InstalledProtocols; LONG lResult = 0; HKEY hKey = NULL; DWORD i; *pfBoundToIp = FALSE; *pfBoundToIpx = FALSE; *pfBoundToATalk = FALSE; lResult = RasGetProtocolInfo( NULL, &InstalledProtocols ); if ( lResult != NO_ERROR ) { goto done; } lResult = RegOpenKey( HKEY_LOCAL_MACHINE, c_szRegKeyRemoteAccessParams, &hKey ); if ( 0 != lResult ) { goto done; } for ( i = 0; i < InstalledProtocols.ulNumProtocols; i++ ) { switch( InstalledProtocols.ProtocolInfo[i].ProtocolType ) { case IPX: #if (WINVER < 0x0501) lResult=lProtocolEnabled( hKey, PID_IPX, TRUE, FALSE, pfBoundToIpx); #endif break; case IP: lResult=lProtocolEnabled( hKey, PID_IP, TRUE, FALSE, pfBoundToIp ); break; case APPLETALK: lResult=lProtocolEnabled( hKey, PID_ATALK, TRUE, FALSE, pfBoundToATalk); break; default: break; } } RegCloseKey( hKey ); done: return ( DWORD ) lResult; } DWORD GetArrayOfIpAddresses(PWSTR pwszIpAddresses, DWORD *pcNumValues, PWSTR **papwstrValues) { DWORD cValues = 0; PWSTR psz = pwszIpAddresses; DWORD dwErr = ERROR_SUCCESS; DWORD i; PWSTR *apwstrValues = NULL; do { for(; TEXT('\0') != *psz; cValues++) { psz += (wcslen(psz) + 1); } apwstrValues = LocalAlloc(LPTR, cValues * sizeof(PWSTR)); if(NULL == apwstrValues) { dwErr = GetLastError(); break; } psz = pwszIpAddresses; for(i = 0; TEXT('\0') != *psz; i++) { apwstrValues[i] = psz; psz += (wcslen(psz) + 1); } } while (FALSE); *pcNumValues = cValues; *papwstrValues = apwstrValues; return dwErr; } DWORD GetIPAddressPoolFromRegistry( HKEY hkey, PWSTR pszValueName, DWORD *pcNumValues, PWSTR **papwstrValues ) { DWORD dwErr = ERROR_SUCCESS; DWORD dwType; DWORD dwSize = 0; PWSTR pwszIpAddresses = NULL; do { if( (NULL == papwstrValues) || (NULL == pcNumValues) || (NULL == pszValueName) || (NULL == hkey)) { dwErr = ERROR_INVALID_HANDLE; break; } *pcNumValues = 0; *papwstrValues = NULL; // // Find the size of the MULTI_SZ // dwErr = RegQueryValueEx( hkey, pszValueName, NULL, &dwType, NULL, &dwSize); if( (ERROR_SUCCESS != dwErr) || (REG_MULTI_SZ != dwType) || (0 == dwSize)) { // // Trace out that failed to read the information // and bail. // break; } // // Allocate the bufffer // pwszIpAddresses = LocalAlloc(LPTR, dwSize); if(NULL == pwszIpAddresses) { dwErr = GetLastError(); break; } // // Get the strings // dwErr = RegQueryValueEx( hkey, pszValueName, NULL, &dwType, (LPBYTE) pwszIpAddresses, &dwSize); if(ERROR_SUCCESS != dwErr) { // // Trace // break; } // // Construct the array of IPAddresses // dwErr = GetArrayOfIpAddresses(pwszIpAddresses, pcNumValues, papwstrValues); } while (FALSE); return dwErr; } DWORD AddressPoolInit( VOID ) { HKEY hkey = NULL; DWORD dwErr = ERROR_SUCCESS; gblDDMConfigInfo.cAnalogIPAddresses = 0; gblDDMConfigInfo.apAnalogIPAddresses = NULL; gblDDMConfigInfo.cDigitalIPAddresses = 0; gblDDMConfigInfo.apDigitalIPAddresses = NULL; do { dwErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Services\\PptpProtocol\\Parameters"), 0, KEY_READ, &hkey); if(ERROR_SUCCESS != dwErr) { break; } // // Get Analog IP Address Pool // dwErr = GetIPAddressPoolFromRegistry( hkey, TEXT("AnalogIPAddressPool"), &gblDDMConfigInfo.cAnalogIPAddresses, &gblDDMConfigInfo.apAnalogIPAddresses); // // Trace out the errors here // // // Get Digital IP Address Pool // dwErr = GetIPAddressPoolFromRegistry( hkey, TEXT("DigitalIPAddressPool"), &gblDDMConfigInfo.cDigitalIPAddresses, &gblDDMConfigInfo.apDigitalIPAddresses); // // Trace out the errors here // } while(FALSE); if(NULL != hkey) { RegCloseKey(hkey); } if(ERROR_FILE_NOT_FOUND == dwErr) { dwErr = ERROR_SUCCESS; } return dwErr; }