Directory Services

Using IDirectoryObject to Get a Security Descriptor

The following code example uses the IDirectoryObject interface to retrieve the security descriptor of the specified object, create a buffer, copy the security descriptor to the buffer, and return a pointer to a SECURITY_DESCRIPTOR structure that contains the security descriptor data.

HRESULT GetSDFromIDirectoryObject(
	IDirectoryObject *pObject,
	PSECURITY_DESCRIPTOR *pSecurityDescriptor)
{
	HRESULT hr = E_FAIL;
	PADS_ATTR_INFO pAttrInfo;
	DWORD dwReturn= 0;
	LPWSTR pAttrName= L"nTSecurityDescriptor";
	PSECURITY_DESCRIPTOR pSD = NULL;

	if(!pObject || !pSecurityDescriptor)
	{
		return E_INVALIDARG;
}
 
	// Get the nTSecurityDescriptor.
	hr = pObject->GetObjectAttributes( &pAttrName, 
									 1, 
									 &pAttrInfo, 
									 &dwReturn );
	if((FAILED(hr)) || (dwReturn != 1)) 
	{
		wprintf(L" failed: 0x%x\n", hr);
		return hr;
}
 
	// Check the attribute name and type.
	if((_wcsicmp(pAttrInfo->pszAttrName,L"nTSecurityDescriptor") == 0) &&
	 (pAttrInfo->dwADsType==ADSTYPE_NT_SECURITY_DESCRIPTOR))
	{
		// Get a pointer to the security descriptor.
		pSD = (PSECURITY_DESCRIPTOR)(pAttrInfo->pADsValues->SecurityDescriptor.lpValue);
			 
		DWORD SDSize = pAttrInfo->pADsValues->SecurityDescriptor.dwLength;
			 
		// Allocate memory for the buffer and copy the security descriptor to the buffer.
		*pSecurityDescriptor = (PSECURITY_DESCRIPTOR)CoTaskMemAlloc(SDSize);
		if (*pSecurityDescriptor)
		{
			CopyMemory((PVOID)*pSecurityDescriptor, (PVOID)pSD, SDSize);
	}
		else
		{
			hr = E_FAIL;
	}

		// Caller must free the memory for pSecurityDescriptor using CoTaskMemFree.
}
 
	// Free memory used for the attributes retrieved.
	FreeADsMem(pAttrInfo); 
 
	return hr;
}