Directory Services

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

The following code example is a function that sets and removes the SE_DACL_PROTECTED and SE_SACL_PROTECTED elements in the IADsSecurityDescriptor.Control property of an object security descriptor.

[C++]
/***************************************************************************

	SetSDInheritProtect()

	This function sets and removes the SE_DACL_PROTECTED and 
	SE_SACL_PROTECTED elements in the Control property. Valid values for 
	lControl are:
		0 - Remove both SE_DACL_PROTECTED and SE_SACL_PROTECTED if they are 
		set.

		SE_DACL_PROTECTED - Add SE_DACL_PROTECTED and remove SE_SACL_PROTECTED.

		SE_SACL_PROTECTED - Add SE_SACL_PROTECTED and remove SE_DACL_PROTECTED.

	Be aware 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)
{
	if(!pObject)
	{
		return E_INVALIDARG;
}

	HRESULT hr = E_FAIL;
	CComVariant svar;
	long lSetControl;
	long lOriginalControl;

	// Get the nTSecurityDescriptor
	CComBSTR sbstrAttribute = "nTSecurityDescriptor";
	hr = pObject->Get(sbstrAttribute, &svar);
	if(FAILED(hr))
	{
		return hr;
}

	/*
	The type should be VT_DISPATCH which is an IDispatch ptr to the security 
	descriptor object.
	*/
	if(svar.vt != VT_DISPATCH)
	{
		return E_FAIL;
}

	/*
	Get the IDispatch pointer from VARIANT structure and QI for 
	IADsSecurityDescriptor ptr.
	*/
	CComPtr<IADsSecurityDescriptor> spSD;
	hr = svar.pdispVal->QueryInterface(IID_IADsSecurityDescriptor, (void**)&spSD);
	if(FAILED(hr))
	{
		return hr;
}

	// Get the Control property.
	hr = spSD->get_Control(&lSetControl);
	if(FAILED(hr))
	{
		return hr;
}

	// Save the original value to see if the value changes.
	lOriginalControl = lSetControl;

	if(lControl & SE_DACL_PROTECTED)
	{
		lSetControl |= SE_DACL_PROTECTED;
		lSetControl &= !SE_SACL_PROTECTED;
}
	else if(lControl & SE_SACL_PROTECTED)
	{
		lSetControl |= SE_SACL_PROTECTED;
		lSetControl &= !SE_DACL_PROTECTED;
}
	else
	{
		lSetControl &= !SE_DACL_PROTECTED;
		lSetControl &= !SE_SACL_PROTECTED;
}

	/*
	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(lOriginalControl != lSetControl)
	{
		hr = spSD->put_Control(lSetControl);
		if(SUCCEEDED(hr))
		{
			hr = pObject->Put(sbstrAttribute, svar);
			if(SUCCEEDED(hr))
			{
				hr = pObject->SetInfo();
		}
	}
}

	return hr;
}