<!--

Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
Portions copyright 1999 Netscape Communications Corporation. All
Rights Reserved.

The contents of this document are subject to the terms of the
Creative Commons Attribution-ShareAlike 2.5 license or any later
version (the "License"). You may not use this document except in
compliance with the License.

See the License for the specific language governing
permissions and limitations under the License. You can obtain
a copy of the License at
http://creativecommons.org/licenses/by-sa/2.5/legalcode.

-->
<chapter id="csdk-urls"><title>LDAP URLs With &DirectorySDKForC;</title>
<indexterm>
<primary>C SDK</primary>
<secondary>LDAP URLs</secondary>
</indexterm><highlights>
<para>This chapter describes how to use LDAP URLs to search and retrieve data
from the directory.</para>
<itemizedlist>
<para>This chapter covers the following topics:</para>
<listitem><para><olink targetptr="bdahp">Checking an LDAP URL With Directory
SDK for C</olink></para></listitem>
<listitem><para><olink targetptr="bdahq">Getting the Components of an LDAP
URL With Directory SDK for C</olink></para></listitem>
<listitem><para><olink targetptr="bdahr">Freeing the Components of an LDAP
URL With Directory SDK for C</olink></para></listitem>
<listitem><para><olink targetptr="bdahs">Processing an LDAP URL With Directory
SDK for C</olink></para></listitem>
</itemizedlist>
</highlights><?Pub Caret1>
<sect1 id="bdahp"><title>Checking an LDAP URL With &DirectorySDKForC;</title>
<para>To determine whether a URL is an LDAP URL, call the <function>ldap_is_ldap_url
</function> 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 <literal>0</literal>.
The following example determines if a URL is an LDAP URL.</para>
<example id="ldap-url-is-ldap-url"><title>Determining Whether a URL Is an
LDAP URL</title>
<programlisting>#include &lt;stdio.h>
#include "ldap.h"
...
char *my_url = "ldap://ldap.example.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 );
}
...</programlisting>
</example>
<para><function>ldap_is_ldap_url</function> determines whether a URL is an
LDAP URL. To verify that an LDAP URL complies with the LDAP URL syntax, you
should call the <function>ldap_url_parse</function> function as detailed in <olink targetptr="bdahq">Getting the Components of an LDAP URL With Directory SDK
for C</olink>.</para></sect1>
<sect1 id="bdahq"><title>Getting the Components of an LDAP URL With &DirectorySDKForC;</title>
<para>To retrieve the individual components of an LDAP URL, call <function>ldap_url_parse
</function>. This function returns the LDAP URL components in an <structname>LDAPURLDesc
</structname> structure as shown in this example.</para>
<example id="ldap-url-ldapurldesc"><title><structname>LDAPURLDesc</structname> Structure
</title>
<programlisting>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;</programlisting>
</example>
<para>The following table describes the structure's fields.</para>
<table frame="topbot" pgwide="1" id="ldap-url-ldapurldesc-fields"><title><structname>
LDAPURLDesc</structname> Field Descriptions</title>
<tgroup cols="2"><colspec colnum="1" colwidth="11.10*"><colspec colnum="2"
colwidth="88.90*">
<thead>
<row>
<entry>
<para>Field Name</para></entry>
<entry>
<para>Description</para></entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para><structfield>lud_host</structfield></para></entry>
<entry>
<para>The name of the host in the URL.</para></entry>
</row>
<row>
<entry>
<para><structfield>lud_port</structfield></para></entry>
<entry>
<para>The number of the port in the URL.</para></entry>
</row>
<row>
<entry>
<para><structfield>lud_dn</structfield></para></entry>
<entry>
<para>The distinguished name in the URL.</para></entry>
</row>
<row>
<entry>
<para><structfield>lud_attrs</structfield></para></entry>
<entry>
<para>A pointer to a <literal>NULL</literal> terminated array of the attributes
specified in the URL.</para></entry>
</row>
<row>
<entry>
<para><structfield>lud_scope</structfield></para></entry>
<entry>
<itemizedlist>
<para>The scope of the search specified in the URL. This field can have the
following values:</para>
<listitem><para><literal>LDAP_SCOPE_BASE</literal> specifies a search of the
base entry.</para></listitem>
<listitem><para><literal>LDAP_SCOPE_ONELEVEL</literal> specifies a search
of all entries one level under the base entry, not including the base entry.</para>
</listitem>
<listitem><para><literal>LDAP_SCOPE_SUBTREE</literal> specifies a search of
all entries at all levels under the base entry, including the base entry.</para>
</listitem>
</itemizedlist>
</entry>
</row>
<row>
<entry>
<para><structfield>lud_filter</structfield></para></entry>
<entry>
<para>Search filter included in the URL.</para></entry>
</row>
<row>
<entry>
<para><structfield>lud_options</structfield></para></entry>
<entry>
<para>Options. If <literal>LDAP_URL_OPT_SECURE</literal>, indicates that the
protocol is <literal>ldaps://</literal> instead of <literal>ldap://</literal>.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>The following example parses an LDAP URL.</para>
<example id="ldap-url-parse-example"><title>Parsing an LDAP URL</title>
<programlisting>#include &lt;stdio.h>
#include "ldap.h"
...
char *my_url =
  "ldap://ldap.example.com:1389/dc=example,dc=com?
   cn,mail,telephoneNumber?sub?(sn=Jensen)";
LDAPURLDesc *ludpp;
int res, i;
...
if ( ( res = ldap_url_parse( my_url, &amp;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 );
...</programlisting>
</example>
<para>The code in <olink targetptr="ldap-url-parse-example">Example 13&ndash;3</olink> prints
each component of the URL as shown in the following example.</para>
<example id="ldap-url-parse-example-output"><title>Results of Parsing an LDAP
URL</title>
<screen>Components of the URL:
Host name: ldap.example.com
Port number: 1389
Base entry: dc=example,dc=com
Attributes returned:
  cn
  mail
  telephoneNumber
Scope of the search: sub
Filter: (sn=Jensen)</screen>
</example>
</sect1>
<sect1 id="bdahr"><title>Freeing the Components of an LDAP URL With &DirectorySDKForC;</title>
<para>When you have finished working with the components of an LDAP URL, you
should free the <structname>LDAPURLDesc</structname> structure from memory
by calling the <function>ldap_free_urldesc</function> function. The following
example parses an LDAP URL. The example then frees the <structname>LDAPURLDesc</structname> structure
from memory, after verifying that the LDAP URL is valid.</para>
<example id="ldap-url-free-example"><title>Freeing the <structname>LDAPURLDesc</structname> Structure
From Memory</title>
<programlisting>#include &lt;stdio.h>
#include "ldap.h"
...
char *my_url = "ldap://ldap.example.com:1389/dc=example,dc=com?cn,mail,
                telephoneNumber?sub?(sn=Jensen)";
LDAPURLDesc *ludpp;
int res, i;
...
if ( ( res = ldap_url_parse( my_url, &amp;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 );
...</programlisting>
</example>
</sect1>
<sect1 id="bdahs"><title>Processing an LDAP URL With &DirectorySDKForC;</title>
<para>To process an LDAP URL search request, call one of the following functions:
</para>
<itemizedlist>
<listitem><para><function>ldap_url_search_s</function> 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 other work.
The function returns <errorcode>LDAP_SUCCESS</errorcode> if the operation
completed successfully. If an error occurred, the function returns an error
code.</para></listitem>
<listitem><para><function>ldap_url_search_st</function> is a synchronous function
that allows a certain amount of time for the completion of the search operation.
Call this function to wait for the operation to complete, and to set a timeout
period for the operation.</para></listitem>
<listitem><para><function>ldap_url_search</function> 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 function returns a message
ID identifying the search operation. To determine whether the operation is
completed or still in progress, call the <function>ldap_result</function> function.
</para><para>After the operation is completed, call the <function>ldap_result2error
</function> function to determine if the operation was successful. If the
operation completed successfully, the <function>ldap_result2error</function> function
returns <errorcode>LDAP_SUCCESS</errorcode>. If an error occurred, the function
returns an error code. </para></listitem>
</itemizedlist>
<para>The following example processes a search request from an LDAP URL.</para>
<example id="ldap-url-search-example"><title>Processing an LDAP URL Search
Request</title>
<programlisting>#include &lt;stdio.h>
#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, &amp;result ) != LDAP_SUCCESS ) {
  ldap_perror( ld, "ldap_url_search_s" );
  return( 1 );
}</programlisting>
</example>
</sect1>
</chapter>
