3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright (c) 1990 Regents of the University of Michigan.
17 #include <ac/stdlib.h>
19 #include <ac/socket.h>
20 #include <ac/string.h>
27 * ldap_search_ext - initiate an ldap search operation.
32 * base DN of the base object
33 * scope the search scope - one of LDAP_SCOPE_BASE,
34 * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
35 * filter a string containing the search filter
36 * (e.g., "(|(cn=bob)(sn=bob))")
37 * attrs list of attribute types to return for matches
38 * attrsonly 1 => attributes only 0 => attributes and values
41 * char *attrs[] = { "mail", "title", 0 };
42 * ldap_search_ext( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
43 * attrs, attrsonly, sctrls, ctrls, timeout, sizelimit,
49 LDAP_CONST char *base,
51 LDAP_CONST char *filter,
56 struct timeval *timeout,
66 LDAP_LOG ( OPERATION, ENTRY, "ldap_search_ext\n", 0, 0, 0 );
68 Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );
72 assert( LDAP_VALID( ld ) );
74 /* check client controls */
75 rc = ldap_int_client_controls( ld, cctrls );
76 if( rc != LDAP_SUCCESS ) return rc;
79 * if timeout is provided, both tv_sec and tv_usec must
82 if( timeout != NULL ) {
83 if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
84 return LDAP_PARAM_ERROR;
87 /* timelimit must be non-zero if timeout is provided */
88 timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;
91 /* no timeout, no timelimit */
95 ber = ldap_build_search_req( ld, base, scope, filter, attrs,
96 attrsonly, sctrls, cctrls, timelimit, sizelimit, &id );
103 /* send the message */
104 *msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id );
115 LDAP_CONST char *base,
117 LDAP_CONST char *filter,
120 LDAPControl **sctrls,
121 LDAPControl **cctrls,
122 struct timeval *timeout,
129 rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
130 sctrls, cctrls, timeout, sizelimit, &msgid );
132 if ( rc != LDAP_SUCCESS ) {
136 rc = ldap_result( ld, msgid, 1, timeout, res );
139 /* error(-1) or timeout(0) */
140 return( ld->ld_errno );
143 if( rc == LDAP_RES_SEARCH_REFERENCE || rc == LDAP_RES_EXTENDED_PARTIAL ) {
144 return( ld->ld_errno );
147 return( ldap_result2error( ld, *res, 0 ) );
151 * ldap_search - initiate an ldap search operation.
156 * base DN of the base object
157 * scope the search scope - one of LDAP_SCOPE_BASE,
158 * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
159 * filter a string containing the search filter
160 * (e.g., "(|(cn=bob)(sn=bob))")
161 * attrs list of attribute types to return for matches
162 * attrsonly 1 => attributes only 0 => attributes and values
165 * char *attrs[] = { "mail", "title", 0 };
166 * msgid = ldap_search( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
167 * attrs, attrsonly );
171 LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter,
172 char **attrs, int attrsonly )
178 LDAP_LOG ( OPERATION, ENTRY, "ldap_search\n", 0, 0, 0 );
180 Debug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 );
183 assert( ld != NULL );
184 assert( LDAP_VALID( ld ) );
186 ber = ldap_build_search_req( ld, base, scope, filter, attrs,
187 attrsonly, NULL, NULL, -1, -1, &id );
194 /* send the message */
195 return ( ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id ));
200 ldap_build_search_req(
202 LDAP_CONST char *base,
204 LDAP_CONST char *filter,
207 LDAPControl **sctrls,
208 LDAPControl **cctrls,
217 * Create the search request. It looks like this:
218 * SearchRequest := [APPLICATION 3] SEQUENCE {
219 * baseObject DistinguishedName,
225 * derefAliases ENUMERATED {
226 * neverDerefaliases (0),
227 * derefInSearching (1),
228 * derefFindingBaseObj (2),
229 * alwaysDerefAliases (3)
231 * sizelimit INTEGER (0 .. 65535),
232 * timelimit INTEGER (0 .. 65535),
235 * attributes SEQUENCE OF AttributeType
237 * wrapped in an ldap message.
240 /* create a message to send */
241 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
245 if ( base == NULL ) {
246 /* no base provided, use session default base */
247 base = ld->ld_options.ldo_defbase;
249 if ( base == NULL ) {
250 /* no session default base, use top */
255 LDAP_NEXT_MSGID( ld, *idp );
256 #ifdef LDAP_CONNECTIONLESS
257 if ( LDAP_IS_UDP(ld) ) {
258 err = ber_write( ber, ld->ld_options.ldo_peer,
259 sizeof(struct sockaddr), 0);
261 if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
262 char *dn = ld->ld_options.ldo_cldapdn;
264 err = ber_printf( ber, "{ist{seeiib", *idp, dn,
265 LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
266 (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
267 (timelimit < 0) ? ld->ld_timelimit : timelimit,
272 err = ber_printf( ber, "{it{seeiib", *idp,
273 LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
274 (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
275 (timelimit < 0) ? ld->ld_timelimit : timelimit,
280 ld->ld_errno = LDAP_ENCODING_ERROR;
285 if( filter == NULL ) {
286 filter = "(objectclass=*)";
289 err = ldap_pvt_put_filter( ber, filter );
292 ld->ld_errno = LDAP_FILTER_ERROR;
297 if ( ber_printf( ber, /*{*/ "{v}N}", attrs ) == -1 ) {
298 ld->ld_errno = LDAP_ENCODING_ERROR;
303 /* Put Server Controls */
304 if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
309 if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
310 ld->ld_errno = LDAP_ENCODING_ERROR;
320 LDAP *ld, LDAP_CONST char *base, int scope,
321 LDAP_CONST char *filter, char **attrs,
322 int attrsonly, struct timeval *timeout, LDAPMessage **res )
326 if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
328 return( ld->ld_errno );
330 if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 )
331 return( ld->ld_errno );
333 if ( ld->ld_errno == LDAP_TIMEOUT ) {
334 (void) ldap_abandon( ld, msgid );
335 ld->ld_errno = LDAP_TIMEOUT;
336 return( ld->ld_errno );
339 return( ldap_result2error( ld, *res, 0 ) );
345 LDAP_CONST char *base,
347 LDAP_CONST char *filter,
354 if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
356 return( ld->ld_errno );
358 if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, res ) == -1 )
359 return( ld->ld_errno );
361 return( ldap_result2error( ld, *res, 0 ) );