Directory Services

Polling for Changes Using the DirSync Control

Microsoft® Active Directory® directory synchronization (DirSync) control is an LDAP server extension that enables an application to search an Active Directory partition for objects that have changed since a previous state.

Be aware that the DirSync caller must have the SE_SYNC_AGENT_NAME privilege, which enables the caller to read all objects and attributes in Active Directory, regardless of the access protections on the objects and attributes. By default, this privilege is assigned to the Administrator and LocalSystem accounts on domain controllers. The caller must also have the DS-Replication-Get-Changes extended right. For more information about implementing a change-tracking mechanism for applications that must run under an account that does not have this privilege, see Polling for Changes Using USNChanged. For more information about privileges, see Privileges.

Use the DirSync control through ADSI by specifying the ADS_SEARCHPREF_DIRSYNC search preference when using IDirectorySearch. For more information and a code example, see Example Code Using ADS_SEARCHPREF_DIRSYNC. You can also perform a DirSync search using the LDAP API. The following describes the ADSI implementation, most of which also applies to using LDAP directly, except as discussed at the end of this topic.

When you perform a DirSync search, you pass in a provider-specific blob of data (a cookie) that identifies the directory's state at the time of the previous DirSync search. For the first search, you pass in a null cookie, and the search returns all objects that match the filter. The search also returns a valid cookie. Store the cookie in the same storage that you are synchronizing with Active Directory. On subsequent searches, get the cookie from storage and pass it with the search request. The search results now include only the objects and attributes that have changed since the previous state identified by the cookie. The search also returns a new cookie to store for the next search.

The following tables list search parameters that the client search request can specify.

Parameter Description
Base of the search The base of a DirSync search must be the root of a directory partition, which can be a domain partition, the configuration partition, or the schema partition.
Scope The scope of a DirSync search must be ADS_SCOPE_SUBTREE, that is, the entire subtree of the partition. Be aware that for a search of a domain partition, the subtree includes the heads, but not the contents, of the configuration and schema partitions. To poll for changes in a smaller scope, use the USNChanged technique instead of DirSync.
Filter You can specify any valid search filter. For an initial search with a null cookie, the results include all objects that match the filter. For subsequent searches with a valid cookie, the search results include data only for objects that match the filter and have changed since the state indicated by the cookie. For more information about search filters, see Creating a Query Filter.
Attributes You can specify a list of attributes to be returned when a change occurs. For each object, the initial results include all the requested attributes set on the object. Subsequent search results include only the specified attributes that have changed. Unchanged attributes are not included in the search results. In the ADSI implementation, the search results always include the objectGUID and instanceType of each object. Also, the specified attribute list acts as an additional filter: the initial search results include only objects that have at least one of the specified attributes set; subsequent searches include only objects on which one or more of the attributes have changed (values added or deleted).

Also, be aware that:

Retrieving Deleted Objects With a DirSync Search

The ADS_SEARCHPREF_DIRSYNC search results automatically include deleted objects (tombstones) that match the specified search filter. However, a search filter that will match an object when it is live may not match the object after it is deleted. This is because tombstones retain only a subset of the attributes present on the original object. For example, you would typically use the following filter for user objects.

(&(objectClass=user)(objectCategory=person))

The objectCategory attribute is removed when an object is deleted, so the filter above would not match any tombstone objects. Conversely, the objectClass attribute is retained on tombstone objects, so a filter of "(objectClass=user)" would match deleted user objects.

The attribute list that you specify with a DirSync search also acts as a filter; search results include only objects on which one or more of the specified attributes have changed since the previous DirSync search. If the attribute list does not include any attributes that are retained on tombstones, the search results will not include tombstones. To handle this, request all attributes by specifying a null attribute list; or you can request the isDeleted attribute, set to TRUE on all tombstones. Tombstone attributes have the 0x8 bit set in the searchFlags attribute of the attributeSchema definition.

For more information, see Retrieving Deleted Objects.

LDAP Implementation of the DirSync Control

You can also perform a DirSync search by using the LDAP API with the LDAP_SERVER_DIRSYNC_OID control. If you use the LDAP API, also specify the LDAP_SERVER_EXTENDED_DN_OID and LDAP_SERVER_SHOW_DELETED_OID controls. The LDAP_SERVER_EXTENDED_DN_OID control causes an LDAP search to return an extended form of the distinguished name that includes the objectGUID and objectSID for security principal objects such as users, groups, and computers. The LDAP_SERVER_SHOW_DELETED_OID control causes the search results to include data for deleted objects. Be aware that these controls are automatically included in the ADSI implementation.