Platform SDK: Active Directory, ADSI, and Directory Services

Example Code for Setting an Extended Right ACE

The following code fragment is a function that adds an ACE for an extended right to the ACL of the specified object:

HRESULT SetExtendedRight(
                          IADs *pObject,
                          LPOLESTR pszRightsGUID,
                          LONG lAccessType,
                          LONG fInheritanceFlags,
                          LONG fAppliesToObjectType,
                          LPOLESTR szTrustee
                          )
 
{
 
BOOL bExists = FALSE;
VARIANT var,varACE;
HRESULT hr = E_FAIL;
IADsSecurityDescriptor *pSD = NULL;
IADsAccessControlList *pACL = NULL;
IDispatch *pDisp = NULL;
LPUNKNOWN pUnk = NULL;
ULONG lFetch;
IEnumVARIANT *pEnum = NULL;
IADsAccessControlEntry *pACE = NULL;
IDispatch *pDispatch = NULL;
IDispatch *pDispACE = NULL;
 
//Check params
//This sample takes the rightsGUID in StringFromGUID2 format and assumes it is the GUID for the correct extended right.
//For extended rights in a DACL, lAccessType must be ADS_ACETYPE_ACCESS_ALLOWED_OBJECT or ADS_ACETYPE_ACCESS_DENIED_OBJECT.
if ((lAccessType!=ADS_ACETYPE_ACCESS_ALLOWED_OBJECT)&&(lAccessType!=ADS_ACETYPE_ACCESS_DENIED_OBJECT))
    return E_INVALIDARG;
//This sample takes the szTrustee in an expected naming format and assumes it is the name for the correct trustee.
if (!szTrustee)
    return E_INVALIDARG;
if (!pszRightsGUID)
    return E_INVALIDARG;
 
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 the 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))
                    {
                        //Create the COM object for the new ACE.
                        hr  = CoCreateInstance( 
                                                    CLSID_AccessControlEntry,
                                                    NULL,
                                                    CLSCTX_INPROC_SERVER,
                                                    IID_IADsAccessControlEntry,
                                                    (void **)&pACE
                                                  );
                        if (SUCCEEDED(hr))
                        {
                            //Set the properties of the new ACE.
                            //For extended right, set the mask to ADS_RIGHT_DS_CONTROL_ACCESS.
                            hr = pACE->put_AccessMask(ADS_RIGHT_DS_CONTROL_ACCESS);
                            //Set the trustee.
                            hr = pACE->put_Trustee( szTrustee );
                            //For extended rights, set AceType to ADS_ACETYPE_ACCESS_ALLOWED_OBJECT or ADS_ACETYPE_ACCESS_DENIED_OBJECT.
                            hr = pACE->put_AceType( lAccessType );
                            //For this sample, set AceFlags so that ACE is not inherited by child objects.
                            hr = pACE->put_AceFlags(fInheritanceFlags);
                            //Flags specifies whether the ACE applies to the current object, child objects, or both.
                            //For this sample, fAppliesToInheritedObject is set to ADS_FLAG_OBJECT_TYPE_PRESENT so that the right applies only to the current object.
                            hr = pACE->put_Flags( fAppliesToObjectType );
                            //For extended rights, set ObjectType to the rightsGUID of the extended right.
                            if (fAppliesToObjectType & ADS_FLAG_OBJECT_TYPE_PRESENT)
                            {
                                hr = pACE->put_ObjectType( pszRightsGUID );
                            }
                            //Set the inherited object type if right applies to child objects.
                            if (fAppliesToObjectType & ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT)
                            {
                                hr = pACE->put_InheritedObjectType( pszRightsGUID );
                            }
                            //Add the ACE to the ACL.
                            //Need to QI for IDispatch pointer to pass to the AddAce method.
                            hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDispACE);
                            if (SUCCEEDED(hr))
                            {
                                hr = pACL->AddAce(pDispACE);
                                if (SUCCEEDED(hr))
                                {
                                    //Write the DACL
                                    hr = pSD->put_DiscretionaryAcl(pDisp);
                                    if (SUCCEEDED(hr))
                                    {
                                        //Write the ntSecurityDescriptor property to the property cache.
                                        hr = pObject->Put(szAttribute, var);
                                        if (SUCCEEDED(hr))
                                        {
                                            //Call SetInfo to update the property on the object in the directory.
                                            hr = pObject->SetInfo();
                                        }
                                    }
 
                                }
 
                            }
                            if (pDispACE)
                                pDispACE->Release();
                        }
                        if (pACE)
                            pACE->Release();
                    }
 
                    if (pACL)
                       pACL->Release();
                }
                if (pDisp)
                   pDisp->Release();
            }
            if (pSD)
               pSD->Release();
        }
    }
    VariantClear(&var);
}
return hr;
}