/* File routerdb.c Implements a database abstraction for accessing router interfaces. If any caching/transactioning/commit-noncommit-moding is done, it should be implemented here with the api's remaining constant. */ #include "precomp.h" EXTERN_C HRESULT APIENTRY HrRenameConnection(const GUID* guidId, PCWSTR pszNewName); typedef DWORD (WINAPI *PRasValidateEntryName)( LPWSTR lpszPhonebook, // pointer to full path and filename of phone-book file LPWSTR lpszEntry // pointer to the entry name to validate ); typedef struct _RTR_IF_LIST { WCHAR pszName[MAX_INTERFACE_NAME_LEN + 1]; struct _RTR_IF_LIST* pNext; } RTR_IF_LIST; // // Callback for RtrdbInterfaceEnumerate that adds the interface // to a list if the interface is type wan. // DWORD RtrdbAddWanIfToList( IN PWCHAR pwszIfName, IN DWORD dwLevel, IN DWORD dwFormat, IN PVOID pvData, IN HANDLE hData) { MPR_INTERFACE_0* pIf0 = (MPR_INTERFACE_0*)pvData; RTR_IF_LIST** ppList = (RTR_IF_LIST**)hData; RTR_IF_LIST* pNode = NULL; DWORD dwErr = NO_ERROR, dwSize; do { // See if the interface type is right // if (pIf0->dwIfType == ROUTER_IF_TYPE_FULL_ROUTER) { // Initialize a new node for the list // pNode = (RTR_IF_LIST*) IfutlAlloc(sizeof(RTR_IF_LIST), TRUE); if (pNode == NULL) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } dwSize = sizeof(pNode->pszName); dwErr = GetIfNameFromFriendlyName( pwszIfName, pNode->pszName, &dwSize); BREAK_ON_DWERR(dwErr); // Add the interface to the list // pNode->pNext = *ppList; *ppList = pNode; } } while (FALSE); // Cleanup { if (dwErr != NO_ERROR) { IfutlFree(pNode); } } return dwErr; } DWORD RtrdbValidatePhoneBookEntry( PWSTR pwszInterfaceName ) { HMODULE hRasApi32; PRasValidateEntryName pfnRasValidateEntryName; DWORD dwErr; WCHAR rgwcPath[MAX_PATH+1]; // // get phone book path + file name // if(g_pwszRouter is NULL) { dwErr = ExpandEnvironmentStringsW(LOCAL_ROUTER_PB_PATHW, rgwcPath, sizeof(rgwcPath)/sizeof(rgwcPath[0])); } else { dwErr = wsprintfW(rgwcPath, REMOTE_ROUTER_PB_PATHW, g_pwszRouter); } ASSERT(dwErr > 0); // // Load RASAPI32 DLL and call into it to verify specified // phone book entry // hRasApi32 = LoadLibraryW(L"RASAPI32.DLL"); if(hRasApi32 isnot NULL) { pfnRasValidateEntryName = (PRasValidateEntryName) GetProcAddress(hRasApi32, "RasValidateEntryNameW"); if(pfnRasValidateEntryName isnot NULL ) { dwErr = pfnRasValidateEntryName(rgwcPath, pwszInterfaceName); if(dwErr is NO_ERROR) { dwErr = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY; } else { if(dwErr is ERROR_ALREADY_EXISTS) { dwErr = NO_ERROR; } } } else { dwErr = GetLastError (); } FreeLibrary(hRasApi32); } else { dwErr = GetLastError(); } return dwErr; } DWORD RtrInterfaceCreate( PMPR_INTERFACE_0 pIfInfo ) { DWORD dwErr; HANDLE hIfCfg, hIfAdmin; dwErr = MprConfigInterfaceCreate(g_hMprConfig, 0, (PBYTE)pIfInfo, &hIfCfg); if(dwErr isnot NO_ERROR) { DisplayError(g_hModule, dwErr); return dwErr; } // // if router service is running add the interface // to it too. // if(IfutlIsRouterRunning()) { dwErr = MprAdminInterfaceCreate(g_hMprAdmin, 0, (PBYTE)pIfInfo, &hIfAdmin); if(dwErr isnot NO_ERROR) { DisplayError(g_hModule, dwErr); return dwErr; } } return NO_ERROR; } DWORD RtrdbInterfaceAdd( IN PWCHAR pszInterface, IN DWORD dwLevel, IN PVOID pvInfo ) /*++ Routine Description: Adds an interface to the router Arguments: pIfInfo - Info for adding the interface Return Value: NO_ERROR --*/ { DWORD dwErr; HANDLE hIfAdmin, hIfCfg; GUID Guid; MPR_INTERFACE_0* pIfInfo = (MPR_INTERFACE_0*)pvInfo; // // If an interface with this name exists, bug out // if(pIfInfo->dwIfType is ROUTER_IF_TYPE_FULL_ROUTER) { // // to create an interface we need a phone book entry // for it. // dwErr = RtrdbValidatePhoneBookEntry(pIfInfo->wszInterfaceName); if(dwErr isnot NO_ERROR) { DisplayMessage(g_hModule, EMSG_NO_PHONEBOOK, pIfInfo->wszInterfaceName); return dwErr; } } else { DisplayMessage(g_hModule, EMSG_BAD_IF_TYPE, pIfInfo->dwIfType); return ERROR_INVALID_PARAMETER; } // // create interface with defaults // pIfInfo->hInterface = INVALID_HANDLE_VALUE; dwErr = RtrInterfaceCreate(pIfInfo); if(dwErr isnot NO_ERROR) { DisplayMessage(g_hModule, EMSG_CANT_CREATE_IF, pIfInfo->wszInterfaceName, dwErr); } return dwErr; } DWORD RtrdbInterfaceDelete( IN PWCHAR pwszIfName ) { DWORD dwErr, dwSize, dwIfType; HANDLE hIfCfg, hIfAdmin; GUID Guid; PMPR_INTERFACE_0 pIfInfo; do { dwErr = MprConfigInterfaceGetHandle(g_hMprConfig, pwszIfName, &hIfCfg); if(dwErr isnot NO_ERROR) { break; } dwErr = MprConfigInterfaceGetInfo(g_hMprConfig, hIfCfg, 0, (PBYTE *)&pIfInfo, &dwSize); if(dwErr isnot NO_ERROR) { break; } if(pIfInfo->dwIfType isnot ROUTER_IF_TYPE_FULL_ROUTER) { MprConfigBufferFree(pIfInfo); dwErr = ERROR_INVALID_PARAMETER; break; } if(IfutlIsRouterRunning()) { dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin, pwszIfName, &hIfAdmin, FALSE); if(dwErr isnot NO_ERROR) { break; } dwErr = MprAdminInterfaceDelete(g_hMprAdmin, hIfAdmin); if(dwErr isnot NO_ERROR) { break; } } dwIfType = pIfInfo->dwIfType; dwErr = MprConfigInterfaceDelete(g_hMprConfig, hIfCfg); MprConfigBufferFree(pIfInfo); if(dwErr isnot NO_ERROR) { break; } }while(FALSE); return dwErr; } DWORD RtrdbInterfaceEnumerate( IN DWORD dwLevel, IN DWORD dwFormat, IN RTR_IF_ENUM_FUNC pEnum, IN HANDLE hData ) { DWORD dwErr, i, dwCount, dwTotal, dwResume, dwPrefBufSize; MPR_INTERFACE_0* pCurIf = NULL; LPBYTE pbBuffer = NULL; BOOL bRouter, bContinue; // Validate / Initiazlize if (pEnum == NULL) { return ERROR_INVALID_PARAMETER; } dwPrefBufSize = sizeof(MPR_INTERFACE_0) * 100; bRouter = IfutlIsRouterRunning(); dwResume = 0; do { // Enumerate the first n interfaces // if (bRouter) { dwErr = MprAdminInterfaceEnum( g_hMprAdmin, 0, &pbBuffer, dwPrefBufSize, &dwCount, &dwTotal, &dwResume); } else { dwErr = MprConfigInterfaceEnum( g_hMprConfig, 0, &pbBuffer, dwPrefBufSize, &dwCount, &dwTotal, &dwResume); } if (dwErr == ERROR_MORE_DATA) { dwErr = NO_ERROR; bContinue = TRUE; } else { bContinue = FALSE; } if (dwErr != NO_ERROR) { break; } // Call the callback for each interface as long // as we're instructed to continue pCurIf = (MPR_INTERFACE_0*)pbBuffer; for (i = 0; (i < dwCount) && (dwErr == NO_ERROR); i++) { dwErr = (*pEnum)( pCurIf->wszInterfaceName, dwLevel, dwFormat, (PVOID)pCurIf, hData); pCurIf++; } if (dwErr != NO_ERROR) { break; } // Free up the interface list buffer if (pbBuffer) { if (bRouter) { MprAdminBufferFree(pbBuffer); } else { MprConfigBufferFree(pbBuffer); } pbBuffer = NULL; } // Keep this loop going until there are // no more interfaces // } while (bContinue); // Cleanup { } return dwErr; } DWORD RtrdbInterfaceRead( IN PWCHAR pwszIfName, IN DWORD dwLevel, IN PVOID pvInfo ) { DWORD dwErr, dwSize; HANDLE hIfCfg, hIfAdmin; PMPR_INTERFACE_0 pInfo = NULL; do { if(IfutlIsRouterRunning()) { dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin, pwszIfName, &hIfAdmin, FALSE); if(dwErr isnot NO_ERROR) { break; } dwErr = MprAdminInterfaceGetInfo(g_hMprAdmin, hIfAdmin, 0, (PBYTE *)&pInfo); if(dwErr isnot NO_ERROR) { break; } if (pInfo == NULL) { dwErr = ERROR_CAN_NOT_COMPLETE; break; } *((MPR_INTERFACE_0*)pvInfo) = *pInfo; MprAdminBufferFree(pInfo); } else { dwErr = MprConfigInterfaceGetHandle(g_hMprConfig, pwszIfName, &hIfCfg); if(dwErr isnot NO_ERROR) { break; } dwErr = MprConfigInterfaceGetInfo(g_hMprConfig, hIfCfg, 0, (PBYTE *)&pInfo, &dwSize); if(dwErr isnot NO_ERROR) { break; } *((MPR_INTERFACE_0*)pvInfo) = *pInfo; MprConfigBufferFree(pInfo); } } while(FALSE); return dwErr; } DWORD RtrdbInterfaceWrite( IN PWCHAR pwszIfName, IN DWORD dwLevel, IN PVOID pvInfo ) { DWORD dwErr; HANDLE hIfCfg = NULL; MPR_INTERFACE_0* pIfInfo = (MPR_INTERFACE_0*)pvInfo; do { if(IfutlIsRouterRunning()) { dwErr = MprAdminInterfaceSetInfo(g_hMprAdmin, pIfInfo->hInterface, 0, (BYTE*)pIfInfo); if(dwErr isnot NO_ERROR) { break; } dwErr = MprConfigInterfaceGetHandle(g_hMprConfig, pIfInfo->wszInterfaceName, &hIfCfg); if(dwErr isnot NO_ERROR) { break; } dwErr = MprConfigInterfaceSetInfo(g_hMprConfig, hIfCfg, 0, (BYTE*)pIfInfo); if(dwErr isnot NO_ERROR) { break; } } else { dwErr = MprConfigInterfaceSetInfo(g_hMprConfig, pIfInfo->hInterface, 0, (BYTE*)pIfInfo); if(dwErr isnot NO_ERROR) { break; } } } while(FALSE); return dwErr; } DWORD RtrdbInterfaceReadCredentials( IN PWCHAR pszIfName, IN PWCHAR pszUser OPTIONAL, IN PWCHAR pszPassword OPTIONAL, IN PWCHAR pszDomain OPTIONAL ) { MPR_INTERFACE_0 If0; DWORD dwErr = NO_ERROR; do { ZeroMemory(&If0, sizeof(If0)); dwErr = RtrdbInterfaceRead( pszIfName, 0, (PVOID)&If0); BREAK_ON_DWERR(dwErr); if (If0.dwIfType != ROUTER_IF_TYPE_FULL_ROUTER) { DisplayError(g_hModule, EMSG_IF_BAD_CREDENTIALS_TYPE); dwErr = ERROR_CAN_NOT_COMPLETE; break; } // Set the credentials // if (pszUser) { pszUser[0] = L'\0'; } if (pszDomain) { pszDomain[0] = L'\0'; } if (pszPassword) { pszPassword[0] = L'\0'; } dwErr = MprAdminInterfaceGetCredentials( g_pwszRouter, pszIfName, pszUser, NULL, pszDomain); BREAK_ON_DWERR(dwErr); if (pszPassword) { wcscpy(pszPassword, L"**********"); } } while (FALSE); // Cleanup { } return dwErr; } DWORD RtrdbInterfaceWriteCredentials( IN PWCHAR pszIfName, IN PWCHAR pszUser OPTIONAL, IN PWCHAR pszPassword OPTIONAL, IN PWCHAR pszDomain OPTIONAL ) { MPR_INTERFACE_0 If0; DWORD dwErr = NO_ERROR; do { ZeroMemory(&If0, sizeof(If0)); dwErr = RtrdbInterfaceRead( pszIfName, 0, (PVOID)&If0); BREAK_ON_DWERR(dwErr); if (If0.dwIfType != ROUTER_IF_TYPE_FULL_ROUTER) { DisplayError(g_hModule, EMSG_IF_BAD_CREDENTIALS_TYPE); dwErr = ERROR_CAN_NOT_COMPLETE; break; } // Set the credentials // dwErr = MprAdminInterfaceSetCredentials( g_pwszRouter, pszIfName, pszUser, pszDomain, pszPassword); BREAK_ON_DWERR(dwErr); } while (FALSE); // Cleanup { } return dwErr; } DWORD RtrdbInterfaceRename( IN PWCHAR pwszIfName, IN DWORD dwLevel, IN PVOID pvInfo, IN PWCHAR pszNewName) { DWORD dwErr = NO_ERROR; HRESULT hr = S_OK; NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING us; GUID Guid; do { // Get the guid from the interface name // RtlInitUnicodeString(&us, pwszIfName); ntStatus = RtlGUIDFromString(&us, &Guid); if (ntStatus != STATUS_SUCCESS) { dwErr = ERROR_BAD_FORMAT; break; } // Rename the interface // hr = HrRenameConnection(&Guid, pszNewName); if (FAILED(hr)) { dwErr = HRESULT_CODE(hr); break; } } while (FALSE); // Cleanup // { } return dwErr; } DWORD RtrdbResetAll() { RTR_IF_LIST* pList = NULL, *pCur = NULL; DWORD dwErr = NO_ERROR; do { // Build a list of interfaces that can be // deleted // dwErr = RtrdbInterfaceEnumerate( 0, 0, RtrdbAddWanIfToList, (HANDLE)&pList); BREAK_ON_DWERR(dwErr); // Delete all of the interfaces // pCur = pList; while (pCur) { RtrdbInterfaceDelete(pCur->pszName); pCur = pCur->pNext; IfutlFree(pList); pList = pCur; } } while (FALSE); // Cleanup { } return NO_ERROR; }