Platform SDK: Active Directory, ADSI, and Directory Services |
The following code fragment is a function that checks for a specified extended right in an ACE in the ACL of the specified object:
//DESCRIPTION: ReadExtendedRight checks for the specified extended right on the specified object. //If an ACE with that extended right exists, it displays (using printf) //the trustee and ACE type for the extended right. //FLOW: Get the security descriptor of an object, get the ACL, //enumerate the ACEs, check for extended rights ACEs, //check for the specified right, and display the trustee and ACE type. //NOTES: The pszRightsGUID UNICODE string should be a string //containing the rightsGUID property value of the extended right //and the string should have the same format as the COM Library //function StringFromGUID2. //For example: //LPOLESTR pszRightsGUID = L"{8186e976-4d8a-11d2-95dd-0000f875b660}"; //The pbExists parameter specifies a BOOL that will receive //TRUE if an ACE with the specified right exists; otherwise, FALSE. HRESULT ReadExtendedRight( IADs *pObject, LPOLESTR pszRightsGUID, BOOL *pbExists ) { BOOL bExists = FALSE; VARIANT var,varACE; HRESULT hr = E_FAIL; IADsSecurityDescriptor *pSD = NULL; IADsAccessControlList *pACL = NULL; IDispatch *pDisp = NULL; LPUNKNOWN pUnk = NULL; ULONG lFetch; BSTR szObjectType, szTrustee; IEnumVARIANT *pEnum = NULL; IADsAccessControlEntry *pACE = NULL; IDispatch *pDispatch = NULL; long lAceType, lAccessMask, lTypeFlag; if (pObject) { VariantClear(&var); //Get the nTSecurityDescriptor LPOLESTR szAttribute = L"nTSecurityDescriptor"; hr = pObject->Get(szAttribute,&var); if (SUCCEEDED(hr)) { //Type should be VT_DISPATCH--an IDispatch ptr to the security descriptor object. if (var.vt==VT_DISPATCH) { //Use V_DISPATCH macro to get the IDispatch pointer from VARIANT structure //and QI for IADsSecurityDescriptor ptr. hr = V_DISPATCH( &var )->QueryInterface(IID_IADsSecurityDescriptor,(void**)&pSD); if (SUCCEEDED(hr)) { //Get the DACL hr = pSD->get_DiscretionaryAcl(&pDisp); if (SUCCEEDED(hr)) { //QI for IADsAccessControlList interface hr = pDisp->QueryInterface(IID_IADsAccessControlList,(void**)&pACL); if (SUCCEEDED(hr)) { //Enumerate the ACEs in the ACL. hr = pACL->get__NewEnum( &pUnk ); if (SUCCEEDED(hr)) { hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) &pEnum ); if (SUCCEEDED(hr)) { hr = pEnum->Next( 1, &varACE, &lFetch ); //Loop to read all ACEs on the object. while( hr == S_OK ) { //Check if 1 item is returned and returned item is an IDispatch pointer. if ( (lFetch == 1) && (varACE.vt==VT_DISPATCH)) { pDispatch = V_DISPATCH(&varACE); //QI for IADsAccessControlEntry to use to read the ACE. hr = pDispatch->QueryInterface( IID_IADsAccessControlEntry, (void**)&pACE ); if (SUCCEEDED(hr)) { hr = pACE->get_AccessMask(&lAccessMask); //Check for control access right flag to see if this is an ACE for an extended right. if (lAccessMask & ADS_RIGHT_DS_CONTROL_ACCESS) { pACE->get_Flags(&lTypeFlag); //Check to make sure this ACE applies to an object if (lTypeFlag & ADS_FLAG_OBJECT_TYPE_PRESENT) { //Get the object type GUID and print it. pACE->get_ObjectType(&szObjectType); if ( _wcsicmp(szObjectType,pszRightsGUID) == 0 ) { if (bExists==FALSE) bExists = TRUE; printf("\nObjectType: %S\n", szObjectType); hr = pACE->get_AceType(&lAceType); if (lAceType == ADS_ACETYPE_ACCESS_ALLOWED_OBJECT) printf("ACE Type: ADS_ACETYPE_ACCESS_ALLOWED_OBJECT\n"); if (lAceType == ADS_ACETYPE_ACCESS_DENIED_OBJECT) printf("ACE Type: ADS_ACETYPE_ACCESS_DENIED_OBJECT\n"); //Get the trustee (who the right applies to) and print it. pACE->get_Trustee(&szTrustee); printf("Trustee: %S\n", szTrustee); //Free the string. if (szTrustee) SysFreeString(szTrustee); } //Free the string. if (szObjectType) SysFreeString(szObjectType); } } } //Clean up the enumerated ACE item. if (pACE) pACE->Release(); if (pDispatch) pDispatch->Release(); } //Clean up the VARIANT for the ACE item. VariantClear(&varACE); //Get the next ACE hr = pEnum->Next( 1, &varACE, &lFetch ); };//End of While loop } //Clean up if (pEnum) pEnum->Release(); } if (pUnk) pUnk->Release(); } if (pACL) pACL->Release(); } if (pDisp) pDisp->Release(); } if (pSD) pSD->Release(); } } VariantClear(&var); } *pbExists = bExists; return hr; }