Platform SDK: Active Directory, ADSI, and Directory Services

Using IDirectoryObject to Get a Security Descriptor

The following C++ code fragment contains a function that 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 PSECURITY_DESCRIPTOR pointer to the security descriptor in the buffer:

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;
 
// 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.
}
 
// Free memory used for the attributes retrieved.
FreeADsMem( pAttrInfo ); 
 
return hr;
}