| Platform SDK: Active Directory, ADSI, and Directory Services |
The following code fragment is a function that checks for a specified extended right in an ACE in the ACL of the specified object:
//DESCRIPTION: ReadExtendedRight checks for the specified extended right on the specified object.
//If an ACE with that extended right exists, it displays (using printf)
//the trustee and ACE type for the extended right.
//FLOW: Get the security descriptor of an object, get the ACL,
//enumerate the ACEs, check for extended rights ACEs,
//check for the specified right, and display the trustee and ACE type.
//NOTES: The pszRightsGUID UNICODE string should be a string
//containing the rightsGUID property value of the extended right
//and the string should have the same format as the COM Library
//function StringFromGUID2.
//For example:
//LPOLESTR pszRightsGUID = L"{8186e976-4d8a-11d2-95dd-0000f875b660}";
//The pbExists parameter specifies a BOOL that will receive
//TRUE if an ACE with the specified right exists; otherwise, FALSE.
HRESULT ReadExtendedRight(
IADs *pObject,
LPOLESTR pszRightsGUID,
BOOL *pbExists
)
{
BOOL bExists = FALSE;
VARIANT var,varACE;
HRESULT hr = E_FAIL;
IADsSecurityDescriptor *pSD = NULL;
IADsAccessControlList *pACL = NULL;
IDispatch *pDisp = NULL;
LPUNKNOWN pUnk = NULL;
ULONG lFetch;
BSTR szObjectType, szTrustee;
IEnumVARIANT *pEnum = NULL;
IADsAccessControlEntry *pACE = NULL;
IDispatch *pDispatch = NULL;
long lAceType, lAccessMask, lTypeFlag;
if (pObject)
{
VariantClear(&var);
//Get the nTSecurityDescriptor
LPOLESTR szAttribute = L"nTSecurityDescriptor";
hr = pObject->Get(szAttribute,&var);
if (SUCCEEDED(hr))
{
//Type should be VT_DISPATCH--an IDispatch ptr to the security descriptor object.
if (var.vt==VT_DISPATCH)
{
//Use V_DISPATCH macro to get the IDispatch pointer from VARIANT structure
//and QI for IADsSecurityDescriptor ptr.
hr = V_DISPATCH( &var )->QueryInterface(IID_IADsSecurityDescriptor,(void**)&pSD);
if (SUCCEEDED(hr))
{
//Get the DACL
hr = pSD->get_DiscretionaryAcl(&pDisp);
if (SUCCEEDED(hr))
{
//QI for IADsAccessControlList interface
hr = pDisp->QueryInterface(IID_IADsAccessControlList,(void**)&pACL);
if (SUCCEEDED(hr))
{
//Enumerate the ACEs in the ACL.
hr = pACL->get__NewEnum( &pUnk );
if (SUCCEEDED(hr))
{
hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) &pEnum );
if (SUCCEEDED(hr))
{
hr = pEnum->Next( 1, &varACE, &lFetch );
//Loop to read all ACEs on the object.
while( hr == S_OK )
{
//Check if 1 item is returned and returned item is an IDispatch pointer.
if ( (lFetch == 1) && (varACE.vt==VT_DISPATCH))
{
pDispatch = V_DISPATCH(&varACE);
//QI for IADsAccessControlEntry to use to read the ACE.
hr = pDispatch->QueryInterface( IID_IADsAccessControlEntry, (void**)&pACE );
if (SUCCEEDED(hr))
{
hr = pACE->get_AccessMask(&lAccessMask);
//Check for control access right flag to see if this is an ACE for an extended right.
if (lAccessMask & ADS_RIGHT_DS_CONTROL_ACCESS)
{
pACE->get_Flags(&lTypeFlag);
//Check to make sure this ACE applies to an object
if (lTypeFlag & ADS_FLAG_OBJECT_TYPE_PRESENT)
{
//Get the object type GUID and print it.
pACE->get_ObjectType(&szObjectType);
if ( _wcsicmp(szObjectType,pszRightsGUID) == 0 )
{
if (bExists==FALSE)
bExists = TRUE;
printf("\nObjectType: %S\n", szObjectType);
hr = pACE->get_AceType(&lAceType);
if (lAceType == ADS_ACETYPE_ACCESS_ALLOWED_OBJECT)
printf("ACE Type: ADS_ACETYPE_ACCESS_ALLOWED_OBJECT\n");
if (lAceType == ADS_ACETYPE_ACCESS_DENIED_OBJECT)
printf("ACE Type: ADS_ACETYPE_ACCESS_DENIED_OBJECT\n");
//Get the trustee (who the right applies to) and print it.
pACE->get_Trustee(&szTrustee);
printf("Trustee: %S\n", szTrustee);
//Free the string.
if (szTrustee)
SysFreeString(szTrustee);
}
//Free the string.
if (szObjectType)
SysFreeString(szObjectType);
}
}
}
//Clean up the enumerated ACE item.
if (pACE)
pACE->Release();
if (pDispatch)
pDispatch->Release();
}
//Clean up the VARIANT for the ACE item.
VariantClear(&varACE);
//Get the next ACE
hr = pEnum->Next( 1, &varACE, &lFetch );
};//End of While loop
}
//Clean up
if (pEnum)
pEnum->Release();
}
if (pUnk)
pUnk->Release();
}
if (pACL)
pACL->Release();
}
if (pDisp)
pDisp->Release();
}
if (pSD)
pSD->Release();
}
}
VariantClear(&var);
}
*pbExists = bExists;
return hr;
}