This chapter explains how you can call functions to parse an LDAP URL into its components and to process a search request specified by an LDAP URL.
The chapter contains the following sections:
An LDAP URL is a URL that begins with the ldap://
protocol prefix (or ldaps://, if the server is
communicating over an SSL connection) and specifies a search request
sent to an LDAP server.
LDAP URLs have the following syntax:
ldap[s]://hostname:portbase_dn?attributes?scope?filter
The ldap:// protocol is used to connect to LDAP
servers over unsecured connections, and the ldaps://
protocol is used to connect to LDAP servers over SSL connections.
Table 10-1 lists the components of an LDAP URL.
Table 10-1 - Components of an LDAP URL
| Component | Description |
|---|---|
hostname |
Name (or IP address in dotted format) of the LDAP server (for example,
ldap.example.com or 192.202.185.90).
|
port |
Port number of the LDAP server (for example, 696). If no port is specified, the standard LDAP port (389) is used. |
base_dn |
Distinguished name (DN) of an entry in the directory. This DN identifies the entry that is starting point of the search. If this component is empty, the search starts at the root DN. |
attributes |
The attributes to be returned. To specify more than one attribute,
use commas to delimit the attributes (for example,
"cn,mail,telephoneNumber").
If no attributes are specified in the URL, all attributes are
returned.
|
scope |
The scope of the search, which can be one of these values:
base
search.
|
filter |
Search filter to apply to entries within the specified scope of the
search.
If no filter is specified, the server uses the filter
(objectClass=*).
|
Any "unsafe" characters in the URL need to be represented by a
special sequence of characters (this is often called escaping
unsafe characters). For example, a space must be represented
as %20. Thus, the distinguished name "ou=Product
Development" must be encoded as
"ou=Product%20Development".
Note that attributes, scope, and
filter are identified by their positions in the URL.
If you do not want to specify any attributes, you still need to
include the question marks delimiting that field.
For example, to specify a subtree search starting from
"dc=example,dc=com" that returns all attributes for
entries matching "(sn=Jensen)", use the following URL:
ldap://ldap.example.com/dc=example,dc=com??sub?(sn=Jensen)
Note that the two consecutive question marks ("??") indicates that no attributes have been specified. Since no specific attributes are identified in the URL, all attributes are returned in the search.
The following LDAP URL specifies a base search for the entry with
the distinguished name "dc=example,dc=com".
ldap://ldap.example.com/dc=example,dc=com
"dc=example,dc=com"
"(objectclass=*)" is used.
The following LDAP URL retrieves the postalAddress
attribute of the dc=example,dc=com entry:
ldap://ldap.example.com/dc=example,dc=com?postalAddress
"dc=example,dc=com".
"(objectclass=*)" is used.
The following LDAP URL retrieves the cn,
mail, and telephoneNumber attributes of
the entry for Barbara Jensen:
ldap://ldap.example.com/uid=bjensen,ou=People,dc=example,dc=com? \ cn,mail,telephoneNumber
"uid=bjensen,ou=People,dc=example,dc=com".
"(objectclass=*)" is used.
The following LDAP URL specifies a search for entries that have
the last name Jensen and are at any level under
"dc=example,dc=com":
ldap://ldap.example.com/dc=example,dc=com??sub?(sn=Jensen)
sub, the search encompasses
the base entry "dc=example,dc=com" and entries at all
levels under the base entry.
The following LDAP URL specifies a search for the object class
for all entries one level under "dc=example,dc=com":
ldap://ldap.example.com/dc=example,dc=com?objectClass?one
one, the search encompasses
all entries one level under the base entry
"dc=example,dc=com". The search scope does not include
the base entry.
"(objectclass=*)" is used.
Note:The syntax for LDAP URLs does not include any
means for specifying credentials or passwords. Search requests
initiated through LDAP URLs are unauthenticated.
To determine whether a URL is an LDAP URL, call the
ldap_is_ldap_url()
function. This function returns a nonzero value if the URL is an
LDAP URL. If the URL is not an LDAP URL, the function returns 0.
The following section of code determines if a URL is an LDAP URL.
Code Example 10-1 - Parsing an LDAP URL
#include <ldap.h>
...
char *my_url = "ldap://ldap.ipalnet.com/dc=example,dc=com";
...
if ( ldap_is_ldap_url( my_url ) != 0 ) {
printf( "%s is an LDAP URL.\n", my_url );
} else {
printf( "%s is not an LDAP URL.\n", my_url );
}
...
To verify that a URL complies with the LDAP URL syntax, you
should call the
ldap_url_parse()
function (see "Getting the Components
of an LDAP URL").
To get the individual components of the URL, call the
ldap_url_parse()
function. This function returns the LDAP URL components in an
LDAPURLDesc structure,
which is shown here:
typedef struct ldap_url_desc {
char *lud_host;
int lud_port;
char *lud_dn;
char **lud_attrs;
int lud_scope;
char *lud_filter;
unsigned long lud_options;
} LDAPURLDesc;
Here is a list of the field descriptions:
Table 10-2 - ldap_url_desc field descriptions
lud_host |
The name of the host in the URL. |
lud_port |
The number of the port in the URL. |
lud_dn |
The distinguished name in the URL. |
lud_attrs |
A pointer to a NULL-terminated array of the
attributes specified in the URL.
|
lud_scope |
The scope of the search specified in the URL. This field can
have the following values:
|
lud_filter |
Search filter included in the URL. |
lud_options |
Options (if LDAP_URL_OPT_SECURE, indicates that
the protocol is ldaps:// instead of
ldap://).
|
The following section of code parses an LDAP URL and prints out each component of the URL.
Code Example 10-2 - Parsing an LDAP URL
#include <stdio.h>
#include <ldap.h>
...
char *my_url = "ldap://ldap.example.com:5000/dc=example,dc=com?cn,mail,telephoneNumber?sub?
(sn=Jensen)";
LDAPURLDesc *ludpp;
int res, i;
...
if ( ( res = ldap_url_parse( my_url, &ludpp ) ) != 0 ) {
switch( res ){
case LDAP_URL_ERR_NOTLDAP:
printf( "URL does not begin with \"ldap://\"\n" );
break;
case LDAP_URL_ERR_NODN:
printf( "URL missing trailing slash after host or port\n" );
break;
case LDAP_URL_ERR_BADSCOPE:
printf( "URL contains an invalid scope\n" );
break;
case LDAP_URL_ERR_MEM:
printf( "Not enough memory\n" );
break;
default:
printf( "Unknown error\n" );
}
return( 1 );
}
printf( "Components of the URL:\n" );
printf( "Host name: %s\n", ludpp->lud_host );
printf( "Port number: %d\n", ludpp->lud_port );
if ( ludpp->lud_dn != NULL ) {
printf( "Base entry: %s\n", ludpp->lud_dn );
} else {
printf( "Base entry: Root DN\n" );
}
if ( ludpp->lud_attrs != NULL ) {
printf( "Attributes returned: \n" );
for ( i=0; ludpp->lud_attrs[i] != NULL; i++ ) {
printf( "\t%s\n", ludpp->lud_attrs[i] );
}
} else {
printf( "No attributes returned.\n" );
}
printf( "Scope of the search: " );
switch( ludpp->lud_scope ) {
case LDAP_SCOPE_BASE:
printf( "base\n" );
break;
case LDAP_SCOPE_ONELEVEL:
printf( "one\n" );
break;
case LDAP_SCOPE_SUBTREE:
printf( "sub\n" );
break;
default:
printf( "Unknown scope\n" );
}
printf( "Filter: %s\n", ludpp->lud_filter );
...
The code prints out the following results:
Components of the URL: Host name: ldap.example.com Port number: 5000 Base entry: dc=example,dc=com Attributes returned: cn mail telephoneNumber Scope of the search: sub Filter: (sn=Jensen)
When you have finished working with the components of an LDAP
URL, you should free the
LDAPURLDesc structure
from memory by calling the
ldap_free_urldesc()
function.
The following section of code parses an LDAP URL and then frees
the LDAPURLDesc
structure from memory after verifying that the LDAP URL is valid.
Code Example 10-3 - Using ldap_free_urldesc() to free the components of an LDAP URL
#include <stdio.h>
#include <ldap.h>
...
char *my_url = "ldap://ldap.example.com:5000/dc=example,dc=com?cn,mail, \
telephoneNumber?sub?(sn=Jensen)";
LDAPURLDesc *ludpp;
int res, i;
...
if ( ( res = ldap_url_parse( my_url, &ludpp ) ) != 0 ) {
switch( res ){
case LDAP_URL_ERR_NOTLDAP:
printf( "URL does not begin with \"ldap://\"\n" );
break;
case LDAP_URL_ERR_NODN:
printf( "URL does not contain a distinguished name\n" );
break;
case LDAP_URL_ERR_BADSCOPE:
printf( "URL contains an invalid scope\n" );
break;
case LDAP_URL_ERR_MEM:
printf( "Not enough memory\n" );
break;
default:
printf( "Unknown error\n" );
}
return( 1 );
}
printf( "URL is a valid LDAP URL\n" );
ldap_free_urldesc( ludpp );
...
To process an LDAP URL search request, call the
ldap_url_search_s(),
ldap_url_search_st(),
or ldap_url_search()
function.
ldap_url_search_s() is
a synchronous function that completes the search operation before
returning. Call this function if you need to wait for the operation
to finish before continuing.
The ldap_url_search_s() function returns
LDAP_SUCCESS if the operation completed successfully.
If an error occurred, the function returns an error code. (See
"Result Codes" for a complete
listing of error codes.)
ldap_url_search_st() is
a synchronous function that allows a certain amount of time for the
completion of the search operation. Call this function if you need to
wait for the operation to complete and if you want to set a timeout
period for the operation.
ldap_url_search() is an
asynchronous function that initiates the search operation but does
not wait for the operation to complete. Call this function if you
want to perform other work (in parallel) while waiting for the
operation to complete.
The ldap_url_search() function returns a message ID
identifying the search operation. To determine whether the operation
is completed or still in progress, call the
ldap_result() function.
After the operation is completed, call the
ldap_result2error()
function to determine whether the operation was successful. If the
operation completed successfully, the ldap_result2error()
function returns LDAP_SUCCESS. If an error occurred,
the function returns an error code. See Chapter
19 - Result Codes for a complete listing.
For more information about the difference between synchronous and asynchronous functions, see "Calling Synchronous and Asynchronous Functions."
The following example processes a search request from an LDAP URL.
Code Example 10-4 - Processing an LDAP URL search request
#include <ldap.h>
...
LDAP *ld;
LDAPMessage *result;
char *my_url = "ldap://ldap.example.com/dc=example,dc=com?cn,mail, \
telephoneNumber?sub?(sn=Jensen)";
/* Process the search request in the URL. */
if ( ldap_url_search_s( ld, my_url, 0, &result ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_url_search_s" );
return( 1 );
}