3 * Copyright 1998-2002 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,
65 LDAP_LOG (( "search", LDAP_LEVEL_ENTRY, "ldap_search_ext\n" ));
67 Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );
71 assert( LDAP_VALID( ld ) );
73 /* check client controls */
74 rc = ldap_int_client_controls( ld, cctrls );
75 if( rc != LDAP_SUCCESS ) return rc;
78 * if timeout is provided, both tv_sec and tv_usec must
81 if( timeout != NULL ) {
82 if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
83 return LDAP_PARAM_ERROR;
86 /* timelimit must be non-zero if timeout is provided */
87 timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;
90 /* no timeout, no timelimit */
94 ber = ldap_build_search_req( ld, base, scope, filter, attrs,
95 attrsonly, sctrls, cctrls, timelimit, sizelimit );
102 if ( ld->ld_cache != NULL ) {
103 if ( ldap_check_cache( ld, LDAP_REQ_SEARCH, ber ) == 0 ) {
105 ld->ld_errno = LDAP_SUCCESS;
106 *msgidp = ld->ld_msgid;
109 ldap_add_request_to_cache( ld, LDAP_REQ_SEARCH, ber );
111 #endif /* LDAP_NOCACHE */
113 /* send the message */
114 *msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber );
125 LDAP_CONST char *base,
127 LDAP_CONST char *filter,
130 LDAPControl **sctrls,
131 LDAPControl **cctrls,
132 struct timeval *timeout,
139 rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
140 sctrls, cctrls, timeout, sizelimit, &msgid );
142 if ( rc != LDAP_SUCCESS ) {
146 rc = ldap_result( ld, msgid, 1, timeout, res );
149 /* error(-1) or timeout(0) */
150 return( ld->ld_errno );
153 if( rc == LDAP_RES_SEARCH_REFERENCE || rc == LDAP_RES_EXTENDED_PARTIAL ) {
154 return( ld->ld_errno );
157 return( ldap_result2error( ld, *res, 0 ) );
161 * ldap_search - initiate an ldap search operation.
166 * base DN of the base object
167 * scope the search scope - one of LDAP_SCOPE_BASE,
168 * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
169 * filter a string containing the search filter
170 * (e.g., "(|(cn=bob)(sn=bob))")
171 * attrs list of attribute types to return for matches
172 * attrsonly 1 => attributes only 0 => attributes and values
175 * char *attrs[] = { "mail", "title", 0 };
176 * msgid = ldap_search( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE, "cn~=bob",
177 * attrs, attrsonly );
181 LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter,
182 char **attrs, int attrsonly )
187 LDAP_LOG (( "search", LDAP_LEVEL_ENTRY, "ldap_search\n" ));
189 Debug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 );
192 assert( ld != NULL );
193 assert( LDAP_VALID( ld ) );
195 ber = ldap_build_search_req( ld, base, scope, filter, attrs,
196 attrsonly, NULL, NULL, -1, -1 );
203 if ( ld->ld_cache != NULL ) {
204 if ( ldap_check_cache( ld, LDAP_REQ_SEARCH, ber ) == 0 ) {
206 ld->ld_errno = LDAP_SUCCESS;
207 return( ld->ld_msgid );
209 ldap_add_request_to_cache( ld, LDAP_REQ_SEARCH, ber );
211 #endif /* LDAP_NOCACHE */
213 /* send the message */
214 return ( ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber ));
219 ldap_build_search_req(
221 LDAP_CONST char *base,
223 LDAP_CONST char *filter,
226 LDAPControl **sctrls,
227 LDAPControl **cctrls,
229 ber_int_t sizelimit )
235 * Create the search request. It looks like this:
236 * SearchRequest := [APPLICATION 3] SEQUENCE {
237 * baseObject DistinguishedName,
243 * derefAliases ENUMERATED {
244 * neverDerefaliases (0),
245 * derefInSearching (1),
246 * derefFindingBaseObj (2),
247 * alwaysDerefAliases (3)
249 * sizelimit INTEGER (0 .. 65535),
250 * timelimit INTEGER (0 .. 65535),
253 * attributes SEQUENCE OF AttributeType
255 * wrapped in an ldap message.
258 /* create a message to send */
259 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
263 if ( base == NULL ) {
264 /* no base provided, use session default base */
265 base = ld->ld_options.ldo_defbase;
267 if ( base == NULL ) {
268 /* no session default base, use top */
273 #ifdef LDAP_CONNECTIONLESS
274 if ( LDAP_IS_UDP(ld) ) {
275 err = ber_write( ber, ld->ld_options.ldo_peer,
276 sizeof(struct sockaddr), 0);
278 if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
279 char *dn = ld->ld_options.ldo_cldapdn;
281 err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid, dn,
282 LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
283 (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
284 (timelimit < 0) ? ld->ld_timelimit : timelimit,
289 err = ber_printf( ber, "{it{seeiib", ++ld->ld_msgid,
290 LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
291 (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
292 (timelimit < 0) ? ld->ld_timelimit : timelimit,
297 ld->ld_errno = LDAP_ENCODING_ERROR;
302 if( filter == NULL ) {
303 filter = "(objectclass=*)";
306 err = ldap_pvt_put_filter( ber, filter );
309 ld->ld_errno = LDAP_FILTER_ERROR;
314 if ( ber_printf( ber, /*{*/ "{v}N}", attrs ) == -1 ) {
315 ld->ld_errno = LDAP_ENCODING_ERROR;
320 /* Put Server Controls */
321 if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
326 if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
327 ld->ld_errno = LDAP_ENCODING_ERROR;
337 LDAP *ld, LDAP_CONST char *base, int scope,
338 LDAP_CONST char *filter, char **attrs,
339 int attrsonly, struct timeval *timeout, LDAPMessage **res )
343 if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
345 return( ld->ld_errno );
347 if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 )
348 return( ld->ld_errno );
350 if ( ld->ld_errno == LDAP_TIMEOUT ) {
351 (void) ldap_abandon( ld, msgid );
352 ld->ld_errno = LDAP_TIMEOUT;
353 return( ld->ld_errno );
356 return( ldap_result2error( ld, *res, 0 ) );
362 LDAP_CONST char *base,
364 LDAP_CONST char *filter,
371 if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
373 return( ld->ld_errno );
375 if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, res ) == -1 )
376 return( ld->ld_errno );
378 return( ldap_result2error( ld, *res, 0 ) );