Platform SDK: Active Directory, ADSI, and Directory Services |
The following code is a program that 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's 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(L"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(L"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 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 see //if 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, //we need to 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 see //if 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, //we need to 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 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 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; }