Sun logo      Previous      Contents      Index      Next     

Sun Java System LDAP SDK for C Programming Guide

Chapter 13
Working with LDAP Controls

This chapter explains how Lightweight Directory Access Protocol (LDAP) controls work and how to use those controls that are supported by Sun™ Java System LDAP SDK for C. It includes the following sections:


How LDAP Controls Work

The LDAPv3, as documented in RFC 2251 - Lightweight Directory Access Protocol (v3) (http://www.faqs.org/rfcs/rfc2251.html), allows clients and servers to use controls as a mechanism for extending an LDAP operation. A control is a way to specify additional information as part of a request and a response. For example, a client can send a control to a server as part of a search request to indicate that the server should sort the search results before sending the results back to the client.


Note

Servers can also send controls back to clients. For example, Sun Java System Directory Server can send a control back to a client during the authentication process if the client’s password has expired or is going to expire.


A control specifies the following information:

When your client includes a control in a request for an LDAP operation, the server may respond in one of the following ways:


Using Controls in the LDAP API

The LDAP SDK for C supports two types of controls:

In the SDK, a control is represented by an LDAPControl structure.

The fields in this structure represent the data in a control:

Code Example 13-1 is the LDAPControl structure definition. For more information on the LDAPControl structure, see Chapter 16, "Data Type Reference."

Code Example 13-1  Example of LDAPControl Structure

typedef struct ldapcontrol {

char *ldctl_oid;

struct berval ldctl_value;

char ldctl_iscritical;

} LDAPControl;

You can either allocate and create the control yourself, or you can call a function to create the control. For example, you can call the ldap_create_sort_control() function to create a server-sorting control. To include a control in a request, call one of the LDAPv3 API functions (functions with names ending with _ext and _ext_s). These functions allow you to pass in an array of server controls and an array of client controls.


Note

You can also include controls in a request by specifying the array of controls in the LDAP_OPT_SERVER_CONTROLS option. However, these controls will be sent to the server with every request. If the control is specific to a certain type of operation, you should use the _ext and _ext_s functions instead.


To retrieve any controls included in a server’s response, call the ldap_parse_result() function. You can then retrieve data from the returned controls yourself (by checking the fields of the LDAPControl structure) or by calling additional functions (such as ldap_parse_sort_control()).

When you are done working with a control or with an array of controls, you should free them from memory by calling the ldap_control_free() function or the ldap_controls_free() function.


Determining Supported Controls

According to the LDAPv3, servers should list any controls that they support in the supportedControl attribute in the root DSE.


Note

See Chapter 10, "Retrieving Server Information" for information on the DSE.


Table 13-1 lists some of the OIDs for server controls that might be referenced in the supportedControl attribute.

Table 13-1  LDAPv3 Server Controls 

OID of Control

Defined Name (in ldap.h)

Description of Control

2.16.840.1.113730.3.4.2

LDAP_CONTROL_MANAGEDSAIT

"Using the Manage DSA IT Control"

2.16.840.1.113730.3.4.3

LDAP_CONTROL_PERSISTENTSEARCH

"Using the Persistent Search Control"

2.16.840.1.113730.3.4.4

LDAP_CONTROL_PWEXPIRED

"Using Password Policy Controls".

2.16.840.1.113730.3.4.5

LDAP_CONTROL_PWEXPIRING

"Using Password Policy Controls"

2.16.840.1.113730.3.4.9

LDAP_CONTROL_VLVREQUEST

"Using the Virtual List View Control"

1.2.840.113556.1.4.473

LDAP_CONTROL_SORTREQUEST

"Using the Server-Side Sorting Control"

2.16.840.1.113730.3.4.12

LDAP_CONTROL_PROXYAUTH

"Using the Proxied Authorization Control"

Code Example 13-2 is a simple command-line program that searches for the root DSE and prints the values of the supportedControl attribute.

Code Example 13-2  Sample Program to Search for Supported Controls 

#include "ldap.h"

static char *usage = "Usage: listctrl -h <hostname> -p <portnumber>\n";

/* Associate OIDs of known controls with descriptions. */

struct oid2desc {

char *oid;

char *desc;

};

static struct oid2desc oidmap[] = {

{LDAP_CONTROL_MANAGEDSAIT, "Manage DSA IT control"},

{LDAP_CONTROL_SORTREQUEST, "Server-side sorting control"},

{LDAP_CONTROL_PERSISTENTSEARCH, "Persistent search control"},

{LDAP_CONTROL_VLVREQUEST, "Virtual list view control"},

{LDAP_CONTROL_PWEXPIRED, "Password expired control"},

{LDAP_CONTROL_PWEXPIRING, "Password expiration warning control"},

{ NULL, NULL }

};

int

main( int argc, char **argv )

{

LDAP *ld;

LDAPMessage *result, *e;

char *hostname = NULL;

char **vals;

char *attrs[2];

int i, j, c, portnumber = LDAP_PORT, rc;

LDAPControl **serverctrls = NULL, **clntctrls = NULL;

/* Parse the command line arguments. */

while ( ( c = getopt( argc, argv, "h:p:" ) ) != -1 ) {

switch ( c ) {

case 'h':

hostname = strdup( optarg );

break;

case 'p':

portnumber = atoi( optarg );

break;

default:

printf( "Unsupported option: %c\n", c );

printf( usage );

exit( 1 );

}

}

/* By default, connect to localhost at port 389. */

if ( hostname == NULL || hostname[0] == NULL ) {

hostname = "localhost";

}

/* Initialize the connection. */

if ( (ld = ldap_init( hostname, portnumber )) == 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 retrieve only the

supportedControl attribute. */

attrs[ 0 ] = "supportedControl";

attrs[ 1 ] = NULL;

rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",

attrs, 0, serverctrls, clntctrls, NULL, NULL, &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:

printf( "LDAP server %s:%d returned result code %d (%s).\n"

"This server does not support the LDAPv3 protocol.\n",

hostname, portnumber, rc, ldap_err2string( rc ) );

return( 1 );

break;

/* If any other value is returned, an error must have occurred. */

default:

ldap_perror( ld, "ldap_search_ext_s" );

return( 1 );

break;

}

/* Get the root DSE from the results.

Since there is only one root DSE, there

should be only one entry in the results. */

e = ldap_first_entry( ld, result );

/* Get and print the values of the supportedControl attribute. */

if (e != NULL &&

(vals = ldap_get_values(ld, e, "supportedControl")) != NULL ) {

printf( "\nControls Supported by %s:%d\n", hostname, portnumber );

printf( "==================================================\n" );

for ( i = 0; vals[i] != NULL; i++ ) {

printf( "%s\n", vals[i] );

for ( j = 0; oidmap[j].oid != NULL; j++ ) {

if ( !strcmp( vals[i], oidmap[j].oid )) {

printf( "\t%s\n", oidmap[j].desc );

}

}

}

/* Free the values allocated by ldap_get_values(). */

ldap_value_free( vals );

printf( "\n" );

}

/* Free memory allocated by ldap_search_ext_s(). */

ldap_msgfree( result );

ldap_unbind( ld );

return( 0 );

}


Using the Server-Side Sorting Control

The control with the OID 1.2.840.113556.1.4.473 (or LDAP_CONTROL_SORTREQUEST, as defined in the ldap.h header file) is a server-side sorting control. When you send a search request with this control to the server, the server should sort the results before sending them back to you.


Note

The server-side sorting control is described in the Internet-Drafts file, RFC 2891 - LDAP Control Extension for Server Side Sorting of Search Results located at http://www.faqs.org/rfcs/rfc2891.html


Specifying the Sort Order

To specify the sort order of the results, call the ldap_create_sort_keylist() function to create a sort key list from a string in the following format:

[-]attrname[:matching_rule_oid] ...

Where:

Creating the Control

Next, to create the server-side sorting control, you pass the sort key list (the array of LDAPsortkey structures) to the ldap_create_sort_control() function. The function passes back a newly created sort control, an LDAPControl structure, which you can include in a search request.


Note

You can specify whether or not the control is critical to the search operation. If the control is marked as critical and the server cannot sort the results, the server should not send back any entries. See "Interpreting the Results" for more information on the ramifications of marking the control as critical.


After you call the ldap_create_sort_control() function and create the control, you should free the array of LDAPsortkey structures by calling ldap_free_sort_keylist(). When you are done receiving sorted results from the server, you should free the LDAPControl structure by calling ldap_control_free().

Performing the Search

To specify that you want the server to sort the results, add the newly created server-sorting control to a NULL-terminated array of LDAPControl structures and pass this array to the ldap_search_ext() function or the ldap_search_ext_s() function. The server returns a result for the search operation and a response control. The response control indicates the success or failure of the sorting. To determine if sorting was successful:

  1. Call ldap_parse_result() to parse the result of the search operation and retrieve any response controls sent back from the server.
  2. Response controls are passed back in a NULL-terminated array of LDAPControl structures.

  3. Pass this array of structures as an argument to ldap_parse_sort_control() to retrieve the LDAP result code for the sorting operation.
  4. If the sorting operation fails, the server may also return the name of the attribute that caused the failure. The ldap_parse_sort_control() function also retrieves this name, if available.

  5. Free the array by calling the ldap_controls_free() function when you are done parsing the array of response controls.

The server can return the result codes detailed in Table 13-2.

Table 13-2  Server-side Sorting Result Codes 

Result Code

Description

LDAP_SUCCESS

The results were sorted successfully.

LDAP_OPERATIONS_ERROR

An internal server error occurred.

LDAP_TIMELIMIT_EXCEEDED

The maximum time allowed for a search was exceeded before the server finished sorting the results.

LDAP_STRONG_AUTH_REQUIRED

The server refused to send back the sorted search results because it requires you to use a stronger authentication method.

LDAP_ADMINLIMIT_EXCEEDED

There are too many entries for the server to sort.

LDAP_NO_SUCH_ATTRIBUTE

The sort key list specifies an attribute that does not exist.

LDAP_INAPPROPRIATE_MATCHING

The sort key list specifies a matching rule that is not recognized or appropriate.

LDAP_INSUFFICIENT_ACCESS

The server did not send the sorted results because the client has insufficient access rights.

LDAP_BUSY

The server is too busy to sort the results.

LDAP_UNWILLING_TO_PERFORM

The server is unable to sort the results.

LDAP_OTHER

This general result code indicates that the server failed to sort the results for a reason other than the ones listed above.

Interpreting the Results

Table 13-3 lists the kinds of results to expect from the LDAP server under different situations.

Table 13-3  Server Responses to Sorting Controls 

Does the Server Support the Sort Control?

Is the Sort Control Marked As Critical?

Other Conditions

Results from LDAP Server

No

Yes

N/A

The server does not send back any entries.

No

The server ignores the sorting control and returns the entries unsorted.

Yes

Yes

The server cannot sort the results using the specified sort key list.

The server does not send back any entries. It sends back the sorting response control, which specifies the result code of the sort attempt and (optionally) the attribute type that caused the error.

No

The server returns the entries unsorted. It sends back the sorting response control, which specifies the result code of the sort attempt and (optionally) the attribute type that caused the error.

N/A (may or may not be marked as critical)

The server successfully sorted the entries.

The server sends back the sorted entries. It sends back the sorting response control, which specifies the result code of the sort attempt (LDAP_SUCCESS).

The search itself failed (for any reason).

The server sends back a result code for the search operation. It does not send back the sorting response control.

Server-Sorting Control Sample Program

Code Example 13-3 uses the server-sorting control to get a list of all users in the directory, sorted in ascending order by last name, then in descending order by first name.

Code Example 13-3  Sample Program to Apply Server-sorting Control 

#include <stdio.h>

#include "ldap.h"

/* Change these as needed. */

#define HOSTNAME "localhost"

#define PORTNUMBER 3890

int

main( int argc, char **argv )

{

LDAP *ld;

LDAPMessage *result, *e;

char *attrfail, *matched = NULL, *errmsg = NULL;

char **vals, **referrals;

int rc, parse_rc, version;

unsigned long rcode;

LDAPControl *sortctrl = NULL;

LDAPControl *requestctrls[ 2 ];

LDAPControl **resultctrls = NULL;

LDAPsortkey **sortkeylist;

/* Get a handle to an LDAP connection */

if ( (ld = ldap_init( HOSTNAME, PORTNUMBER ) ) == NULL ) {

perror( "ldap_init" );

return( 1 );

}

version = LDAP_VERSION3;

ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );

/* Create a sort key list that specifies the sort order of the results.

Sort the results by last name first, then by first name. */

ldap_create_sort_keylist( &sortkeylist, "sn -givenname" );

/* Create the sort control. */

rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl );

if ( rc != LDAP_SUCCESS ) {

fprintf( stderr, "ldap_create_sort_control: %s\n", ldap_err2string( rc ) );

ldap_unbind( ld );

return( 1 );

}

requestctrls[ 0 ] = sortctrl;

requestctrls[ 1 ] = NULL;

/* Search for all entries in Sunnyvale */

rc = ldap_search_ext_s( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE,

"(mail=*example.com*)", NULL, 0, requestctrls, NULL, NULL, 0, &result );

if ( rc != LDAP_SUCCESS ) {

fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );

ldap_unbind( ld );

return( 1 );

}

parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg, &referrals, &resultctrls, 0 );

if ( parse_rc != LDAP_SUCCESS ) {

fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( parse_rc ) );

ldap_unbind( ld );

return( 1 );

}

if ( rc != LDAP_SUCCESS ) {

fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );

if ( errmsg != NULL && *errmsg != '\0' ) {

fprintf( stderr, "%s\n", errmsg );

}

ldap_unbind( ld );

return( 1 );

}

parse_rc = ldap_parse_sort_control( ld, resultctrls, &rcode, &attrfail );

if ( parse_rc != LDAP_SUCCESS ) {

fprintf( stderr, "ldap_parse_sort_control: %s\n", ldap_err2string( parse_rc ) );

ldap_unbind( ld );

return( 1 );

}

if ( rcode != LDAP_SUCCESS ) {

fprintf( stderr, "Sort error: %s\n", ldap_err2string( rcode ) );

if ( attrfail != NULL && *attrfail != '\0' ) {

fprintf( stderr, "Bad attribute: %s\n", attrfail );

}

ldap_unbind( ld );

return( 1 );

}

/* for each entry print out name + all attrs and values */

for ( e = ldap_first_entry( ld, result ); e != NULL;

e = ldap_next_entry( ld, e ) ) {

if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) {

if ( vals[0] != NULL ) {

printf( "%s", vals[0] );

}

ldap_value_free( vals );

}

if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) {

if ( vals[0] != NULL ) {

printf( "\t%s", vals[0] );

}

ldap_value_free( vals );

}

printf( "\n" );

}

ldap_msgfree( result );

ldap_free_sort_keylist( sortkeylist );

ldap_control_free( sortctrl );

ldap_controls_free( resultctrls );

ldap_unbind( ld );

return( 0 );

}


Using the Persistent Search Control

The control with the OID 2.16.840.1.113730.3.4.3 (or LDAP_CONTROL_PERSISTENTSEARCH as defined in the ldap.h header file) is the persistent search control. A persistent search is an ongoing search operation that allows your LDAP client to get notification of changes to the directory.


Note

The persistent search control is described in the Internet-Drafts file, Persistent Search: A Simple LDAP Change Notification Mechanism located at http://www.ietf.org/proceedings/01mar/I-D/ldapext-psearch-03.txt.


To use persistent searching for change notification, you create a persistent search control that specifies the types of changes that you want to track. You include the control in a search request. If an entry in the directory is changed, the server determines if the entry matches the search criteria in your request and if the change is the type of change that you are tracking. If both of these are true, the server sends the entry to your client.

To create a persistent search control, call ldap_create_persistentsearch_control() as illustrated in Code Example 13-4.

Code Example 13-4  Calling ldap_create_persistentsearch_control()

int ldap_create_persistentsearch_control( LDAP *ld,

int changetypes, int changesonly, int return_echg_ctls,

char ctl_iscritical, LDAPControl **ctrlp );

You can specify the following information:

The function passes back an LDAPControl structure representing the control in the ctrlp parameter. You can add the newly created control to a NULL-terminated array of LDAPControl structures and pass this array to the ldap_search_ext() function.

To end the persistent search, you can either call the ldap_abandon_ext() function to abandon the search operation, or you can call the ldap_unbind() function to disconnect from the server.


Note

For an example detailing how to perform a persistent search, refer to the example provided with the LDAP SDK for C in DSRK_base/lib/ldapcsdk/examples called psearch.c.



Using the Entry Change Notification Control

The control with the OID 2.16.840.1.113730.3.4.7 (or LDAP_CONTROL_ENTRYCHANGE, as defined in the ldap.h header file) is the "entry change notification" control. This control contains additional information about the change made to the entry, including the type of change made, the change number (which corresponds to an item in the server’s change log, if the server supports a change log), and, if the entry was renamed, the old DN of the entry.

You use this control in conjunction with a persistent search control. If you have specified the preference for returning entry change notification controls, the server includes an entry change notification control with each entry found by the search. To retrieve and parse an entry change notification control included with an entry:

  1. Pass the LDAPMessage structure that represents an entry to the ldap_get_entry_controls() function.
  2. Pass the entry change notification control to the ldap_parse_entrychange_control() function.

For more information, see "Using the Persistent Search Control".


Using the Virtual List View Control

The control with the OID 2.16.840.1.113730.3.4.9 (or LDAP_CONTROL_VLVREQUEST, as defined in the ldap.h header file) is a virtual list view control. When you send a search request with this control and a server-side sorting control to the server, the server should sort the results and return the specified subset of entries back to your client.


Note

The virtual list view control is described in the Internet-Drafts file, LDAP Extensions for Scrolling View Browsing of Search Results located at http://www.ietf.org/proceedings/01mar/I-D/ldapext-ldapv3-vlv-04.txt.



Using the Manage DSA IT Control

The control with the OID 2.16.840.1.113730.3.4.2 (or LDAP_CONTROL_MANAGEDSAIT, as defined in the ldap.h header file) is the manage DSA IT control. You can use this control to manage search references in the directory. To create this control, create an LDAPControl structure and set the ldctl_oid field to 2.16.840.1.113730.3.4.2.

When you add this control to the array of LDAPControl structures that you pass to a function (for example, ldap_search_ext() or ldap_modify_ext(), the server treats search references as ordinary entries. Rather than returning a reference to you, the server returns the entry containing the reference. This allows your client application to manage search references in the directory.


Note

The manage DSA IT control is described in the Internet-Drafts file, RFC 2891 - LDAP Control Extension for Server Side Sorting of Search Results located at http://www.faqs.org/rfcs/rfc2891.html



Using Password Policy Controls

Sun Java System Directory Server uses two server response controls to send information back to a client after an LDAP bind operation:

  1. The control with the OID 2.16.840.1.113730.3.4.4 (or LDAP_CONTROL_PWEXPIRED, as defined in the ldap.h header file) is the expired password control. It is used if the server is configured to require users to change their passwords when first logging in and whenever their password has been reset. If the user is logging in for the first time or their password has been reset, the server sends this control to indicate that the client needs to change the password immediately. At this point, the only operation that the client can perform is to change the user’s password. If the client requests any other operation, the server sends back an LDAP_UNWILLING_TO_PERFORM result code with an expired password control.
  2. The control with the OID 2.16.840.1.113730.3.4.5 (or LDAP_CONTROL_PWEXPIRING, as defined in the ldap.h header file) is the password expiration warning control. This control is used if the server is configured to expire user passwords after a certain amount of time. The server sends this control back to the client if the client binds using a password that will soon expire. The ldctl_value field of the LDAPControl structure specifies the number of seconds before the password will expire.

To get these server response controls when binding, you can:

You can then check the ldctl_oid field to determine the OID of the control and the ldctl_value field for any data included in the control.


Using the Proxied Authorization Control

Proxied authorization is an extension to the LDAPv3 that allows a bound client to assume the identity of another directory entity without rebinding. This allows the client to perform operations as if it were bound as the proxied directory entity. All directory access (read, write, search, compare, delete, and add) is supported by proxied authorization. For example, suppose a client is bound as uid=bjensen,ou=Engineering,dc=example,dc=com. bjensen does not have the right to search the ou=Marketing,dc=example,dc=com tree. However, uid=lboyd,ou=Marketing,dc=example,dc=com does have rights to search the Marketing tree and, lboyd grants proxy rights to bjensen. In this case, bjensen may bind as herself, assume the identity of lboyd, and then search the Marketing tree.

This feature is intended as a performance and administrative benefit for certain types of directory usage. Specifically, applications that want to allow many clients to access or modify specific directory data without rebinding as another directory entity may want to use this feature.


Caution

Be aware that other directory servers might not support this feature. Sun Java System Directory Server access control (including the proxy right) is fully described in the Sun ONE Directory Server Administration Guide located at http://docs.sun.com/doc/816-6698-10.


The Proxy Right

Proxied authorization adds an additional access right: proxy. If an entry grants the proxy right, then the entity to which that right is granted may assume the identity of the granting entity. For example, if you wanted to allow uid=bjensen the right to proxy as uid=lboyd, add the Proxy Right access control instruction (ACI) illustrated in Code Example 13-5 to your directory. This ACI allows bjensen to assume the identity of lboyd for all directory operations giving bjensen the permission to do to the directory whatever lboyd has permission to do.

Code Example 13-5  Proxy Right ACI

aci: (target = "ldap:///uid=lboyd,ou=Marketing,dc=example,dc=com")

(targetattr=*)

(version 3.0; aci "grant bjensen the right to proxy as lboyd";

allow(proxy) userdn="ldap:///uid=bjensen,ou=Engineering,dc=example,dc=com";)

The Proxied Authorization Control

To support proxied authorization (an extension to the LDAPv3), the proxy authorization control has been added to the LDAP SDK for C in the form of the ldap_create_proxyauth_control() function. You use this function to create the control that allows a bound entity to assume the identity of another directory entry.

Proxy authorization is an optional LDAP server feature; it may not be supported on all LDAP servers. You should call the proxy authorization control function only when interacting with LDAP servers that support this LDAPv3 extension. You can check on the support of this control by looking at the rootDSE supportedControl attrubute. For example, the following command uses the ldapsearch utility to display the rootDSE:

ldapsearch -v -h hostname -p 389 -b ““ -s base ““

In order for the control to work, the LDAP server that you are connecting to must support the server control for proxied authorization (OID 2.16.840.1.113730.3.4.12, or LDAP_CONTROL_PROXYAUTH as defined in the ldap.h header file).

Proxy Authorization Sample Program

Code Example 13-6 creates an LDAP connection, sets the proxied authorization control, binds to the directory, and then performs a search operation using the proxied authorization control. A more complete example is also available with the SDK example files located in DSRK_base/lib/ldapcsdk/examples.

Code Example 13-6  Proxied Authorization Control Example 

#include <ldap.h>

int version;

LDAP *ld;

LDAPControl *requestctrls[ 2 ];

LDAPControl *pactrl = NULL;

/* Customize the following host and bind information for your site. */

int port=389;

char *host="directory.example.com";

char *baseDN="dc=example,dc=com";

/* Proxied auth specific information.

proxyDN is the entity that will be proxied.

bindDN and bindpw is for the bind entity that will use the proxyDN. */

char *proxyDN = "uid=lboyd,ou=marketing,dc=example,dc=com";

char *bindDN = "uid=bjensen,ou=engineering,dc=example,dc=com";

char *bindpw = "password";

/* Do general LDAP init stuff */

/* Get a handle to an LDAP connection */

if ( (ld = ldap_init( host, port ) ) == NULL ) {

printf("ldap_init did not return a conn handle.\n");

return;

}

/* set version to ldap version 3 */

version = LDAP_VERSION3;

ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );

/* authenticate to the directory */

if ( ldap_simple_bind_s( ld, bindDN, bindpw ) != LDAP_SUCCESS ) {

printf("ldap_simple_bind_s failed");

return (-1);

}

/* create the proxied authorization control */

if ( ldap_create_proxyauth_control( ld, proxyDN, 1, &pactrl ) ) {

printf("ldap_create_proxyauth_control failed.\n");

if ( ldap_unbind( ld ) != LDAP_SUCCESS ) {

printf("ldap_unbind failed\n");

}

return(-1);

}

requestctrls[ 0 ] = pactrl;

requestctrls[ 1 ] = NULL;

/* Perform the search using the control */

printf("Searching for %s with the proxy auth control.\n", proxyDN);

if ( ldap_search_ext_s( ld, proxyDN, LDAP_SCOPE_SUBTREE, "(objectclass=*)",

NULL, 0, requestctrls, NULL, NULL, LDAP_NO_LIMIT, &results ) !=

LDAP_SUCCESS ) {

printf("ldap_search_ext failed.\n");

printf("Something is wrong with proxied auth.\n");

} else {

print_search_results(ld, results);

}



Previous      Contents      Index      Next     


Copyright 2004 Sun Microsystems, Inc. All rights reserved.