|
|
#include "pch.h"
#pragma hdrstop
#include <aclapi.h>
#include "netoc.h"
#include "ncreg.h"
#include "snmpocx.h"
// Under opened registry subkey hKey,
// removes the registry value name who has a value data of pwszRegValData
// if it exists.
HRESULT HrSnmpRegDeleteValueData( IN HKEY hKey, IN LPCWSTR pwszRegValData) { HRESULT hr = S_OK; DWORD dwIndex = 0; DWORD dwNameSize; DWORD dwValueSize; DWORD dwValueType; WCHAR wszName[MAX_PATH]; WCHAR wszValue[MAX_PATH];
Assert (hKey); Assert (pwszRegValData);
// initialize buffer sizes
dwNameSize = sizeof(wszName) / sizeof(wszName[0]); // size in number of TCHARs
dwValueSize = sizeof(wszValue); // size in number of bytes
// loop until error, end of list, or found subagent to be removed
while (S_OK == hr) { // read next value
hr = HrRegEnumValue( hKey, dwIndex, wszName, &dwNameSize, &dwValueType, (LPBYTE)wszValue, &dwValueSize ); // validate return code
if (S_OK == hr) { // see if the subagent value data matched the one to be removed
if (!wcscmp(pwszRegValData, wszValue)) { hr = HrRegDeleteValue(hKey, wszName); if (S_OK != hr) { TraceTag(ttidError, "SnmpNetOc: HrRegDeleteValue: failed to delete %S. hr = %x.", wszName, hr); } break; } // re-initialize buffer sizes
dwNameSize = sizeof(wszName) / sizeof(wszName[0]); // size in number of TCHARs
dwValueSize = sizeof(wszValue); // size in number of bytes
// next
dwIndex++; } else if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) { // success
break; } } return hr; }
// Removes Subagent Configuration from registry according to the given
// array of SUBAGENT_REMOVAL_INFO
HRESULT SnmpRemoveSubAgents ( IN const SUBAGENT_REMOVAL_INFO * prgSRI, // array of SUBAGENT_REMOVAL_INFO
IN UINT cParams // number of elements in the arrary
) { if ((NULL == prgSRI) || (0 == cParams)) { TraceError( "No Subagents need to be removed.", S_FALSE); return S_FALSE; } HRESULT hr = S_OK; HRESULT hrTmp = S_OK; UINT i = 0; HKEY hKey = NULL;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_EXTENSION_AGENTS, KEY_READ | KEY_WRITE, &hKey); if (S_OK != hr) { TraceTag(ttidError, "SnmpNetOc: HrRegOpenKeyEx: failed to open %S. hr = %x.", REG_KEY_EXTENSION_AGENTS, hr); return hr; }
for (i = 0; i < cParams; i++) { hrTmp = S_OK; if ( // removal from all SKU AND has valid registry info
(!prgSRI[i].pfnFRemoveSubagent && prgSRI[i].pwszRegKey && prgSRI[i].pwszRegValData) || // removal depending on given function and has valid registry info
(prgSRI[i].pfnFRemoveSubagent && (*(prgSRI[i].pfnFRemoveSubagent))() && prgSRI[i].pwszRegKey && prgSRI[i].pwszRegValData) ) { // removes everything under subagent registry key if it exits
hrTmp = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, prgSRI[i].pwszRegKey); if (S_OK != hrTmp) { TraceTag(ttidError, "SnmpNetOc: HrRegDeleteKeyTree: failed to delete %S. hr = %x.", prgSRI[i].pwszRegKey, hrTmp); }
// Under registry subkey of REG_KEY_EXTENSION_AGENTS,
// removes the registry value name who has value data identical to
// pwszRegKey.
hrTmp = HrSnmpRegDeleteValueData(hKey, prgSRI[i].pwszRegValData); if (S_OK != hrTmp) { TraceTag(ttidError, "SnmpNetOc: HrSnmpRegDeleteValueData: failed to delete %S value data. hr = %x.", prgSRI[i].pwszRegValData, hrTmp); }
} } RegSafeCloseKey(hKey); //we dont pass the error of hrTmp out of this function because
//there is not much we can do with this error
return hr; }
// Allocates an admin ACL to be used with security descriptor
PACL AllocACL() { PACL pAcl = NULL; PSID pSidAdmins = NULL; SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;
EXPLICIT_ACCESS ea[1];
// Create a SID for the BUILTIN\Administrators group.
if ( !AllocateAndInitializeSid( &Authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSidAdmins )) { return NULL; }
// Initialize an EXPLICIT_ACCESS structure for an ACE.
ZeroMemory(&ea, 1 * sizeof(EXPLICIT_ACCESS)); // The ACE will allow the Administrators group full access to the key.
ea[0].grfAccessPermissions = KEY_ALL_ACCESS; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance= NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP; ea[0].Trustee.ptstrName = (LPTSTR) pSidAdmins;
// Create a new ACL that contains the new ACEs.
if (SetEntriesInAcl(1, ea, NULL, &pAcl) != ERROR_SUCCESS) { TraceError( "SetEntriesInAcl Error", GetLastError() ); FreeSid(pSidAdmins); return NULL; }
FreeSid(pSidAdmins);
return pAcl; } // frees a ACL
void FreeACL( PACL pAcl) { if (pAcl != NULL) LocalFree(pAcl); }
HRESULT SnmpAddAdminAclToKey(PWSTR pwszKey) { HKEY hKey = NULL; HRESULT hr; PACL pAcl = NULL; SECURITY_DESCRIPTOR S_Desc;
if (pwszKey == NULL) return S_FALSE; // open registy key
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, pwszKey, // subkey name
KEY_ALL_ACCESS, // want WRITE_DAC,
&hKey // handle to open key
); if (hr != S_OK) { TraceError("SnmpAddAdminDaclToKey::HrRegOpenKeyEx", hr); return hr; } // Initialize a security descriptor.
if (InitializeSecurityDescriptor (&S_Desc, SECURITY_DESCRIPTOR_REVISION) == 0) { RegSafeCloseKey(hKey); TraceError("SnmpAddAdminDaclToKey::InitializeSecurityDescriptor", GetLastError()); return S_FALSE; }
// get the ACL and put it into the security descriptor
if ( (pAcl = AllocACL()) != NULL ) { if (!SetSecurityDescriptorDacl (&S_Desc, TRUE, pAcl, FALSE)) { FreeACL(pAcl); RegSafeCloseKey(hKey); TraceError("SnmpAddAdminDaclToKey::SetSecurityDescriptorDacl Failed.", GetLastError()); return S_FALSE; } } else { RegSafeCloseKey(hKey); TraceError("SnmpAddAdminAclToKey::AllocACL Failed.", GetLastError()); return S_FALSE; }
if (RegSetKeySecurity (hKey, DACL_SECURITY_INFORMATION, &S_Desc) != ERROR_SUCCESS) { FreeACL(pAcl); RegSafeCloseKey(hKey); TraceError("SnmpAddAdminDaclToKey::RegSetKeySecurity", GetLastError()); return S_FALSE; }
FreeACL(pAcl); RegSafeCloseKey(hKey); return S_OK; }
HRESULT SnmpRegWriteDword(PWSTR pszRegKey, PWSTR pszValueName, DWORD dwValueData) { HRESULT hr; HKEY hKey;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, pszRegKey, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL); if (hr != S_OK) { return hr; }
hr = HrRegSetDword(hKey, pszValueName, dwValueData);
RegSafeCloseKey(hKey);
return hr; }
HRESULT SnmpRegUpgEnableAuthTraps() { HRESULT hr = S_OK; HKEY hKey;
// open the ..SNMP\Parameters registry key
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_AUTHENTICATION_TRAPS, KEY_QUERY_VALUE, &hKey);
// if successful, look for EnableAuthenticationTrap switch
// in the old registry location
if (hr == S_OK) { DWORD dwAuthTrap;
// get the value of the old 'switch' parameter
hr = HrRegQueryDword(hKey, REG_VALUE_SWITCH, &dwAuthTrap);
// if successful transfer the value to the new location
// if this fails, it means the SNMP service worked with the default value
// which is already installed through the inf file.
if (hr == S_OK) { hr = SnmpRegWriteDword(REG_KEY_SNMP_PARAMETERS, REG_VALUE_AUTHENTICATION_TRAPS, dwAuthTrap); }
// close and delete the old registry key as it is obsolete
RegSafeCloseKey(hKey); HrRegDeleteKey (HKEY_LOCAL_MACHINE, REG_KEY_AUTHENTICATION_TRAPS); }
return hr;
}
HRESULT SnmpRegWriteCommunities(PWSTR pszCommArray) { HRESULT hr; HKEY hKey; PWSTR pszComm, pszAccess; DWORD dwAccess;
hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE, REG_KEY_VALID_COMMUNITIES);
if (hr != S_OK) { return hr; }
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_VALID_COMMUNITIES, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL);
if (hr != S_OK) { return hr; }
pszComm = pszCommArray; while (*pszComm != L'\0') { dwAccess = SEC_READ_ONLY_VALUE; pszAccess = wcschr(pszComm, L':'); if (pszAccess != NULL) { *pszAccess = L'\0'; pszAccess++;
if (_wcsicmp(pszAccess, SEC_NONE_NAME)==0) { dwAccess = SEC_NONE_VALUE; } if (_wcsicmp(pszAccess, SEC_NOTIFY_NAME)==0) { dwAccess = SEC_NOTIFY_VALUE; } if (_wcsicmp(pszAccess, SEC_READ_ONLY_NAME)==0) { dwAccess = SEC_READ_ONLY_VALUE; } if (_wcsicmp(pszAccess, SEC_READ_WRITE_NAME)==0) { dwAccess = SEC_READ_WRITE_VALUE; } if (_wcsicmp(pszAccess, SEC_READ_CREATE_NAME)==0) { dwAccess = SEC_READ_CREATE_VALUE; } }
hr = HrRegSetDword(hKey, pszComm, dwAccess); if (hr != S_OK) { break; } if (pszAccess != NULL) { pszComm = pszAccess; } pszComm += (wcslen(pszComm) + 1); }
RegSafeCloseKey(hKey); return hr; }
HRESULT SnmpRegWritePermittedMgrs(BOOL bAnyHost, PWSTR pMgrsList) { HRESULT hr; HKEY hKey; UINT nMgr = 1; WCHAR szMgr[16];
hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE, REG_KEY_PERMITTED_MANAGERS);
if (hr != S_OK) { return hr; }
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_PERMITTED_MANAGERS, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL);
if (hr != S_OK) { return hr; }
if (bAnyHost) { RegSafeCloseKey(hKey); return hr; }
AssertSz(pMgrsList, "pMgrsList is NULL and bAnyHost is FALSE in SnmpRegWritePermittedMgrs"); while(*pMgrsList != L'\0') { swprintf(szMgr, L"%d", nMgr++); hr = HrRegSetSz(hKey, szMgr, pMgrsList); if (hr != S_OK) break; pMgrsList += wcslen(pMgrsList) + 1; }
RegSafeCloseKey(hKey);
return hr; }
HRESULT SnmpRegWriteTraps(tstring tstrVariable, PWSTR pTstrArray) { HKEY hKey, hKeyTrap; HRESULT hr = S_OK; UINT nTrap = 1; WCHAR szTrap[16];
hr = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, REG_KEY_TRAP_DESTINATIONS);
if (hr != S_OK) return hr;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_TRAP_DESTINATIONS, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL);
if (hr != S_OK) return hr;
hr = HrRegCreateKeyEx(hKey, tstrVariable.c_str(), 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKeyTrap, NULL); if (hr == S_OK) { // it might just happen that you want to create a
// community but you don't have the trap destination
// addresses yet. We should let this happen.
if (pTstrArray != NULL) { while(*pTstrArray != L'\0') { swprintf(szTrap, L"%d", nTrap++); hr = HrRegSetSz(hKeyTrap, szTrap, pTstrArray); if (hr != S_OK) break; pTstrArray += wcslen(pTstrArray) + 1; } }
RegSafeCloseKey(hKeyTrap); }
RegSafeCloseKey(hKey);
return hr; }
HRESULT SnmpRegWriteTstring(PWSTR pRegKey, PWSTR pValueName, tstring tstrValueData) { HRESULT hr = S_OK; HKEY hKey;
hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, pRegKey, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL); if (hr != S_OK) return hr;
hr = HrRegSetString(hKey, pValueName, tstrValueData);
RegSafeCloseKey(hKey);
return hr; }
DWORD SnmpStrArrayToServices(PWSTR pSrvArray) { DWORD dwServices = 0;
while(*pSrvArray) { if(_wcsicmp(pSrvArray, SRV_AGNT_PHYSICAL_NAME)==0) dwServices |= SRV_AGNT_PHYSICAL_VALUE; if(_wcsicmp(pSrvArray, SRV_AGNT_DATALINK_NAME)==0) dwServices |= SRV_AGNT_DATALINK_VALUE; if(_wcsicmp(pSrvArray, SRV_AGNT_ENDTOEND_NAME)==0) dwServices |= SRV_AGNT_ENDTOEND_VALUE; if(_wcsicmp(pSrvArray, SRV_AGNT_INTERNET_NAME)==0) dwServices |= SRV_AGNT_INTERNET_VALUE; if(_wcsicmp(pSrvArray, SRV_AGNT_APPLICATIONS_NAME)==0) dwServices |= SRV_AGNT_APPLICATIONS_VALUE;
pSrvArray += wcslen(pSrvArray) + 1; } return dwServices; }
|