Sun Java System Directory Server Enterprise Edition 6.3 Reference

Chapter 10 Directory Server DSMLv2

For information about DSMLv2 in Directory Server, see the following sections:

Introduction to DSML

Directory Services Markup Language version 2, DSMLv2, is a markup language that describes directory operations in an eXtensible Markup Language (XML) document. For information about the DSMLv2 standard, see Directory Services Markup Language (DSML) v2.0 [OASIS 200201] at http://www.oasis-open.org/specs.

The complete DSMLv2 specification and supporting documentation can be found at the following locations:

Directory Server supports DSMLv2 SOAP over HTTP binding. DSML requests and responses are embedded in the body of SOAP v1.1, and transported in an HTTP/1.1 payload.

The Directory Server Resource Kit contains tools for searching and modifying directories using DSMLv2. See dsmlsearch(1) and dsmlmodify(1).

By using DSML, non-LDAP clients can perform directory operations. The following figure shows an example deployment where a non-LDAP client makes a requests to modify data on DSML-enabled directory servers.

Figure 10–1 Sample DSML-Enabled Directory Deployment

Figure shows an example deployment where a non-LDAP client
makes modification requests to DSML-enabled directory servers.

In the example deployment, update requests in DSML arrive from non-LDAP client applications cross a firewall over HTTP port 80. The web proxy server enforces the use of secure HTTP over port 443 for the requests to cross a second firewall and enter the intranet domain. The requests are then processed by the two master replicas on Master A and Master B, before being replicated to the non-DSML enabled Consumers C and D.

Implementation of the DSMLv2 Standard

The Directory Server implementation of the DSMLv2 specification has the following restrictions:

Bindings

DSMLv2 defines two normative bindings: a SOAP request/response binding and a file binding that serves as the DSMLv2 analog of LDIF. Directory Server supports the SOAP request/response binding.

Modify DN

Directory Server supports the DSML modDNRequest and modDNResponse operations.

Abandon request

Directory Server does not support the abandonRequest operation, because this operation is of no use over HTTP.

Search operations

Some DSML clients incorrectly send an equality match with value * when a presence match is intended. Directory Server will return zero results from these badly formatted queries. You can detect these incorrect clients by searching for the characters =\2a in the access log.

DSML Security

The DSML front end constitutes a restricted HTTP server; it accepts only DSML post operations, it rejects requests that do not conform to the DSMLv2 SOAP binding specifications.

The security of DSML is configured by the following server properties dsml-client-auth-mode, dsml-port, dsml-secure-port, and dsml-relative-root-url. For information about these properties, see server(5dsconf).

For additional security, consider the following.

DSML Identity Mapping

Identity mapping is required for the following mechanisms: DSML over HTTP, DIGEST-MD5, and GSSAPI SASL. Identity mapping is used to determine a bind DN based on protocol specific credentials provided by the client.

Identity mapping uses the entries in the cn=identity mapping, cn=config configuration branch. This branch includes the following containers for the protocols that perform identity mapping:

cn=HTTP-BASIC, cn=identity mapping, cn=config

Contains the mappings for DSML-over-HTTP connections.

cn=DIGEST-MD5, cn=identity mapping, cn=config

Contains the mappings for client authentication using the DIGEST-MD5 SASL mechanism.

cn=GSSAPI, cn=identity mapping, cn=config

Must be created to contain the mappings for client authentication using the GSSAPI SASL mechanism.

A mapping entry defines how to extract credentials about the protocol to use them in a search operation. If a search returns a single user entry, the mapping has succeeded and the connection uses the mapping entry as the bind DN for all operations. If the search returns zero or more than one entry, the mapping fails and the connection does not use the mapping entry as the bind DN.

The protocols that perform identity mapping must have a default mapping. Additionally, The protocols can have any number of custom mappings. The default mapping has the RDN cn=default, and custom mappings may have any other RDN that uses cn as the naming attribute. All of the custom mappings are evaluated first, in a non deterministic order until one of them succeeds. If all custom mappings fail, the default mapping is applied. If the default mapping fails, authentication of the client fails.

A mapping entry must contain the object classes top, container, and dsIdentityMapping.

The entry can contain the following attributes.

dsMappedDN: DN

A literal string that defines a DN in the directory. This DN will be used for binding if it exists when the mapping is performed. You may also define the following attributes to perform a search in case this DN does not exist.

dsSearchBaseDN: DN

The base DN for a search. If omitted, the mapping will search all root suffixes in the entire directory tree, including all naming contexts, but excluding cn=config, cn=monitor, and cn=schema.

dsSearchScope: base|one|sub

The scope for a search, either the search base itself, one level of children below the base, or the entire subtree below the base. The default scope for mapping searches is the entire subtree when this attribute is omitted.

dsSearchFilter: filterString

A filter string to perform the mapping search. LDAP search filters are defined in RFC 4515 on http://www.ietf.org/rfc/rfc4515.txt.

Additionally, a mapping entry may also contain the dsPatternMatching object class which allows it to use the following attributes:

dsMatching-pattern: patternString

A string on which to perform pattern matching.

dsMatching-regexp: regularExpression

A regular expression to apply to the pattern string.

All of the attribute values above, except for dsSearchScope may contain placeholders of the format ${keyword}, where keyword is the name of an element in the protocol-specific credentials. During mapping, the placeholder is substituted for the actual value of the element provided by the client.

After all of the placeholders have been substituted, the pattern matching is performed. The matching pattern is compared to the regular expression, as follows.

For example, the following mapping could be defined for SASL.

dsMatching-pattern: ${Principal}
dsMatching-regexp: (.*)@(.*)\\.(.*)
dsMappedDN: uid=$1,ou=people,dc=$2,dc=$3

If a client authenticates with the Principal of bjensen@example.com, this mapping will define the following bind DN: uid=bjensen,ou=people,dc=example,dc=com. If this DN exists in the directory, the mapping will succeed, the client will be authenticated, and all operations performed during this connection will use this bind DN.

The dsMatching-pattern is compared to the dsMatching-regexp by using the POSIX regexec(3C) and regcomp(3C) function calls. Directory Server uses extended regular expressions and all comparisons are case insensitive. For more information, refer to the man pages for these functions.

The attribute values that can contain placeholders must encode any $, {, and } characters that are not part of a placeholder, even if no placeholder is used. You must encode these characters with the following values: $ as \\24, { as \\7B, and } as \\7D.

The use of placeholders and substitutions allows you to create mappings that extract a username or any other value from the protocol-specific credentials. The credential can be used to define a mapped DN or perform a search for a corresponding DN anywhere in the directory.


Caution – Caution –

Creating a poorly defined mapping is a security hole. For example, a mapping to a hard coded DN without pattern matching will always succeed, thereby authenticating clients who might not be directory users. It is safer to define several mappings to handle different client credential formats than to create a single, overly generic and permissive mapping. Always try to map client connections to specific users according to the client credentials.


Content of the HTTP Header

Directory Server supports the HTTP POST operation only. The following example shows the minimum fields required to send a DSML request to the server over HTTP:

POST /dsml HTTP/1.1
content-length: 450
HOST: hostname
SOAPAction: ""
Content-Type: text/xml
Connection: close

The Connection field is optional. In HTTP 1.0, the default value of this field is close. In HTTP 1.1, however, the default value is keep-alive. It is therefore recommended that you include this field with a value of close in your last request if you are using HTTP 1.1, to accelerate the dialog.

Additional fields may be included in the HTTP header. If they are supported by Directory Server, their values will override the defaults. If the fields are not supported, the request is not rejected by the server but the fields are ignored.

Accessing the Directory Using DSMLv2

The following examples indicate how to use DSML requests to access and search the directory.

Note that the content-length: header in these examples contains the exact length of the DSMLv2 request. For these examples to function correctly, ensure that the editor you use respects these content lengths, or that you modify them accordingly.

An Empty Anonymous DSML Ping Request

The DSML front end is disabled by default. For information on how to enable it, refer to Configuring DSML in Sun Java System Directory Server Enterprise Edition 6.3 Administration Guide. To check whether the DSML front end is enabled, send an empty DSML batch request, as shown in Example 10–1.


Example 10–1 Empty Anonymous DSML Request

POST /dsml HTTP/1.1
 content-length: 451
 HOST: hostname
 SOAPAction: ""
 Content-Type: text/xml
Connection: close
<?xml version=’1.0’ encoding=’UTF-8’?\>
 <soap-env:Envelope
    xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’\>
   <soap-env:Body\>
       <batchRequest
           xmlns=’urn:oasis:names:tc:DSML:2:0:core’           requestID=’Ping!’\>
           <!-- empty batch request --\>
      </batchRequest\>
    </soap-env:Body\>
 </soap-env:Envelope\>

The first section of this DSML request contains the HTTP method line, POST /dsml HTTP/1.1, followed by a number of HTTP headers. The HTTP method line specifies the HTTP method request and URL to be used by the DSML front end. POST is the only HTTP method request accepted by the DSML front end. The /dsml URL is the default URL for Directory Server, but can be configured with any other valid URL. The HTTP headers that follow, specify the remaining details of the DSML request.


Example 10–2 Empty Anonymous DSML Response

HTTP/1.1 200 OK
Cache-control: no-cache
Connection: close
Date: Mon, 11 Dec 2006 13:56:49 GMT
Accept-Ranges: none
Server: Sun-Java(tm)-System-Directory/6.3
Content-Type: text/xml; charset="utf-8"
Content-Length: 500
<?xml version=’1.0’ encoding=’UTF-8’ ?\>
<soap-env:Envelope
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’
   \>
<soap-env:Body\>
<batchResponse
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns=’urn:oasis:names:tc:DSML:2:0:core’
   requestID=’Ping!’
   \>
</batchResponse\>
</soap-env:Body\>
</soap-env:Envelope\>

If nothing is returned, you can conclude that the front end is disabled.

Maximum limits exist for the number of clients connecting simultaneously to the directory and for the size of the DSML requests. The limit for the number of clients is specified by the dsml-max-parser-count and dsml-min-parser-count server properties and the request size limit by the server property dsml-request-max-size. See server(5dsconf).

Issuing a DSML Request to Bind as a Particular User

To issue a DSML request you can bind to the directory as a specified user or anonymously. To bind as a specified user, the request must include an HTTP authorization header containing a UID and a password that are mapped to a DN, as shown in Example 10–3.


Example 10–3 DSML Extended Operation: Bind as a Particular User

POST /dsml HTTP/1.1
content-length: 578
content-Type: text/xml; charset="utf-8"
HOST: hostname
Authorization: Basic ZWFzdGVyOmVnZw==
SOAPAction: ""
Connection: close
<?xml version=’1.0’ encoding=’UTF-8’?\>
<soap-env:Envelope
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’\>
   <soap-env:Body\>
     <batchRequest
        xmlns=’urn:oasis:names:tc:DSML:2:0:core’\>
        <extendedRequest\>
          <requestName\>1.3.6.1.4.1.4203.1.11.3</requestName\>
        </extendedRequest\>
     </batchRequest\>
   </soap-env:Body\>
</soap-env:Envelope\>

In this example the HTTP authorization header transports the user ID easter and the password egg, which, in clear, appears as easter:egg, and encoded in base64 as Authorization: Basic ZWFzdGVyOmVnZw==.

The <extendedRequest\> tag is used to specify an LDAP Extended Operation. The <requestName\> tag is used to specify the OID of the extended operation. In this example, the OID 1.3.6.1.4.1.4203.1.11.3 identifies the whoami extended operation.

The response to the DSML extended operation shows the DN of the user that made the bind request. In Example 10–4, the whoami response, which contains the DN, is shown in the response line.

<response\>dn:uid=easter,ou=people,dc=example,dc=com</response\>

Example 10–4 Response to DSML Extended Operation

HTTP/1.1 200 OK
Cache-control: no-cache
Connection: close
Date: Fri, 15 Dec 2006 09:15:09 GMT
Accept-Ranges: none
Server: Sun-Java(tm)-System-Directory/6.3
Content-Type: text/xml; charset="utf-8"
Content-Length: 697

<?xml version=’1.0’ encoding=’UTF-8’ ?\>
<soap-env:Envelope
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’
   \>
<soap-env:Body\>
<batchResponse
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns=’urn:oasis:names:tc:DSML:2:0:core’
   \>
   <extendedResponse\>
      <resultCode code=’0’ descr=’success’/\>
   <responseName\>1.3.6.1.4.1.4203.1.11.3</responseName\>
   <response\>dn:uid=easter,ou=people,dc=example,dc=com</response\>
   </extendedResponse\>
</batchResponse\>
</soap-env:Body\>
</soap-env:Envelope\>

For anonymous access, no HTTP authorization header is required, although anonymous access is often subject to strict access controls, and possibly to data access restrictions. Similarly, you can issue DSML requests to perform LDAP operations by LDAP proxy.

Because DSML requests are managed on a batch basis, if you issue requests by LDAP proxy, the required DSML proxy authorization request must be the first in a given batch of requests.

A DSML Search Request

Example 10–5 shows a DSML base object search request on the root DSE entry.


Example 10–5 DSML Search Request

POST /dsml HTTP/1.1
HOST: hostname
Content-Length: 1081
Content-Type: text/xml
SOAPAction: ""
Connection: close
<?xml version=’1.0’ encoding=’UTF-8’?\>
<soap-env:Envelope
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’
   \>
   <soap-env:Body\>
      <batchRequest
        xmlns=’urn:oasis:names:tc:DSML:2:0:core’
        requestID=’Batch of search requests’
        \>
        <searchRequest
            dn=""
            requestID="search on Root DSE"
            scope="baseObject"
            derefAliases="neverDerefAliases"
            typesOnly="false"
            \>
            <filter\>
               <present name="objectClass"/\>
            </filter\>
            <attributes\>
               <attribute name="namingContexts"/\>
               <attribute name="supportedLDAPversion"/\>
               <attribute name="vendorName"/\>
               <attribute name="vendorVersion"/\>
               <attribute name="supportedSASLMechanisms"/\>
            </attributes\>
        </searchRequest\>
      </batchRequest\>
   </soap-env:Body\>
</soap-env:Envelope\>


Example 10–6 DSML Search Response

HTTP/1.1 200 OK
Cache-control: no-cache
Connection: close
Date: Fri, 15 Dec 2006 09:21:43 GMT
Accept-Ranges: none
Server: Sun-Java(tm)-System-Directory/6.3
Content-Type: text/xml; charset="utf-8"
Content-Length: 1287

<?xml version=’1.0’ encoding=’UTF-8’ ?\>
<soap-env:Envelope
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns:soap-env=’http://schemas.xmlsoap.org/soap/envelope/’
   \>
<soap-env:Body\>
<batchResponse
   xmlns:xsd=’http://www.w3.org/2001/XMLSchema’
   xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
   xmlns=’urn:oasis:names:tc:DSML:2:0:core’
   requestID=’Batch of search requests’
   \>
   <searchResponse requestID=’search on Root DSE’\>
   <searchResultEntry\>
      <attr name=’namingContexts’\>
      <value\>dc=example,dc=com</value\>
      </attr\>
      <attr name=’supportedLDAPVersion’\>
      <value\>2</value\>
      <value\>3</value\>
      </attr\>
      <attr name=’vendorName’\>
      <value\>Sun Microsystems, Inc.</value\>
      </attr\>
      <attr name=’vendorVersion’\>
      <value\>Sun-Java(tm)-System-Directory/6.3</value\>
      </attr\>
      <attr name=’supportedSASLMechanisms’\>
      <value\>EXTERNAL</value\>
      <value\>GSSAPI</value\>
      <value\>DIGEST-MD5</value\>
      </attr\>
   </searchResultEntry\>
   <searchResultDone\>
      <resultCode code=’0’ descr=’success’/\>
   </searchResultDone\>
   </searchResponse\>
</batchResponse\>
</soap-env:Body\>
</soap-env:Envelope\>