The XDS interface comprises a number of functions, together with many OM classes of OM objects, which are used as the parameters and results of the functions. Both the functions and the OM objects are based closely on the Abstract Service that is specified in the standards (see \*EThe Directory: Abstract Service Definition\*O, ISO 9594-3, CCITT X.511).
The interface models the directory interactions as service requests made through a number of interface functions, which take a number of input parameters. Each valid request causes an operation within the Directory Service, which eventually returns a status and any result of the operation.
All interactions between the user and the Directory Service belong to a session, which is represented by an OM object passed as the first parameter to most interface functions.
The other parameters to the functions include a context and various service-specific parameters. The context includes a number of parameters that are common to many functions, and that seldom change from operation to operation.
Each of the components of this model are described in the following sections in this chapter along with other features of the interface, such as security.
The XDS interface defines an API that application programs can use to access the functionality of the underlying Directory Service. The DCE XDS API conforms to the \*EX/Open CAE Specification, API to Directory Services (XDS)\*O (November 1991).
The DCE XDS implementation supports the following features:
This call does not issue a Directory Service abandon operation. It returns with a DS_E_TOO_LATE) error. For details on abandoning operations see Section 10.10.3.
If there are any outstanding operations (when multiple threads issue XDS calls in parallel), this function returns DS_SUCCESS with the completion_flag_return parameter set to DS_OUTSTANDING_OPERATIONS. If no XDS calls are outstanding, this function returns DS_SUCCESS with the completion_flag_return parameter set to DS_NO_OUTSTANDING_OPERATION.
The programmer controls this mapping through the local_strings boolean parameter. To request conversion, set this parameter to OM_TRUE. The mappings currently suported are
For details on these mappings refer to the Appendixes D and F of the OSF DCE GDS Administration Guide and Reference.
On input, when requesting conversion of LATIN-1 characters to T.61 format, then you should only use the T.61 subset; otherwise an error is returned.
DCE XDS supports five packages, of which one is mandatory and four are optional. Use of the optional packages is negotiated by using ds_version(). The packages are as follows:
None of the OM classes defined in these five packages are encodable. Thus, DCE XDS application programmers do not require the use of the XOM functions om_encode and om_decode, which are not supported by the DCE XOM API.
As mentioned already, the standards define Abstract Services that requestors use to interact with the directory. Each of these Abstract Services maps to a single function call, and the detailed specifications are given in the XDS reference pages. The services and the function calls to which they map are as follows:
There is a function called ds_receive_result, which has no counterpart in the Abstract Service. It is used with asynchronous operations. (See the XDS xds_intro(3xds) reference page for information on how the asynchronous functions ds_abandon and ds_receive_result are handled by the DCE XDS API.)
The ds_initialize(), ds_shutdown(), and ds_version() functions are used to control the XDS API and do not initiate any directory operations.
The interface functions are summarized in Table 10-1.
| Name | Description |
|---|---|
| ds_abandon() | Abandons the result of a pending asynchronous operation. This function is not supported (see xds_intro(3xds). |
| ds_add_entry() | Adds a leaf entry to the DIT. |
| ds_bind() | Opens a session with a DUA, which in turn connects to a DSA. |
| ds_compare() | Compares a purported attribute value with the attribute value stored in the DIB for a particular entry. |
| ds_initialize() | Initializes the XDS interface. |
| ds_list() | Enumerates the names of the immediate subordinates of a particular directory entry. |
| ds_modify_entry() | Atomically performs modification to a directory entry. |
| ds_modify_rdn() | Changes the RDN of a leaf entry. |
| ds_read() | Queries information on a particular directory entry by name. |
| ds_receive_result | Retrieves the result of an asynchronously executed function. See xds_intro(3xds). |
| ds_remove_entry() | Removes a leaf entry from the DIT. |
| ds_search() | Finds entries of interest in a portion of the DIT. |
| Discards a workspace. | |
| ds_unbind() | Unbinds from a directory session. |
| ds_version() | Negotiates features of the interface and service. |
The interface has an initialization and shutdown sequence that permits the negotiation of optional features. This involves the ds_initialize(), ds_version(), and ds_shutdown() functions.
Every application program must first call ds_initialize(), which returns a workspace. This workspace supports the standard Directory Service Package (see Chapter 11).
The workspace can be extended to support the optional Basic Directory Contents Package (see Chapter 12), the Strong Authentication Package (see Chapter 13), the Global Directory Service Package (see Chapter 15), or the MHS Directory User Package (see Chapter 14). These packages are identified by means of OSI object identifiers, and these object identifiers are supplied to ds_version() to incorporate the extensions into the workspace.
After a workspace with the required features is negotiated in this way, the application can use the workspace as required. It can create and manipulate OM objects by using the OM functions, and it can start one or more directory sessions by using ds_bind().
After completing its tasks, terminating all its directory sessions by using ds_unbind(), and releasing all its OM objects by using om_delete(), the application needs to ensure that resources associated with the interface are freed by calling ds_shutdown().
It is possible to retain access to service-generated public objects after ds_shutdown() is called, or to start another cycle by calling ds_initialize() if so required by the application design.
A session identifies the DUA and the suite of DSAs to which a particular directory operation is sent. It contains some DirectoryBindArguments, such as the distinguished name of the requestor. The session parameter is passed as the first parameter to most interface functions.
A session is described by an OM object of OM class DS_C_SESSION. It is created and appropriate parameter values can be set using the OM functions. A directory session then starts with ds_bind() and later terminates with ds_unbind(). A session with default parameters can be started by passing the constant DS_DEFAULT_SESSION as the DS_C_SESSION parameter to ds_bind().
The ds_bind() function must be called before DS_C_SESSION can be used as a parameter to any other function in this interface. After ds_unbind() is called, ds_bind() must be called again if another session is to be started.
The interface supports multiple concurrent sessions so that an application implemented as a single process, such as a server in a client/server model, can interact with the directory by using several identities, and a process can interact directly and concurrently with different parts of the directory.
Details of the OM class DS_C_SESSION are given in Chapter 11.
The context defines the characteristics of the directory interaction that are specific to a particular directory operation; nevertheless, the same characteristics are often used for many operations. Since these parameters are presumed to be relatively static for a given directory user during a particular directory interaction, these parameters are collected into an OM object of OM class DS_C_CONTEXT, which is supplied as the second parameter of each Directory Service request. This reduces the number of parameters passed to each function.
The context includes many administrative details, such as the CommonArguments defined in the Abstract Service, which affect the processing of each directory operation. These include a number of ServiceControls, which allow control over some aspects of the service. The ServiceControls include options such as preferChaining, chainingProhibited, localScope, dontUseCopy, and dontDereferenceAliases, together with priority, timeLimit, sizeLimit, and scopeOfReferral. Each of these is mapped onto an OM attribute in the context (see Chapter 11).
The effect of passing the context parameter is as if its contents were passed as a group of additional parameters for every function call. The value of each component of the context is determined when the interface function is called, and it remains fixed throughout the operation.
All OM attributes in the class DS_C_CONTEXT have default values, some of which are administered locally. The constant DS_DEFAULT_CONTEXT can be passed as the value of the DS_C_CONTEXT parameter to the interface functions, and it has the same effect as a context OM object created with default values. The context must be a private object, unless it is DS_DEFAULT_CONTEXT.
(See Chapter 11 for detailed specifications of the OM class DS_C_CONTEXT.)
The Abstract Service defines specific parameters for each operation. These are mapped onto corresponding parameters to each interface function, which are also called input parameters. Although each service has different parameters, some specific parameters recur in several operations and these are briefly introduced here. (For complete details of these parameters, see Chapter 11.)
All parameters that are OM objects can generally be supplied to the interface functions as public objects (that is, descriptor lists) or as private objects. Private objects must be created in the workspace that is returned by ds_initialize(). In some cases, constants can be supplied instead of OM objects.
Note: Wherever a function can accept an instance of a particular OM class as the value of a parameter, it also accepts an instance of any subclass of the OM class. For example, most functions have a name parameter, which accepts values of OM class DS_C_NAME. It is always acceptable to supply an instance of the subclass DS_C_DS_DN as the value of the parameter.
Each directory attribute is represented in the interface by an OM object of OM class DS_C_ATTRIBUTE. The type of the directory attribute is represented by an OM attribute, DS_ATTRIBUTE_TYPE, within the OM object. The values of the directory attribute are expressed as the values of the OM attribute DS_ATTRIBUTE_VALUES.
The representation of the attribute value depends on the attribute type and is determined as indicated in the following list. The list describes the way in which an application program must supply values to the interface; for example, in the changes parameter to ds_modify_entry(). The interface follows the same rules when returning attribute values to the application; for example, in the ds_read() result.
Note: The distinguished encoding specified in the standards (see Clause 8.7 of The Directory: Authentication Framework, ISO 9594-8, CCITT X.500) must be used if the request is to be signed.
An Attribute Value Assertion (AVA) is an assertion about the value of an attribute of an entry, and it can be TRUE, FALSE, or undefined. It consists of an attribute type and a single value. In general, the AVA is TRUE if one of the values of the given attribute in the entry matches the given value. An AVA is represented in the interface by an instance of OM class DS_C_AVA, which is a subclass of DS_C_ATTRIBUTE and can only have one value.
Information used by ds_add_entry() to construct a new directory entry is represented by an OM object of OM class DS_C_ATTRIBUTE_LIST, which contains a single multivalued OM attribute whose values are OM objects of OM class DS_C_ATTRIBUTE.
The selection parameter of the ds_read() and ds_search() operations tailors its results to obtain just part of the required entry. Information on all attributes, no attributes, or a specific group of attributes can be chosen. Attribute types are always returned, but the attribute values are not necessarily returned.
The value of the parameter is an instance of OM class DS_C_ENTRY_INFO_SELECTION, but one of the constants in the following list can be used in simple cases:
To choose a particular set of attributes, create a new instance of the OM class DS_C_ENTRY_INFO_SELECTION and set the appropriate OM attribute values by using the OM functions.
Most operations take a name parameter to specify the target of the operation. The name is represented by an instance of one of the subclasses of the OM class DS_C_NAME. The DCE XDS API defines the subclass DS_C_DS_DN to represent distinguished names and other names.
For directory interrogations, any aliases in the name are dereferenced, unless prohibited by the DS_DONT_DEREFERENCE_ALIASES service control. However, for modify operations, this service control is ignored if set, and aliases are never dereferenced.
RDNs are represented by an instance of one of the subclasses of the OM class DS_C_RELATIVE_NAME. The DCE XDS API defines the subclass DS_C_DS_RDN to represent RDNs.
All XDS functions return a DS_status, which is the C function result; most return data in an invoke_id parameter, which identifies the particular invocation, and the interrogation operations each return data in the result parameter. The invoke_id\*O and \*Vresult values are returned using pointers that are supplied as parameters of the C function. These three types of function results are introduced in the following subsections.
All OM objects returned by interface functions (results and errors) are private objects in the workspace returned by ds_initialize().
All interface functions that invoke a Directory Service operation return an invoke_id parameter, which is an integer that identifies the particular invocation of an operation. Since asynchronous operations (within the same thread) are not supported, the invoke_id return value is no longer relevant for operations. DCE application programmers must still supply this parameter as described in the XDS reference pages, but should ignore the value returned.
Directory Service interrogation operations return a result value only if they succeed. All errors from these operations, including Directory Access Protocol (DAP) errors, are reported in DS_status (see Section 10.7.3), as are errors from all other operations.
The result of an interrogation is returned in a private object whose OM class is appropriate to the particular operation. The format of directory operation results is driven by the Abstract Service. To simplify processing, the result of a single operation is returned in a single OM object, which corresponds to the abstract result defined in the standards. The components of the result of an operation are represented by OM attributes in the operation's result object. All information contained in the Abstract Service result is made available to the application program. The result is inspected using the functions provided in the Object Management API, om_get().
Only the interrogation operations produce results, and each type of interrogation has a specific OM class of OM object for its result. These OM classes are as follows (see Chapter 11 for their definitions):
The results of the different operations share several common components, including the CommonResults defined in the standards (see \*EThe Directory: Abstract Service Definition\*O, ISO 9594-3, CCITT X.511) by inheriting OM attributes from the superclass DS_C_COMMON_RESULTS. An additional common component is the full DN of the target object, after all aliases are dereferenced.
The actual OM class of the result can always be a subclass of that named in order to allow flexibility for extensions. Thus, om_instance() always needs to be used when testing the OM class.
Any attribute values in the result are represented as discussed in Section 10.6.1.
Every interface function returns a DS_status value, which is either the constant DS_SUCCESS or an error. Errors are represented by private objects whose OM class is a subclass of DS_C_ERROR. Details of all errors are given in Chapter 11.
Other results of functions are not valid unless the status result has the value DS_SUCCESS.
Since asynchronous use of the interface (within the same thread) is not supported, the value of the DS_C_CONTEXT is always OM_FALSE, causing all operations within the same thread to be synchronous.
In synchronous mode, all functions wait until the operation is complete before returning. The thread of control is blocked within the interface after calling a function, and it can use the result immediately after the function returns.
Implementations define a limit on the number of asynchronous operations that can be outstanding at any one time on any one session. The limit is given by the implementation-defined constant DS_MAX_OUTSTANDING_OPERATIONS. It always has the value 0 (zero) because asynchronous operations within the same thread are not supported.
All errors occurring during a synchronous request are reported when the function returns. (See Chapter 11 for complete details of error handling.)
The DS_C_SESSION is not used by the DCE XDS API and is always set to DS_NO_VALID_FILE_DESCRIPTOR.
The X/Open XDS specifications do not define a security interface because this can put constraints on security features of existing directory implementations.
DCE GDS provides an extension to the XDS API for security support. This is achieved at the XDS API level through a new DSX_C_GDS_SESSION session object which contains information on the security mechanism that should be used. Simple authentication through the use of name and password, and external authentication based on DCE security are supported. (See Chapter 15 for additional information.)
The following subsections describe these features of the interface:
An implementation can provide automatic management of the association or connection between the user and the Directory Service, making and releasing connections at its discretion.
The DCE XDS implementation does not support automatic connection management. A DSA connection is established when ds_bind() is called and released when ds_unbind() is called.
The interface provides automatic handling of continuation references and referrals in order to reduce the burden on application programs. These facilities can be inhibited to meet special needs.
A continuation reference describes how the performance of all or part of an operation can be continued at a different DSA or DSAs. A single continuation reference returned as the entire response to an operation is called a referral and is classified as an error. One or more continuation references can also be returned as part of DS_PARTIAL_OUTCOME_QUAL returned from a ds_list() or ds_search() operation.
A DSA returns a referral if it has administrative, operational, or technical reasons for preferring not to chain. It can return a referral if DS_CHAINING_PROHIB is set in the DS_C_CONTEXT, or instead it can report a service error (DS_E_CHAINING_REQUIRED) in this case.
By default, the implementation uses any continuation references it receives to try to contact the other DSA or DSAs, enabling it to make further progress in the operation, whenever practical. It only returns the result, or an error, to the application after it has made this attempt. Note that continuation references can still be returned to the application; for example, if the relevant DSA cannot be contacted.
The default behavior is the simplest for most applications but, if necessary, the application can cause all continuation references to be returned to it. It does this by setting the value of the OM attribute DS_AUTOMATIC_CONTINUATION in the DS_C_CONTEXT to OM_FALSE.
The XDS user can abandon a directory operation when operating in multithreaded mode. An operation is abandoned by calling pthread_cancel() to cancel the thread that issued the directory operation. General cancelability must be enabled; otherwise, the cancelability will be ignored.
XDS will react as follows, depending on when the cancel is delivered:
It is the responsibility of the user to handle the cancel exception in the last case and, if necessary, to discard the result.