Platform SDK: Active Directory, ADSI, and Directory Services

IADsAccessControlList

The IADsAccessControlList interface manages individual access-control entries (ACEs). An access-control list (ACL) consists of a collection of ACEs that can provide more fine-tuned access control to the same ADSI object for different clients. In general, different providers implement different access controls. The object's behavior is thus highly provider-specific. Consult the documentation of your provider for more information. For providers supplied by Microsoft®, see ADSI System Providers. Presently, only the LDAP provider supports access controls.

Before you can work with an object's ACEs, you must first obtain the ACL to which they belong. ACLs are managed by security descriptors and can be of either discretionary ACL and system ACL. For more information, see the IADsSecurityDescriptor interface.

Using the properties and methods of the IADsAccessControlList interface, you can retrieve and enumerate ACEs, add new entries to the list, or remove existing ones. The general procedure to manage access controls over an ADSI object involves the following steps:

  1. Obtain the security descriptor of the object of interest.
  2. Retrieve an ACL from the security descriptor.
  3. Work with ACEs in the ACL.

To make any new or modified ACEs persistent:

  1. Add the ACEs to the ACL
  2. Assign the ACL to the security descriptor
  3. Commit the security descriptor to the directory store.

The code snippets presented in the following table and in the IADsAccessControlEntry interfaces provide working examples.

The IADsAccessControlList is a dual interface and exposes the following properties and methods.

Methods in Vtable Order

IUnknown methods Description
QueryInterface Returns pointers to supported interfaces.
AddRef Increments reference count.
Release Decrements reference count.

IDispatch methods Description
GetTypeInfoCount Gets the number of type descriptions.
GetTypeInfo Gets a description of object's programmable interface.
GetIDsOfNames Maps name of method or property to DISPID.
Invoke Calls one of the object's methods, or gets/sets one of its properties.

IADsAccessControlList property methods Description
get/put_AclRevision Gets/sets the ACL revision number.
get/put_AceCount Gets/sets number of ACEs in the ACL.
AddAce Adds an entry to the ACL.
RemoveAce Removes an entry from the ACL.
CopyAccessList Copies the ACL.
get__NewEnum Gets an pointer to the enumerator object.

Example Code [Visual Basic]

The following Visual Basic® code snippet shows the general procedure to work with access control entries of a discretionary ACL.

Dim X As IADs
Dim Namespace As IADsOpenDSObject
Dim SecurityDescriptor As IADsSecurityDescriptor
Dim Dacl As IADsAccessControlList
 
Set Namespace = GetObject("LDAP://")
Set X= Namespace.OpenDSObject("LDAP://DC=Fabrikam,DC=Com, "cn=administrator,cn=users,DC=ArcadiayBay,DC=COM", "passwOrdGoesHere",  ADS_SECURE_AUTHENTICATION)
 
Set SecurityDescriptor = X.Get("ntSecurityDescriptor")
Debug.Print SecurityDescriptor.Owner
Debug.Print SecurityDescriptor.Group
 
Set Dacl = SecurityDescriptor.DiscretionaryAcl
Debug.Print Dacl.AceCount
 
For Each Obj In Dacl
   Debug.Print Obj.Trustee
   Debug.Print Obj.AccessMask
   Debug.Print Obj.AceFlags
   Debug.Print Obj.AceType
Next

Example Code [C++]

The following C++ code snippet enumerates ACEs from a DACL.

HRESULT hr;
VARIANT var;
 
// Assume that the pADs (IADs) pointer is valid
 
hr = pADs->Get(L"ntSecurityDescriptor", &var );
 
if (!SUCCEEDED(hr) )
{
   return;
}
 
///////////////////////////////////////
// Get the IADsSecurityDescriptor
///////////////////////////////////////
IDispatch *pDisp;
IADsSecurityDescriptor *pSecurityDesc;
pDisp = V_DISPATCH(&var);
hr = pDisp->QueryInterface( IID_IADsSecurityDescriptor, (void**) &pSecurityDesc );
VariantClear(&var);
if ( !SUCCEEDED(hr) )
{
   return;
}
 
////////////////////////////////////////
// Get the ACL
////////////////////////////////////////
IADsAccessControlList *pACL;
hr = pSecurityDesc->get_DiscretionaryAcl( &pDisp );
if (!SUCCEEDED(hr) )
{
   pSecurityDesc->Release();
   return;
}
 
hr=pDisp->QueryInterface(IID_IADsAccessControlList, (void**) &pACL);
pDisp->Release();
pSecurityDesc->Release();
 
//////////////////////////////////////////////
// Enumerate ACEs
//////////////////////////////////////////////
IEnumVARIANT *pEnum;
LPUNKNOWN     pUnk;
ULONG    lFetch;
BSTR    bstr;
IADsAccessControlEntry *pACE;
 
hr = pACL->get__NewEnum( &pUnk );
if ( !SUCCEEDED(hr) )
{
   pACL->Release();
   return;
}
 
hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) &pEnum );
if ( !SUCCEEDED(hr) )
{
   return;
}
 
hr = pEnum->Next( 1, &var, &lFetch );
 
while( hr == S_OK )
{
   if ( lFetch == 1 )
   {
      if ( VT_DISPATCH != V_VT(&var) )
      {
         pEnum->Release();
         return;
      }
      pDisp = V_DISPATCH(&var);
      /////////////////////////////
      // Get the individual ACE
      /////////////////////////////
      hr = pDisp->QueryInterface( IID_IADsAccessControlEntry, 
                                  (void**)&pACE ); 
      if ( SUCCEEDED(hr) )
      {
         pACE->get_Trustee(&bstr);
         printf("\n %S:\n", bstr);
         // ACE manipulation here
         SysFreeString(bstr);
         pACE->Release();
      }
       VariantClear(&var);
   }
   hr = pEnum->Next( 1, &var, &lFetch );
};
 
pACL->Release();

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