Directory Services |
The following code example demonstrates how to add an ACE for a control access right to the ACL of an object.
[C++]
/***************************************************************************
SetExtendedRight()
This function takes the rightsGUID in StringFromGUID2 format and assumes
it is the GUID for the correct control access right. For control access
rights in a DACL, lAccessType must be ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
or ADS_ACETYPE_ACCESS_DENIED_OBJECT.
***************************************************************************/
HRESULT SetExtendedRight(IADs *pObject,
LPWSTR pwszRightsGUID,
LONG lAccessType,
LONG fInheritanceFlags,
LONG fAppliesToObjectType,
LPWSTR pwszTrustee)
{
if(!pObject || !pwszRightsGUID || !pwszTrustee)
{
return E_INVALIDARG;
}
if((lAccessType != ADS_ACETYPE_ACCESS_ALLOWED_OBJECT) &&
(lAccessType != ADS_ACETYPE_ACCESS_DENIED_OBJECT))
{
return E_INVALIDARG;
}
HRESULT hr;
// Get the nTSecurityDescriptor attribute.
CComBSTR sbstrNTSecDesc = L"nTSecurityDescriptor";
CComVariant svarSecDesc;
hr = pObject->Get(sbstrNTSecDesc, &svarSecDesc);
if(FAILED(hr))
{
return hr;
}
/*
The type should be VT_DISPATCH which is an IDispatch pointer to the
security descriptor object.
*/
if(VT_DISPATCH != svarSecDesc.vt)
{
return E_FAIL;
}
// Get the IADsSecurityDescriptor interface from the IDispatch pointer.
CComPtr<IADsSecurityDescriptor> spSecDesc;
hr = svarSecDesc.pdispVal->QueryInterface(IID_IADsSecurityDescriptor, (void**)&spSecDesc);
if(FAILED(hr))
{
return hr;
}
// Get the DACL object.
CComPtr<IDispatch> spDispDACL;
hr = spSecDesc->get_DiscretionaryAcl(&spDispDACL);
if(FAILED(hr))
{
return hr;
}
// Get the IADsAccessControlList interface from the DACL object.
CComPtr<IADsAccessControlList> spACL;
hr = spDispDACL->QueryInterface(IID_IADsAccessControlList, (void**)&spACL);
if(FAILED(hr))
{
return hr;
}
// Create the COM object for the new ACE.
CComPtr<IADsAccessControlEntry> spACE;
hr = CoCreateInstance(CLSID_AccessControlEntry,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsAccessControlEntry,
(void **)&spACE);
if(FAILED(hr))
{
return hr;
}
// Set the properties of the new ACE.
/*
For an extended control access right, set the mask to
ADS_RIGHT_DS_CONTROL_ACCESS.
*/
hr = spACE->put_AccessMask(ADS_RIGHT_DS_CONTROL_ACCESS);
if(FAILED(hr))
{
return hr;
}
// Set the trustee.
hr = spACE->put_Trustee(pwszTrustee);
if(FAILED(hr))
{
return hr;
}
/*
For extended control access rights, set AceType to
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT or ADS_ACETYPE_ACCESS_DENIED_OBJECT.
*/
hr = spACE->put_AceType(lAccessType);
if(FAILED(hr))
{
return hr;
}
/*
For this example, set the AceFlags so that ACE is not inherited by child
objects.
*/
hr = spACE->put_AceFlags(fInheritanceFlags);
if(FAILED(hr))
{
return hr;
}
/*
Flags specifies whether the ACE applies to the current object, child objects,
or both. For this example, fAppliesToInheritedObject is set to
ADS_FLAG_OBJECT_TYPE_PRESENT so that the right applies only to the current
object.
*/
hr = spACE->put_Flags(fAppliesToObjectType);
if(FAILED(hr))
{
return hr;
}
/*
For extended control access rights, set ObjectType to the rightsGUID of the
extended right.
*/
if(fAppliesToObjectType & ADS_FLAG_OBJECT_TYPE_PRESENT)
{
hr = spACE->put_ObjectType(pwszRightsGUID);
if(FAILED(hr))
{
return hr;
}
}
// Set the inherited object type if right applies to child objects.
if(fAppliesToObjectType & ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT)
{
hr = spACE->put_InheritedObjectType(pwszRightsGUID);
if(FAILED(hr))
{
return hr;
}
}
// Get the IDispatch pointer for the ACE.
CComPtr<IDispatch> spDispACE;
hr = spACE->QueryInterface(IID_IDispatch, (void**)&spDispACE);
if(FAILED(hr))
{
return hr;
}
// Add the ACE to the ACL.
hr = spACL->AddAce(spDispACE);
if(FAILED(hr))
{
return hr;
}
// Update the DACL property.
hr = spSecDesc->put_DiscretionaryAcl(spDispDACL);
if(FAILED(hr))
{
return hr;
}
/*
Write the updated value for the ntSecurityDescriptor attribute to the
property cache.
*/
hr = pObject->Put(sbstrNTSecDesc, svarSecDesc);
if(FAILED(hr))
{
return hr;
}
// Call SetInfo to update the property on the object in the directory.
hr = pObject->SetInfo();
return hr;
}