Active Directory Sync
The server can synchronize users, groups and user passwords bidirectionally with Microsoft Active Directory and Windows NT4 Domain Controllers. For clarity we call changes made from the DS to Active Directory 'outbound' and changes propagated from Active Directory to the DS 'inbound'. All communication between the server and its Active Directory peer is via LDAP.
How Active Directory Sync Works
Active Directory Sync makes heavy use of the server's replication infrastructure. It uses the changelog for outbound changes in much the same way as regular multi-master replication does. However the process for inbound change propagation is different. Here the special Active Directory 'dirsync' feature is used to request the entries that have changed since the previous sync pass was completed.
Inbound Password Sync
There is no documented mechanism that allows retrieval of plain text passwords from Active Directory. Plain text password values are required because Active Directory and Directory Server use different incompatible one-way password hashing mechanisms. Therefore special steps must be taken to 'catch' password changes as they occur on the Active Directory machine, by means of a 'password hook' dll. This dll, along with its associated Win32 service, comprise the 'Password Sync Service'. The Password Sync Service is responsible for propagating password changes caught with the hook dll back to the peer Directory Server (via an SSL protected LDAP connection).
How NT4 Sync Works
Legacy NT4 deployments are also supported by the 'Active Directory Sync' feature. In the case of NT4, in contrast to Active Directory there is no native support for LDAP. For NT4, a special 'LDAP Service' was written that aims to present an LDAP server with similar schema and characteristics to Active Directory. The Directory Server's sync code has a small number of special cases to accomodate the differences between the two. For example NT4 has no 'surname' field for users, and so it is necessary to generate a fake value for 'surname' in newly created sync'ed users (because the IETF inetOrgPerson object class requires that 'surname' be present). The NT4 LDAP Service is based on Apache DS, with a special 'jnetman' back-end that calls the NT4 NetApi functions.
Network I/O and Connections
The server is multi-threaded and has been designed to efficiently handle many simultaneous requests. The server uses poll() on platforms where it is available (which is most all of them at this point) so it is able to handle large numbers of connections. The OS imposes a limit on the number of file descriptors available in the whole system and per process - see your OS documentation (or run the dsktune utility) for information about how to increase this limit. The server keeps some file descriptors in reserve for file I/O (e.g. log files), outgoing network connections, and other purposes. The number of connections the server can handle at once is set by the maximum number of descriptors minus the reserve descriptors. These are both configured by using the corresponding attributes in cn=config - nsslapd-maxdescriptors and nsslapd-reservedescriptors.
Upon startup, the server creates a pool of operation threads. The number of threads is set by the attribute nsslapd-threadnumber in cn=config. The default number strikes a pretty good balance between being network I/O bound and CPU bound. The number can be multiplied by the number of CPUs in the system. The server polls to see what file descriptors have activity. Each active connection has a Connection object associated with it. If there is a new connection, a new Connection object is created. The server then loops through the active connections. For each one, it creates a new operation, puts it in a queue, and notifies the operation thread pool. The connection management code also looks for possible DoS attempts, idle connections, and things of that nature. Each thread in the operation thread pool will dequeue and perform operations until there are no more operations in the queue. The first thing the operation thread does is determine what type of LDAP operation is being requested, by reading just enough of the LDAP PDU to determine that information. It then calls a function whose name corresponds to the LDAP operation e.g. the function do_add() is called for LDAP ADD operations. The do_OP function reads the rest of the PDU including any request controls, processes the operation, and sends the response. The server code uses the Mozilla LDAP C SDK ber library to do the reading and the writing. The SDK allows us to replace the actual calls it uses to read and write. For non-SSL connections the functions read_function() and write_function() are used to actually read and write to the network connection. secure_read_function() and secure_write_function() are used for SSL connections.