Platform SDK: Active Directory, ADSI, and Directory Services

Example Code for Checking for an Extended Right in an ACE

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;
}