Platform SDK: Active Directory, ADSI, and Directory Services

Example Code for Setting and Removing SACL and DACL Protection in the Control Property

The following code fragment is a function that sets/removes the SE_DACL_PROTECTED and SE_SACL_PROTECTED bits in the Control property of an object's security descriptor.

// This function sets/removes the SE_DACL_PROTECTED and 
// SE_SACL_PROTECTED bits in the Control property.
// Valid values for lControl:
// 0L means remove both SE_DACL_PROTECTED and SE_SACL_PROTECTED if they are set.
// SE_DACL_PROTECTED means add SE_DACL_PROTECTED and remove SE_SACL_PROTECTED.
// ...and so on.
// Note that SE_DACL_PRESENT must be present to set SE_DACL_PROTECTED
// and SE_SACL_PRESENT must be present to set SE_SACL_PROTECTED.
 
HRESULT SetSDInheritProtect(
                  IADs *pObject,
                  long lControl
                  )
 
{
HRESULT hr = E_FAIL;
 
VARIANT var;
IADsSecurityDescriptor *pSD = NULL;
 
long lSetControl;
bool bChange = FALSE;
 
if (pObject = NULL)
    return hr;
 
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 Control property
            hr = pSD->get_Control(&lSetControl);
            // Parse the lControl and check for the bits in lSetControl
 
            // Check if SE_DACL_PROTECTED needs to be set.
            if (lControl & SE_DACL_PROTECTED)
            {
                // Check if SE_DACL_PROTECTED is NOT set.
                if (!(lSetControl & SE_DACL_PROTECTED))
                {
                    lSetControl = lSetControl | SE_DACL_PROTECTED;
                    bChange = TRUE;
                }
            }
            // SE_DACL_PROTECTED needs to be removed
            else
            {
                if ((lSetControl &SE_DACL_PROTECTED)==SE_DACL_PROTECTED)
                {
                    lSetControl=lSetControl-SE_DACL_PROTECTED;
                    bChange = TRUE;
                }
            }
 
            //Check if SE_SACL_PROTECTED needs to be set.
            if (lControl & SE_SACL_PROTECTED)
            {
                //Check if SE_SACL_PROTECTED is NOT set.
                if (!(lSetControl & SE_SACL_PROTECTED))
                {
                    lSetControl = lSetControl | SE_SACL_PROTECTED;
                    bChange = TRUE;
                }
            }
            //SE_SACL_PROTECTED needs to be removed
            else
            {
                if ((lSetControl &SE_SACL_PROTECTED)==SE_SACL_PROTECTED)
                {
                    lSetControl=lSetControl-SE_SACL_PROTECTED;
                    bChange = TRUE;
                }
            }
 
            //If there was change to the Control property,
            //write it to the Security Descriptor,
            //write the SD to object, and then call SetInfo
            //to write the object to the directory.
            if (bChange)
            {
                hr = pSD->put_Control(lSetControl);
                if (SUCCEEDED(hr))
                {
                    hr = pObject->Put(szAttribute,var);
                    if (SUCCEEDED(hr))
                    {
                        hr = pObject->SetInfo();
                    }
                }
            }
        }
        if (pSD)
           pSD->Release();
    }
}
VariantClear(&var);
return hr;
}