windows-nt/Source/XPSP1/NT/net/config/common/ncbase/trnrgsec.cpp
2020-09-26 16:20:57 +08:00

155 lines
4.5 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: T R N R G S E C . C P P
//
// Contents: Atomic application of security to registry keys
//
//
// Notes:
//
// Author: ckotze 10 July 2000
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include <ncreg.h>
#include <regkysec.h>
#include <trnrgsec.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTransactedRegistrySecurity::CTransactedRegistrySecurity()
{
m_listTransaction.clear();
}
CTransactedRegistrySecurity::~CTransactedRegistrySecurity()
{
}
//+---------------------------------------------------------------------------
//
// Function: SetPermissionsForKeysFromList
//
// Purpose: Returns a HRESULT that is either S_OK or E_ABORT. E_ABORT
// specifies that the transaction was cancelled and rolled back.
//
// Arguments:
// psidUserOrGroup - The Security Identifier for the user or group that
// needs have it's security changed on certain keys.
// listRegKeyApply - An stl list of REGKEYDATA for the different keys and
// the different permissions to set on those keys.
// bGrantRights - Are we granting or revoke rights?
//
// Returns: S_OK if the permissions is set correctly, and error code otherwise
//
// Author: ckotze 10 July 2000
//
// Notes:
//
HRESULT CTransactedRegistrySecurity::SetPermissionsForKeysFromList(PCSID psidUserOrGroup, LISTREGKEYDATA& listRegKeyApply, BOOL bGrantRights)
{
HRESULT hr = E_FAIL;
BOOL bAbort = FALSE;
Assert(psidUserOrGroup != NULL);
Assert(listRegKeyApply.size() > 0);
for (REGKEYDATAITER i = listRegKeyApply.begin(); i != listRegKeyApply.end(); i++)
{
REGKEYDATA rkdInfo = *i;
hr = ApplySecurityToKey(psidUserOrGroup, rkdInfo, bGrantRights);
// We might return S_FALSE if we didn't change anything and we don't want to add it to the list
if (S_OK == hr)
{
m_listTransaction.insert(m_listTransaction.end(), rkdInfo);
}
else if (FAILED(hr) && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
{
bAbort = TRUE;
break;
}
}
if(bAbort)
{
for (REGKEYDATAITER i = m_listTransaction.end(); i != m_listTransaction.begin(); i++)
{
REGKEYDATA rkdInfo = *i;
hr = ApplySecurityToKey(psidUserOrGroup, rkdInfo, !bGrantRights);
}
hr = E_ABORT;
}
else
{
hr = S_OK;
}
m_listTransaction.clear();
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: SetPermissionsForKeysFromList
//
// Purpose: Returns a HRESULT that is either S_OK or E_ABORT. E_ABORT
// specifies that the transaction was cancelled and rolled back.
//
// Arguments:
// psidUserOrGroup - The Security Identifier for the user or group that
// needs have it's security changed on certain keys.
// rkdInfo - A REGKEYDATA structure for this key.
//
// bGrantRights - Are we granting or revoke rights?
//
// Returns: S_OK if the permissions is set correctly, and error code otherwise
//
// Author: ckotze 10 July 2000
//
// Notes:
//
HRESULT CTransactedRegistrySecurity::ApplySecurityToKey(PCSID psidUserOrGroup, const REGKEYDATA rkdInfo, const BOOL bGrantRights)
{
HRESULT hr = S_OK;
hr = RegOpenKey(rkdInfo.hkeyRoot, rkdInfo.strKeyName.c_str());
if (SUCCEEDED(hr))
{
hr = GetKeySecurity();
if (SUCCEEDED(hr))
{
hr = GetSecurityDescriptorDacl();
if (SUCCEEDED(hr))
{
if (bGrantRights)
{
hr = GrantRightsOnRegKey(psidUserOrGroup, rkdInfo.amMask, rkdInfo.kamMask);
}
else
{
hr = RevokeRightsOnRegKey(psidUserOrGroup, rkdInfo.amMask, rkdInfo.kamMask);
}
}
}
// we actually need the hr from the call above so we just assert here instead of returning the HRESULT
Assert(SUCCEEDED(RegCloseKey()));
}
return hr;
}