Platform SDK: Active Directory, ADSI, and Directory Services |
The following code fragment is a function that adds an ACE for an extended right to the ACL of the specified object:
HRESULT SetExtendedRight( IADs *pObject, LPOLESTR pszRightsGUID, LONG lAccessType, LONG fInheritanceFlags, LONG fAppliesToObjectType, LPOLESTR szTrustee ) { BOOL bExists = FALSE; VARIANT var,varACE; HRESULT hr = E_FAIL; IADsSecurityDescriptor *pSD = NULL; IADsAccessControlList *pACL = NULL; IDispatch *pDisp = NULL; LPUNKNOWN pUnk = NULL; ULONG lFetch; IEnumVARIANT *pEnum = NULL; IADsAccessControlEntry *pACE = NULL; IDispatch *pDispatch = NULL; IDispatch *pDispACE = NULL; //Check params //This sample takes the rightsGUID in StringFromGUID2 format and assumes it is the GUID for the correct extended right. //For extended rights in a DACL, lAccessType must be ADS_ACETYPE_ACCESS_ALLOWED_OBJECT or ADS_ACETYPE_ACCESS_DENIED_OBJECT. if ((lAccessType!=ADS_ACETYPE_ACCESS_ALLOWED_OBJECT)&&(lAccessType!=ADS_ACETYPE_ACCESS_DENIED_OBJECT)) return E_INVALIDARG; //This sample takes the szTrustee in an expected naming format and assumes it is the name for the correct trustee. if (!szTrustee) return E_INVALIDARG; if (!pszRightsGUID) return E_INVALIDARG; 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 the 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)) { //Create the COM object for the new ACE. hr = CoCreateInstance( CLSID_AccessControlEntry, NULL, CLSCTX_INPROC_SERVER, IID_IADsAccessControlEntry, (void **)&pACE ); if (SUCCEEDED(hr)) { //Set the properties of the new ACE. //For extended right, set the mask to ADS_RIGHT_DS_CONTROL_ACCESS. hr = pACE->put_AccessMask(ADS_RIGHT_DS_CONTROL_ACCESS); //Set the trustee. hr = pACE->put_Trustee( szTrustee ); //For extended rights, set AceType to ADS_ACETYPE_ACCESS_ALLOWED_OBJECT or ADS_ACETYPE_ACCESS_DENIED_OBJECT. hr = pACE->put_AceType( lAccessType ); //For this sample, set AceFlags so that ACE is not inherited by child objects. hr = pACE->put_AceFlags(fInheritanceFlags); //Flags specifies whether the ACE applies to the current object, child objects, or both. //For this sample, fAppliesToInheritedObject is set to ADS_FLAG_OBJECT_TYPE_PRESENT so that the right applies only to the current object. hr = pACE->put_Flags( fAppliesToObjectType ); //For extended rights, set ObjectType to the rightsGUID of the extended right. if (fAppliesToObjectType & ADS_FLAG_OBJECT_TYPE_PRESENT) { hr = pACE->put_ObjectType( pszRightsGUID ); } //Set the inherited object type if right applies to child objects. if (fAppliesToObjectType & ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT) { hr = pACE->put_InheritedObjectType( pszRightsGUID ); } //Add the ACE to the ACL. //Need to QI for IDispatch pointer to pass to the AddAce method. hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDispACE); if (SUCCEEDED(hr)) { hr = pACL->AddAce(pDispACE); if (SUCCEEDED(hr)) { //Write the DACL hr = pSD->put_DiscretionaryAcl(pDisp); if (SUCCEEDED(hr)) { //Write the ntSecurityDescriptor property to the property cache. hr = pObject->Put(szAttribute, var); if (SUCCEEDED(hr)) { //Call SetInfo to update the property on the object in the directory. hr = pObject->SetInfo(); } } } } if (pDispACE) pDispACE->Release(); } if (pACE) pACE->Release(); } if (pACL) pACL->Release(); } if (pDisp) pDisp->Release(); } if (pSD) pSD->Release(); } } VariantClear(&var); } return hr; }