Sun Java System LDAP SDK for C Programming Guide |
Chapter 10
Retrieving Server InformationThe Sun Java System LDAP SDK for C contains functions to access and modify information about your Lightweight Directory Access Protocol (LDAP) directory server. This chapter contains information about your server attributes and how to retrieve the information. It includes the following sections:
Understanding DSEsA directory server entry or DSE is an entry in the directory that contains information specific to the server. In a directory tree, the root of the tree is the root DSE. It is not part of any naming context. For example, it is above dc=example,dc=com in the directory tree.
Note
The root DSE is specified as part of the LDAPv3. LDAPv2 servers do not necessarily have a root DSE.
The root DSE can contain the following information:
- The naming contexts of this server (for example, dc=example,dc=com).
- URLs of alternate servers to contact if this server is unavailable.
- The versions of the LDAP supported by this server (for example, 2 or 3).
- The LDAPv3 controls supported by the server. See Chapter 13, "Working with LDAP Controls" for details.
- The SASL mechanisms supported by the server. See Chapter 12, "Using SASL Authentication" for details.
- The LDAPv3 extended operations supported by the server. See Chapter 15, "Extended Operations" for details.
Table 10-1 lists the types of information available in the different attributes of the root DSE.
Getting the Root DSEThis is the procedure to get the root DSE for an LDAP server.
- Initialize an LDAP session by calling the ldap_init() function.
- Turn off automatic referral handling by calling the ldap_set_option() function and setting the LDAP_OPT_REFERRALS option to LDAP_OPT_OFF.
- Search the directory using the following criteria:
- Set the search scope to a base search.
- Specify an empty string for the base DN.
- Use the search filter (objectclass=*).
Note
For details on how to use API functions to search the directory, see Chapter 5, "Searching a LDAP Directory."
- Check the results of the search.
If the server returns a result code such as LDAP_OPERATIONS_ERROR, LDAP_PROTOCOL_ERROR, LDAP_REFERRAL, or LDAP_NO_SUCH_OBJECT, the LDAP server probably does not support LDAPv3.
Code Example 10-1 gets the root DSE for a server and prints out its attributes. The function assumes that you are passing in a valid connection handle (LDAP structure) that you have created by calling ldap_init(). The function returns 0 if successful or 1 if an error occurred.
Determining LDAPv3 SupportYou can determine what version an LDAP server supports by getting the supportedLDAPVersion attribute from the root DSE. This attribute could contain the value 2 or 3.
Note
You do not need to authenticate or bind before searching the directory. Unlike LDAPv2, LDAPv3 states that clients do not need to bind to the server before performing LDAP operations.
Code Example 10-2 connects to an LDAP server and determines whether or not that server supports the LDAPv3.
Code Example 10-2 Determining the Supported LDAP Version
/* Function for determining if the LDAP server supports LDAPv3.
This function returns 1 if the server supports LDAPv3 or
0 if the server does not support LDAPv3.
*/
int
check_version( char *hostname, int portnum )
{
LDAP *ld;
int i, rc, v3supported = 0;
LDAPMessage *result, *e;
BerElement *ber;
LDAPControl **serverctrls = NULL, **clntctrls = NULL;
char *a, *dn;
char **vals;
char *attrs[2];
char *filter = "(objectClass=*)";
/* Check arguments */
if ( !hostname || !hostname[0] || !portnum ) {
printf( "Error: hostname or port number not specified\n" );
return( -1 );
}
/* Get a handle to an LDAP connection. */
if ( (ld = ldap_init( hostname, portnum )) == NULL ) {
perror( "ldap_init" );
return( -1 );
}
/* Set automatic referral processing off. */
if (ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != LDAP_SUCCESS) {
ldap_perror( ld, "ldap_set_option" );
return( -1 );
}
/* Search for the root DSE and get the supportedLDAPVersion attribute. */
attrs[0] = "supportedLDAPVersion";
attrs[1] = NULL;
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, filter, attrs, 0,
serverctrls, clntctrls, NULL, 0, &result );
/* Check the search results. */
switch( rc ) {
/* If successful, the root DSE was found. */
case LDAP_SUCCESS:
break;
/* If the root DSE was not found, the server does not comply
with the LDAPv3 protocol. */
case LDAP_PARTIAL_RESULTS:
case LDAP_NO_SUCH_OBJECT:
case LDAP_OPERATIONS_ERROR:
case LDAP_PROTOCOL_ERROR:
ldap_perror( ld, "ldap_search_ext_s" );
return( 0 );
break;
/* If an different result code is returned, an error may have
occurred (for example, the server may be down. */
default:
ldap_perror( ld, "ldap_search_ext_s" );
return( -1 );
break;
}
/* Get the values of the supportedLDAPVersion attribute in the entry. */
if (( e = ldap_first_entry( ld, result )) != NULL &&
( a = ldap_first_attribute( ld, e, &ber )) != NULL &&
(vals = ldap_get_values( ld, e, a)) != NULL ) {
for ( i = 0; vals[i] != NULL; i++ ) {
if ( !strcmp( "3", vals[i] ) ) {
v3supported = 1;
break;
}
}
/* Free any memory allocated. */
ldap_value_free( vals );
ldap_memfree( a );
if ( ber != NULL ) {
ber_free( ber, 0 );
}
}
/* Free memory allocated by ldap_search_ext_s(). */
ldap_msgfree( result );
/* Free the ld structure. */
ldap_unbind_s( ld );
/* Return a value indicating whether or not LDAPv3 is supported. */
return( v3supported );
}
...
Getting Schema InformationIn the LDAPv3, an entry can specify the schema that defines the object classes, attributes, and matching rules used by the directory. This entry is called the subschema entry. To find the DN of the subschema entry, get the subschemaSubentry operational attribute from the root DSE or any entry.
Note
See "Specifying Attributes to Retrieve" in Chapter 5, "Searching a LDAP Directory" for details on how to get attributes.
The subschema entry can have the following attributes:
- objectClasses specifies the object class definitions in the schema. Each value of this attribute is an object class that is known to the server.
- attributeTypes specifies the attribute type definitions in the schema. Each value of this attribute is an attribute type that is known to the server.
- matchingRules specifies the matching rule definitions in the schema. Each value of this attribute is a matching rule that is known to the server.
- matchingRuleUse specifies the use of a matching rule in the schema. (This specifies the attributes that can be used with this extensible matching rule.) Each value of this attribute is a matching rule use description.
For information on the the format of the attribute values, see RFC 2252 - Lightweight Directory Access Protocol (v3): Attribute Syntax Definitions (http://www.faqs.org/rfcs/rfc2252.html).