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.
496 lines
11 KiB
496 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1992-1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
trapmgrs.c
|
|
|
|
Abstract:
|
|
|
|
Contains routines for manipulating trap destination structures.
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
10-Feb-1997 DonRyan
|
|
Rewrote to implement SNMPv2 support.
|
|
|
|
--*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Include files //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "globals.h"
|
|
#include "snmpmgrs.h"
|
|
#include "trapmgrs.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Private procedures //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
FindTrapDestination(
|
|
PTRAP_DESTINATION_LIST_ENTRY * ppTLE,
|
|
LPSTR pCommunity
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Locates valid trap destination in list.
|
|
|
|
Arguments:
|
|
|
|
ppTLE - pointer to receive pointer to entry.
|
|
|
|
pCommunity - pointer to trap destination to find.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
PLIST_ENTRY pLE;
|
|
PTRAP_DESTINATION_LIST_ENTRY pTLE;
|
|
|
|
// initialize
|
|
*ppTLE = NULL;
|
|
|
|
// obtain pointer to list head
|
|
pLE = g_TrapDestinations.Flink;
|
|
|
|
// process all entries in list
|
|
while (pLE != &g_TrapDestinations) {
|
|
|
|
// retrieve pointer to trap destination structure
|
|
pTLE = CONTAINING_RECORD(pLE, TRAP_DESTINATION_LIST_ENTRY, Link);
|
|
|
|
// compare trap destination string with entry
|
|
if (!strcmp(pTLE->pCommunity, pCommunity)) {
|
|
|
|
// transfer
|
|
*ppTLE = pTLE;
|
|
|
|
// success
|
|
return TRUE;
|
|
}
|
|
|
|
// next entry
|
|
pLE = pLE->Flink;
|
|
}
|
|
|
|
// failure
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
AddTrapDestination(
|
|
HKEY hKey,
|
|
LPWSTR pwCommunity
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Adds trap destination to list.
|
|
|
|
Arguments:
|
|
|
|
hKey - trap destination subkey.
|
|
|
|
pwCommunity - pointer to trap destination to add.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
HKEY hSubKey;
|
|
LONG lStatus;
|
|
BOOL fOk = FALSE;
|
|
PTRAP_DESTINATION_LIST_ENTRY pTLE = NULL;
|
|
LPSTR pCommunity = NULL;
|
|
|
|
// open registry subkey
|
|
lStatus = RegOpenKeyExW(
|
|
hKey,
|
|
pwCommunity,
|
|
0,
|
|
KEY_READ,
|
|
&hSubKey
|
|
);
|
|
|
|
// validate return code
|
|
if (lStatus == ERROR_SUCCESS &&
|
|
SnmpUtilUnicodeToUTF8(
|
|
&pCommunity,
|
|
pwCommunity,
|
|
TRUE) == 0) {
|
|
|
|
// attempt to locate in list
|
|
if (FindTrapDestination(&pTLE, pCommunity)) {
|
|
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: SVC: updating trap destinations for %s.\n",
|
|
pCommunity
|
|
));
|
|
|
|
// load associated managers
|
|
LoadManagers(hSubKey, &pTLE->Managers);
|
|
|
|
// success
|
|
fOk = TRUE;
|
|
|
|
} else {
|
|
|
|
// allocate trap destination structure
|
|
if (AllocTLE(&pTLE, pCommunity)) {
|
|
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: SVC: adding trap destinations for %s.\n",
|
|
pCommunity
|
|
));
|
|
|
|
// load associated managers
|
|
if (LoadManagers(hSubKey, &pTLE->Managers)) {
|
|
|
|
// insert into valid communities list
|
|
InsertTailList(&g_TrapDestinations, &pTLE->Link);
|
|
|
|
// success
|
|
fOk = TRUE;
|
|
}
|
|
|
|
// cleanup
|
|
if (!fOk) {
|
|
|
|
// release
|
|
FreeTLE(pTLE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// release subkey
|
|
RegCloseKey(hSubKey);
|
|
|
|
SnmpUtilMemFree(pCommunity);
|
|
}
|
|
|
|
return fOk;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Public procedures //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL
|
|
AllocTLE(
|
|
PTRAP_DESTINATION_LIST_ENTRY * ppTLE,
|
|
LPSTR pCommunity
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocates trap destination structure and initializes.
|
|
|
|
Arguments:
|
|
|
|
ppTLE - pointer to receive pointer to entry.
|
|
|
|
pCommunity - pointer to trap destination string.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL fOk = FALSE;
|
|
PTRAP_DESTINATION_LIST_ENTRY pTLE = NULL;
|
|
|
|
// attempt to allocate structure
|
|
pTLE = AgentMemAlloc(sizeof(TRAP_DESTINATION_LIST_ENTRY));
|
|
|
|
// validate
|
|
if (pTLE != NULL) {
|
|
|
|
// allocate memory for trap destination string
|
|
pTLE->pCommunity = AgentMemAlloc(strlen(pCommunity)+1);
|
|
|
|
// validate
|
|
if (pTLE->pCommunity != NULL) {
|
|
|
|
// transfer trap destination string
|
|
strcpy(pTLE->pCommunity, pCommunity);
|
|
|
|
// initialize list of managers
|
|
InitializeListHead(&pTLE->Managers);
|
|
|
|
// success
|
|
fOk = TRUE;
|
|
}
|
|
|
|
// cleanup
|
|
if (!fOk) {
|
|
|
|
// release
|
|
FreeTLE(pTLE);
|
|
|
|
// re-init
|
|
pTLE = NULL;
|
|
}
|
|
}
|
|
|
|
// transfer
|
|
*ppTLE = pTLE;
|
|
|
|
return fOk;
|
|
}
|
|
|
|
|
|
BOOL
|
|
FreeTLE(
|
|
PTRAP_DESTINATION_LIST_ENTRY pTLE
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Releases trap destination structure.
|
|
|
|
Arguments:
|
|
|
|
pTLE - pointer to trap destination list entry to be freed.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL fOk = TRUE;
|
|
|
|
// validate pointer
|
|
if (pTLE != NULL) {
|
|
|
|
// release manager structures
|
|
UnloadManagers(&pTLE->Managers);
|
|
|
|
// release string
|
|
AgentMemFree(pTLE->pCommunity);
|
|
|
|
// release structure
|
|
AgentMemFree(pTLE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
LoadTrapDestinations(
|
|
BOOL bFirstCall
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructs list of trap destinations.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
HKEY hKey;
|
|
LONG lStatus;
|
|
DWORD dwIndex;
|
|
WCHAR wszName[MAX_PATH+1];
|
|
BOOL fPolicy;
|
|
LPTSTR pszKey;
|
|
BOOL fOk = FALSE;
|
|
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: SVC: loading trap destinations.\n"
|
|
));
|
|
|
|
#ifdef _POLICY
|
|
// we need to provide precedence to the parameters set through the policy
|
|
fPolicy = TRUE;
|
|
#else
|
|
fPolicy = FALSE;
|
|
#endif
|
|
|
|
do
|
|
{
|
|
// if the policy is to be enforced, check the policy registry location first
|
|
pszKey = fPolicy ? REG_POLICY_TRAP_DESTINATIONS : REG_KEY_TRAP_DESTINATIONS;
|
|
|
|
// open registry subkey
|
|
lStatus = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
pszKey,
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
);
|
|
// if the call succeeded or we were not checking the policy, break the loop
|
|
if (lStatus == ERROR_SUCCESS || !fPolicy)
|
|
break;
|
|
|
|
// being at this point, this means we were checking for the policy parameters.
|
|
// If and only if the policy is not defined (registry key is missing) we
|
|
// reset the error, mark 'fPolicy already tried' and go back into the loop
|
|
if (lStatus == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
lStatus = ERROR_SUCCESS;
|
|
fPolicy = FALSE;
|
|
}
|
|
} while (lStatus == ERROR_SUCCESS);
|
|
|
|
// validate return code
|
|
if (lStatus == ERROR_SUCCESS) {
|
|
|
|
// initialize
|
|
dwIndex = 0;
|
|
|
|
// loop until error or end of list
|
|
while (lStatus == ERROR_SUCCESS) {
|
|
|
|
// read next value
|
|
lStatus = RegEnumKeyW(
|
|
hKey,
|
|
dwIndex,
|
|
wszName,
|
|
sizeof(wszName) / sizeof(wszName[0])
|
|
);
|
|
|
|
// validate return code
|
|
if (lStatus == ERROR_SUCCESS) {
|
|
|
|
// add trap destination to list
|
|
if (AddTrapDestination(hKey, wszName)) {
|
|
|
|
// next
|
|
dwIndex++;
|
|
|
|
} else {
|
|
|
|
// reset status to reflect failure
|
|
lStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
} else if (lStatus == ERROR_NO_MORE_ITEMS) {
|
|
|
|
// success
|
|
fOk = TRUE;
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
// it doesn't matter how the values are, the key has to exist,
|
|
// so mark as bFirstCall in order to log an event if this is not true.
|
|
bFirstCall = TRUE;
|
|
|
|
if (!fOk) {
|
|
|
|
SNMPDBG((
|
|
SNMP_LOG_ERROR,
|
|
"SNMP: SVC: error %d processing TrapDestinations subkey.\n",
|
|
lStatus
|
|
));
|
|
|
|
// log an event only if on first call (service initialization)
|
|
// otherwise, due to registry operations through regedit, the event log
|
|
// might get flooded with records
|
|
if (bFirstCall)
|
|
// report event
|
|
ReportSnmpEvent(
|
|
SNMP_EVENT_INVALID_REGISTRY_KEY,
|
|
1,
|
|
&pszKey,
|
|
lStatus
|
|
);
|
|
}
|
|
|
|
return fOk;
|
|
}
|
|
|
|
|
|
BOOL
|
|
UnloadTrapDestinations(
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destroys list of trap destinations.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Values:
|
|
|
|
Returns true if successful.
|
|
|
|
--*/
|
|
|
|
{
|
|
PLIST_ENTRY pLE;
|
|
PTRAP_DESTINATION_LIST_ENTRY pTLE;
|
|
|
|
// process entries until list is empty
|
|
while (!IsListEmpty(&g_TrapDestinations)) {
|
|
|
|
// extract next entry from head of list
|
|
pLE = RemoveHeadList(&g_TrapDestinations);
|
|
|
|
// retrieve pointer to trap destination structure
|
|
pTLE = CONTAINING_RECORD(pLE, TRAP_DESTINATION_LIST_ENTRY, Link);
|
|
|
|
// release
|
|
FreeTLE(pTLE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|