Common Processing for Enumeration of Users, Groups, and Aliases

This section specifies message processing that is common for SamrEnumerateGroupsInDomain, SamrEnumerateAliasesInDomain, and SamrEnumerateUsersInDomain. The explanation of each method specifies a filter that is used to identify which objects to return to the client; this filter is referred to in this section by the term Enumerate-Filter.

Let the term "session" refer to a set of sequential enumerate method calls made by a client, starting with an EnumerationContext parameter of value 0 and ending with an enumerate method that returns STATUS_SUCCESS. The methods MUST be the same type; for example, a session is a sequence of SamrEnumerateGroupsInDomain method calls, not a SamrEnumerateGroupsInDomain method call followed by a SamrEnumerateUsersInDomain method call.

Finally, a non-normative description of EnumerationContext is helpful to understand the processing of this parameter. This parameter is used as a "cookie" by the server in order to communicate to itself, between method calls within a session, which accounts have already been returned to the client.

As an example, recall that EnumerationContext is a 32-bit value. Because of this fact, a possible choice of cookie could be the RID of the last account that was returned. Upon receiving a nonzero cookie, the server can determine the next account that needs to be returned. Note that this example depends on the server returning the accounts in RID sort order; however, this method has no constraint about sort order.

[MS-DRSR] section has information on another IDL method, IDL_DRSGetNT4ChangeLog, that uses a "cookie" mechanism.

Upon receipt of one of the messages, the server MUST process the data from the message, subject to the following constraints:

  1. DomainHandle.GrantedAccess MUST have the required access specified in section Otherwise, the server MUST return STATUS_ACCESS_DENIED.

  2. The server MUST return an error if DomainHandle.HandleType is not equal to "Domain".

  3. The server MUST enable a client to obtain a listing, without duplicates, of all database objects that satisfy the criteria of Enumerate-Filter.

  4. The server MUST use EnumerationContext to allow the client implementation to pass back to the server, on a subsequent call, information on the last database object that was returned using EnumerationContext.

    If an object that satisfies Enumerate-Filter is added between successive Enumerate method calls in a session, and said object has a RID that is greater than the RIDs of all objects returned in previous calls, the server MUST return said object before the enumeration is complete.

    If an object that satisfies Enumerate-Filter is deleted between successive Enumerate method calls in a session, and said object has not already been returned by a previous method call in the session, the server MUST NOT return said object before the enumeration is complete.

  5. The server SHOULD<45> validate that EnumerationContext is an expected value for the server's implementation.

  6. The server SHOULD<46> fill Buffer.Buffer with as many entries as possible, such that not more than PreferedMaximumLength bytes are returned in Buffer.Buffer. If the server returns more than PreferedMaximumLength bytes, the difference between PreferedMaximumLength and the actual number of bytes returned MUST be less than the maximum size, in bytes, of one entry in the array Buffer.Buffer.

  7. Each element of Buffer.Buffer MUST represent one database object that matches the Enumerate-Filter and MUST be set as follows:

    1. Buffer.Buffer.Name is the sAMAccountName attribute value of the database object.

    2. Buffer.Buffer.RelativeId is the RID of the objectSid attribute of the database object.

  8. On output, CountReturned MUST equal Buffer.EntriesRead.

  9. STATUS_MORE_ENTRIES MUST be returned if the server returns less than all of the database objects in Buffer.Buffer because of the PreferedMaximumLength restriction described above. Note that this return value is not an error status.

  10. If there are no entries or if Buffer.Buffer contains all matching database objects that remain, the server MUST return STATUS_SUCCESS.