Platform SDK: Active Directory, ADSI, and Directory Services

Change Notifications in Active Directory

Active Directory™ provides a mechanism for a client application to register with a domain controller to receive change notifications. To do this, the client specifies the LDAP change notification control in an asynchronous LDAP search operation. The client also specifies the following search parameters:

Base of the search
The distinguished name of an object in the directory.
Scope
You can specify either LDAP_SCOPE_BASE to monitor just the object itself, or LDAP_SCOPE_ONELEVEL to monitor the immediate children of the object, not including the object itself. Do not specify LDAP_SCOPE_SUBTREE. Although the subtree scope is supported if the base object is the root of a naming context, its use can severely impact server performance, because it generates an LDAP search result message every time an object in the naming context is modified. You cannot specify LDAP_SCOPE_SUBTREE for an arbitrary subtree.
Filter
You must specify a search filter of (objectclass=*), which means you receive notifications for changes to any object in the specified scope.
Attributes
You can specify a list of attributes to be returned when a change occurs. Note that you receive notifications when any attribute is modified, not just the specified attributes.

You can register up to five notification requests on a single LDAP connection. You must have a dedicated thread that waits for the notifications and processes them as quickly as possible. When you call the ldap_search_ext function to register a notification request, the function returns a message identifier that identifies that request. You then use the ldap_result function to wait for change notifications. When a change occurs, the server sends you an LDAP message containing the message identifier for the notification request that generated the notification. This causes the ldap_result function to return with search results that identify the object that changed.

It is up to the client application to determine the initial state of the object being monitored. To do this, you must first register the notification request and then read the current state.

It is also up to the client application to determine the nature of the change. For a base level search, a notification occurs when any attribute changes, or when the object is deleted or moved. For a one-level search, a notification occurs when a child object is created, deleted, moved, or modified. Note that moving or renaming an object in the hierarchy above a target object does not generate a notification even though the distinguished name of the target changed as a result. For example, suppose you are monitoring changes to the child objects in a container, you do not receive notifications if the container itself is moved or renamed.

When the client processes the search results, it can use the ldap_get_dn function to get the distinguished name of the object that changed. Of course, you cannot rely on distinguished names to identify the objects being tracked, because distinguished names can change. Instead, include the objectGUID attribute in the list of attributes to retrieve. Each object's objectGUID remains unchanged regardless of where the object is moved within the enterprise forest.

If an object within the search scope is deleted, the client receives a change notification and the isDeleted attribute of the object is set to TRUE. In this case, the search results report the new distinguished name of the object in the Deleted Objects container of its partition. It is not necessary to specify the tombstone control (LDAP_SERVER_SHOW_DELETED_OID) to get notifications of object deletions. For more information, see Retrieving Deleted Objects.

Once a client has registered a notification request, the client continues to receive notifications until the connection is broken or the client abandons the search by calling the ldap_abandon function. If the client or server disconnects, for example, if the server goes down, the notification request is terminated. When the client reconnects, it must register for notifications again, and then read the current state of the objects of interest in case there were changes while the client was disconnected.

The client can use the value of an object's uSNChanged attribute to determine whether the current state of the object on the server reflects the latest changes that the client has received. The system increases an object's uSNChanged attribute whenever the object is moved or modified. For instance, if the server goes down and the directory partition is restored from a backup, the server's replica of an object may not reflect changes previously reported to the client, in which case the uSNChanged value on the server will be lower than the value stored by the client.

For sample code that uses the LDAP change notification control in an asynchronous LDAP search operation, see Example Code for Receiving Change Notifications.

For a discussion of when to use the LDAP change notification control, see Overview of Change Tracking Techniques.