Directory Services

Example Code for Reading defaultSecurityDescriptor

The following code example reads the defaultSecurityDescriptor for a specified object class.

#include <stdio.h>
#include <wchar.h>
#include <objbase.h>
#include <activeds.h>
#include <ACCCTRL.h>
// For security descriptor control flags.
#include <winnt.h>
#define _WIN32_WINNT 0x0500
#include <Sddl.h>
 
HRESULT ReadDefaultSecurityDescriptor( IADs *pObject );
int SDParseControlMasks( long lCtrl );
int SDParseAccessMask( long lCtrl );
 
int main(int argc, char *argv[])
{
LPOLESTR szPath = new OLECHAR[MAX_PATH];
LPOLESTR pszBuffer  = new WCHAR[MAX_PATH];
HRESULT hr = S_OK;
IADs *pObject = NULL;
VARIANT var;
 
wprintf(L"This program displays the default security descriptor of an object class\n");
wprintf(L"Specify the object class:");
_getws(pszBuffer);
if (!pszBuffer)
	return TRUE;
wcscpy(szPath, L"LDAP://cn=");
wcscat(szPath, pszBuffer);
wcscat(szPath, L",");
 
// Intialize COM.
CoInitialize(NULL);
 
// Get rootDSE and the schema container DN.
// Bind to current user's domain using current user's security context.
hr = ADsOpenObject(L"LDAP://rootDSE",
				 NULL,
				 NULL,
				 ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
				 IID_IADs,
				 (void**)&pObject);
 
if (SUCCEEDED(hr))
{
	hr = pObject->Get(CComBSTR("schemaNamingContext"), &var);
	if (SUCCEEDED(hr))
	{
		wcscat(szPath,var.bstrVal);
		VariantClear(&var);
		if (pObject)
		{
		 pObject->Release();
		 pObject = NULL;
	}
		hr = ADsOpenObject(szPath,
						 NULL,
						 NULL,
						 ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
						 IID_IADs,
						 (void**)&pObject);
		if (SUCCEEDED(hr))
		{
			wprintf(L"***********Read the default SD for the %s class***********\n", pszBuffer);
			hr = ReadDefaultSecurityDescriptor(
								pObject
								);
	}
}
}
 
if (FAILED(hr))
	wprintf(L"Failed with the following HRESULT: %x\n",hr);
 
if (pObject)
	pObject->Release();
 
// Uninitialize COM.
CoUninitialize();
return TRUE;
}
 
 
HRESULT ReadDefaultSecurityDescriptor( IADs *pObject )
{
HRESULT hr = E_FAIL;
PSECURITY_DESCRIPTOR pSDCNV = NULL;
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
PACL pDacl = NULL;
LPVOID pAce = NULL;
BYTE bAceType, bAceFlags;
PSID pSID = NULL;
DWORD dAccessMask;
OLECHAR szTrusteeName[MAX_PATH];
DWORD cbName = 0L;
OLECHAR szTrusteeDomainName[MAX_PATH];
DWORD cbReferencedDomainName = 0L;
SID_NAME_USE TrusteeType;
PACCESS_ALLOWED_ACE paace = NULL;
PACCESS_ALLOWED_OBJECT_ACE poace = NULL;
DWORD dFlags = 0L;
VARIANT var;
LPOLESTR szGUID = new WCHAR [39];
 
	hr = pObject->Get(CComBSTR("defaultSecurityDescriptor"), &var);
	if (SUCCEEDED(hr))
	{
		// Type should be VT_BSTR.
		if (var.vt==VT_BSTR)
		{
			wprintf(L"Default SD: %s\n", var.bstrVal);
			if (ConvertStringSecurityDescriptorToSecurityDescriptor(var.bstrVal,
																	SDDL_REVISION_1,
																	&pSDCNV,
																	NULL
																	))
			{
				// Read the security descriptor.
				// Get the DACL.
				if (GetSecurityDescriptorDacl(  
					pSDCNV, // Address of the security descriptor
					&bDaclPresent, // Address of flag for presence of disc. ACL
					&pDacl,  // Address of pointer to ACL.
					&bDaclDefaulted // Address of flag for default disc. ACL
					))
				{
					printf("Ace count: %d\n",pDacl->AceCount);
					for (WORD i = 0; i < pDacl->AceCount; i++ )
					{
						// Get the ACE.
						if (GetAce( pDacl, // pointer to access-control list
								i, // Index of ACE to retrieve.
								&pAce // Pointer to pointer to ACE.
								))
						{
							wprintf(L"**** ACE %d of %d ****\n", i+1, pDacl->AceCount);
							bAceType = ((ACE_HEADER *)pAce)->AceType;
							bAceFlags = ((ACE_HEADER *)pAce)->AceFlags;
 
							switch (bAceType)
							{
							case ACCESS_ALLOWED_ACE_TYPE:
								printf("ACE Type: ACCESS_ALLOWED_ACE_TYPE\n");
								dAccessMask = ((ACCESS_ALLOWED_ACE *)pAce)->Mask;
								paace = (PACCESS_ALLOWED_ACE)pAce;
								pSID = (PSID)&(paace->SidStart);
								break;
							case ACCESS_DENIED_ACE_TYPE:
								printf("ACE Type: ACCESS_DENIED_ACE_TYPE\n");
								dAccessMask = ((ACCESS_DENIED_ACE *)pAce)->Mask;
								paace = (PACCESS_ALLOWED_ACE)pAce;
								pSID = (PSID)&(paace->SidStart);
								break;
							case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
								printf("ACE Type: ACCESS_ALLOWED_OBJECT_ACE_TYPE\n");
								dAccessMask = ((ACCESS_ALLOWED_OBJECT_ACE *)pAce)->Mask;
								poace = (PACCESS_ALLOWED_OBJECT_ACE)pAce;
								// Check Flags to verify that object type and/or
								// inherited object type is set.
								dFlags = poace->Flags;
								if (dFlags & ACE_OBJECT_TYPE_PRESENT)
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->ObjectType, szGUID, 39); 
									// Print the GUID.
									wprintf(L"ObjectType GUID: %s\n",szGUID);
							}
								// Print the inherited object type.
								// If both GUIDs are present, go to the member.
								if ( (dFlags & ACE_OBJECT_TYPE_PRESENT) 
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->InheritedObjectType, szGUID, 39); 
									// Print the GUID.
									wprintf(L"Inherited ObjectType GUID: %s\n",szGUID);
							}
								// If only the inherited object type is present,
								// go to the ObjectType member.
								if ( (!(dFlags & ACE_OBJECT_TYPE_PRESENT))
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->ObjectType, szGUID, 39); 
									// Print the GUID.
									wprintf(L"Inherited ObjectType GUID: %s\n",szGUID);
							}
 
								// Get the SID from the ACE.
								if ( (dFlags & ACE_OBJECT_TYPE_PRESENT) 
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
								 pSID = (PSID)&(poace->SidStart);
							}
								else if (dFlags & ACE_OBJECT_TYPE_PRESENT)
								{
								 pSID = (PSID)&(poace->InheritedObjectType);
							}
								else if (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								{
								 pSID = (PSID)&(poace->InheritedObjectType);
							}
								break;
							case ACCESS_DENIED_OBJECT_ACE_TYPE:
								printf("ACCESS_DENIED_OBJECT_ACE_TYPE\n");
								dAccessMask = ((ACCESS_DENIED_OBJECT_ACE *)pAce)->Mask;
								poace = (PACCESS_ALLOWED_OBJECT_ACE)pAce;
								// Check Flags to verify that object type
								// and/or inherited object type are set.
								dFlags = poace->Flags;
								if (dFlags & ACE_OBJECT_TYPE_PRESENT)
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->ObjectType, szGUID, 39); 
									// Print the GUID.
									wprintf(L"ObjectType GUID: %s\n",szGUID);
							}
								// Print the inherited object type.
								// If both GUIDs are present, go to the member.
								if ( (dFlags & ACE_OBJECT_TYPE_PRESENT) 
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->InheritedObjectType, szGUID, 39); 
									// Print the GUID
									wprintf(L"Inherited ObjectType GUID: %s\n",szGUID);
							}
								// If only the inherited object type is present,
								// go to the ObjectType member.
								if ( (!(dFlags & ACE_OBJECT_TYPE_PRESENT))
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
									// Convert GUID to string.
									::StringFromGUID2(poace->ObjectType, szGUID, 39); 
									// Print the GUID.
									wprintf(L"Inherited ObjectType GUID: %s\n",szGUID);
							}
 
								// Get the SID from the ACE.
								if ( (dFlags & ACE_OBJECT_TYPE_PRESENT) 
									 && (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								 )
								{
								 pSID = (PSID)&(poace->SidStart);
							}
								else if (dFlags & ACE_OBJECT_TYPE_PRESENT)
								{
								 pSID = (PSID)&(poace->InheritedObjectType);
							}
								else if (dFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
								{
								 pSID = (PSID)&(poace->InheritedObjectType);
							}
								break;
							default:
								printf("Unknown ACE TYPE\n");
								break;
						}
							cbName = sizeof(szTrusteeName); 
							cbReferencedDomainName = sizeof(szTrusteeDomainName); 
							ZeroMemory(szTrusteeName, cbName); 
							ZeroMemory(szTrusteeDomainName, cbReferencedDomainName);
							// Look up the trustee name and domain.
							if (LookupAccountSid( 
							NULL, // Address of string for system name.
							pSID, 		 // Address of security identifier.
							szTrusteeName, 	// Address of string for account name.
							&cbName,  // Address of size account string.
							szTrusteeDomainName,
													// Address of string for referenced domain.
							&cbReferencedDomainName,
													// Address of size domain string.
							&TrusteeType		// Address of structure for SID type.
							))
							{
							 if (wcslen(szTrusteeDomainName)==0)
								 wprintf(L"Trustee: %s\n",szTrusteeName);
							 else
								 wprintf(L"Trustee: %s\\%s\n", szTrusteeDomainName,szTrusteeName);
						}
							else
							{
								if (GetLastError() == ERROR_NONE_MAPPED)
								{
									printf("Last Error: ERROR_NONE_MAPPED\n");
							}
								else
								{
									printf("Last Error: %d\n",GetLastError()); 
							}
						}
							printf("AccessMask: \n");
							SDParseAccessMask(dAccessMask);
							printf("Inheritance flags: %d\n",bAceFlags);
					}
				}
			}
		}
			if (pSDCNV)
				LocalFree(pSDCNV);
	}
}
	VariantClear(&var);
return hr;
}
 
// Function used to print Control flags.
int SDParseControlMasks(
						long lCtrl
						)
{
	int iReturn = TRUE;
 
if (lCtrl & SE_OWNER_DEFAULTED)
	printf("  SE_OWNER_DEFAULTED\n");
 
if (lCtrl & SE_GROUP_DEFAULTED)
	printf("  SE_GROUP_DEFAULTED\n");
 
if (lCtrl & SE_DACL_PRESENT)
	printf("  SE_DACL_PRESENT\n");
 
if (lCtrl & SE_DACL_DEFAULTED)
	printf("  SE_DACL_DEFAULTED\n");
 
if (lCtrl & SE_SACL_PRESENT)
	printf("  SE_SACL_PRESENT\n");
 
if (lCtrl & SE_SACL_DEFAULTED)
	printf("  SE_SACL_DEFAULTED\n");
 
if (lCtrl & SE_DACL_AUTO_INHERIT_REQ)
	printf("  SE_DACL_AUTO_INHERIT_REQ\n");
 
if (lCtrl & SE_SACL_AUTO_INHERIT_REQ)
	printf("  SE_SACL_AUTO_INHERIT_REQ\n");
 
if (lCtrl & SE_DACL_AUTO_INHERITED)
	printf("  SE_DACL_AUTO_INHERITED\n");
 
if (lCtrl & SE_SACL_AUTO_INHERITED)
	printf("  SE_SACL_AUTO_INHERITED\n");
 
if (lCtrl & SE_DACL_PROTECTED)
	printf("  SE_DACL_PROTECTED\n");
 
if (lCtrl & SE_SACL_PROTECTED)
	printf("  SE_SACL_PROTECTED\n");
 
if (lCtrl & SE_SELF_RELATIVE)
	printf("  SE_OWNER_DEFAULTED\n");
 
return iReturn;
 
}
 
// Function used to print AccessMask flags.
int SDParseAccessMask(
						long lCtrl
						)
{
	int iReturn = TRUE;
 
if (lCtrl & ADS_RIGHT_DELETE)
	printf("  ADS_RIGHT_DELETE\n");
 
if (lCtrl & ADS_RIGHT_READ_CONTROL)
	printf("  ADS_RIGHT_READ_CONTROL\n");
 
if (lCtrl & ADS_RIGHT_WRITE_DAC)
	printf("  ADS_RIGHT_WRITE_DAC\n");
 
if (lCtrl & ADS_RIGHT_WRITE_OWNER)
	printf("  ADS_RIGHT_WRITE_OWNER\n");
 
if (lCtrl & ADS_RIGHT_GENERIC_READ)
	printf("  ADS_RIGHT_GENERIC_READ\n");
 
if (lCtrl & ADS_RIGHT_GENERIC_WRITE)
	printf("  ADS_RIGHT_GENERIC_WRITE\n");
 
if (lCtrl & ADS_RIGHT_GENERIC_EXECUTE)
	printf("  ADS_RIGHT_GENERIC_EXECUTE\n");
 
if (lCtrl & ADS_RIGHT_GENERIC_ALL)
	printf("  ADS_RIGHT_GENERIC_ALL\n");
 
if (lCtrl & ADS_RIGHT_DS_CREATE_CHILD)
	printf("  ADS_RIGHT_DS_CREATE_CHILD\n");
 
if (lCtrl & ADS_RIGHT_DS_DELETE_CHILD)
	printf("  ADS_RIGHT_DS_DELETE_CHILD\n");
 
if (lCtrl & ADS_RIGHT_ACTRL_DS_LIST)
	printf("  ADS_RIGHT_ACTRL_DS_LIST\n");
 
if (lCtrl & ADS_RIGHT_DS_SELF)
	printf("  ADS_RIGHT_DS_SELF\n");
 
if (lCtrl & ADS_RIGHT_DS_READ_PROP)
	printf("  ADS_RIGHT_DS_READ_PROP\n");
 
if (lCtrl & ADS_RIGHT_DS_WRITE_PROP)
	printf("  ADS_RIGHT_DS_WRITE_PROP\n");
 
if (lCtrl & ADS_RIGHT_DS_DELETE_TREE)
	printf("  ADS_RIGHT_DS_DELETE_TREE\n");
 
if (lCtrl & ADS_RIGHT_DS_LIST_OBJECT)
	printf("  ADS_RIGHT_DS_LIST_OBJECT\n");
 
if (lCtrl & ADS_RIGHT_DS_CONTROL_ACCESS)
	printf("  ADS_RIGHT_DS_CONTROL_ACCESS\n");
 
return iReturn;
 
}