Platform SDK: Active Directory, ADSI, and Directory Services

IADsAccessControlList::CopyAccessList

The IADsAccessControlList::CopyAccessList method copies all access control entries (ACEs) in the access-control list (ACL) to the caller's process space.

HRESULT CopyAccessList(
  IDispatch ** ppAccessControlList  
);

Parameters

ppAccessControlList
[out] Address of an IDispatch interface pointer to an ACL as the copy of the original access list. If this parameter is NULL on return, no copies of the ACL could be made.

Return Values

This method returns the standard return values, as well as the following:

S_OK
The ACEs was copied successfully.
E_INVALIDARG
The argument supplied is not valid.
OUTOFMEMORY
No memory could be allocated for the new ACL.
E_FAIL
The operation has failed.

For other return values, see ADSI Error Codes.

Remarks

As with any method-allocated memory, the caller is responsible for calling Release on the copy of ACEs through their IDispatch pointers.

Example Code [Visual Basic]

The following Visual Basic® code snippet shows how to copy ACL from one ADSI object to another.

Dim x As IADs
Dim sd As IADsSecurityDescriptor
Dim Dacl As IADsAccessControlList
Dim CopyDacl As IADsAccessControlList
 
'Get the ACL from one object
Set x = GetObject("LDAP://OU=Sales, DC=activeD,DC=nttest,DC=microsoft,DC=com")
Set sd = x.Get("ntSecurityDescriptor")
Set Dacl = sd.DiscretionaryAcl
Set CopyDacl = Dacl.CopyAccessList()
 
'Copy the ACL to another object in the Directory
Set x = GetObject("LDAP://OU=Sales, DC=Fabrikam,DC=com")
Set sd = x.Get("ntSecurityDescriptor")
sd.DiscretionaryAcl = CopyDacl
x.Put "ntSecurityDescriptor", Array(sd)
x.SetInfo

Example Code [C++]

The following C++ code snippet makes a copy of an ACL.

LPWSTR guestPath = L"LDAP://CN=Guest,CN=Sales,dc=Fabrikam,dc=com";
LPWSTR user = L"Administrator";
LPWSTR passwd = L"secret";

IADs *pAds;
HRESULT hr;
hr = ADsOpenObject(guestPath, 
                   user,
                   passwd,
                   ADS_SECURE_AUTHENTICATION, 
                   IID_IADs,
                   (void**)&pAds);
if(FAILED(hr)) exit(0);

IADsSecurityDescriptor *pSD=getSD(pAds);
if(!pSD) {
    pAds->Release();
    exit (0);
}

IADsAccessControlList *pAcl = getAcl(pSD);

IADsAccessControlList *pAclCopy;
hr = pAcl.CopyAccessList(pAclCopy);

IADs pValCust;
hr = ADsOpenObject(
          L"LDAP://CN=ValuedCustomer,CN=Sales,DC=Fabrikam,DC=com",
          user,
          passwd,
          ADS_SECURE_AUTHENTICATION,
          IID_IADs,
          (void**) &pValCust);

IADsSecurityDescriptor *pSdValCust=getSD(pValCust);

IDispatch *pDisp;
hr = pAclCopy->QueryInterface(IID_IDispatch,(void**)&pDisp);
hr = pSdValCust->put_DiscretionaryACL(pDisp);
hr = pValCust->SetInfo();

pDisp->Release();

pValCust->Release();
pAclCopy->Release();
pSdValCust->Release();

if(pAcl) pAcl->Release();
if(pSD)   pSD->Release();
if(pAds) pAds->Release();

/////////////////////////////////////////////////////////
// functions to bind to an object and get its SD and ACL.
/////////////////////////////////////////////////////////
IADs *getIADsObject(LPWSTR adsPath,LPWSTR usr,LPWSTR passwd)
{
    if(!adsPath) return NULL;
    HRESULT hr;
    IADs *pObj;
    hr = ADsOpenObject(adsPath,
                       usr,
                       passwd,
                       ADS_SECURE_AUTHENTICATION,
                       IID_IADs,
                       (void**)&pObj);

    if(FAILED(hr)) {
        printf("adsopenobject: hr = %x\n",hr);
        if(pObj) pObj->Release();
        return NULL;
    }
    return pObj;
}

IADsSecurityDescriptor *getSD(IADs *pObj)
{
    VARIANT var;
    VariantInit(&var);
    HRESULT hr;

    hr = pObj->Get(L"ntSecurityDescriptor",&var);
    if(FAILED(hr)) {
        VariantClear(&var);
        return NULL;
    }

    IADsSecurityDescriptor *psd;
    hr = V_DISPATCH(&var)->QueryInterface(IID_IADsSecurityDescriptor,
                                  (void**)&psd);
    if(FAILED(hr)) {
        if(psd) psd->Release();
        return NULL;
    }
    return psd;
}

IADsAccessControlList *getAcl(IADsSecurityDescriptor *psd)
{
    HRESULT hr;
    IDispatch *pDisp;

    hr = psd->get_DiscretionaryAcl(&pDisp);
    if(FAILED(hr)) {
    pDisp->Release();
    return NULL;
    }

    IADsAccessControlList *pAcl;
    hr = pDisp->QueryInterface(IID_IADsAccessControlList,
                               (void**)&pAcl);
    pDisp->Release();
    if(FAILED(hr)) {
       pAcl->Release();
       return NULL;
    }

    return pAcl;
}

Requirements

  Windows NT/2000: Requires Windows 2000 (or Windows NT 4.0 with DSClient).
  Windows 95/98: Requires Windows 95 or later (with DSClient).
  Header: Declared in Iads.h.

See Also

IADsAccessControlEntry, IADsSecurityDescriptor