1 /* $OpenLDAP: pkg/ldap/tests/progs/slapd-search.c,v 1.41.2.7 2008/02/11 23:26:50 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2008 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Kurt Spanier for inclusion
17 * in OpenLDAP Software.
24 #include "ac/stdlib.h"
28 #include "ac/socket.h"
29 #include "ac/string.h"
30 #include "ac/unistd.h"
37 #include "slapd-common.h"
43 do_search( char *uri
, char *manager
, struct berval
*passwd
,
44 char *sbase
, int scope
, char *filter
, LDAP
**ldp
,
45 char **attrs
, int noattrs
, int nobind
,
46 int innerloop
, int maxretries
, int delay
, int force
, int chaserefs
);
49 do_random( char *uri
, char *manager
, struct berval
*passwd
,
50 char *sbase
, int scope
, char *filter
, char *attr
,
51 char **attrs
, int noattrs
, int nobind
,
52 int innerloop
, int maxretries
, int delay
, int force
, int chaserefs
);
55 usage( char *name
, char o
)
58 fprintf( stderr
, "unknown/incorrect option \"%c\"\n", o
);
63 "-H <uri> | ([-h <host>] -p <port>) "
86 main( int argc
, char **argv
)
90 char *host
= "localhost";
93 struct berval passwd
= { 0, NULL
};
95 int scope
= LDAP_SCOPE_SUBTREE
;
98 char *srchattrs
[] = { "cn", "sn", NULL
};
99 char **attrs
= srchattrs
;
102 int retries
= RETRIES
;
109 tester_init( "slapd-search", TESTER_SEARCH
);
111 /* by default, tolerate referrals and no such object */
112 tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
114 while ( ( i
= getopt( argc
, argv
, "Aa:b:CD:f:FH:h:i:l:L:Np:r:s:t:T:w:" ) ) != EOF
)
125 case 'H': /* the server uri */
126 uri
= strdup( optarg
);
129 case 'h': /* the servers host */
130 host
= strdup( optarg
);
134 tester_ignore_str2errlist( optarg
);
141 case 'p': /* the servers port */
142 if ( lutil_atoi( &port
, optarg
) != 0 ) {
147 case 'D': /* the servers manager */
148 manager
= strdup( optarg
);
151 case 'w': /* the server managers password */
152 passwd
.bv_val
= strdup( optarg
);
153 passwd
.bv_len
= strlen( optarg
);
154 memset( optarg
, '*', passwd
.bv_len
);
158 attr
= strdup( optarg
);
161 case 'b': /* file with search base */
162 sbase
= strdup( optarg
);
165 case 'f': /* the search request */
166 filter
= strdup( optarg
);
173 case 'l': /* number of loops */
174 if ( lutil_atoi( &loops
, optarg
) != 0 ) {
179 case 'L': /* number of loops */
180 if ( lutil_atoi( &outerloops
, optarg
) != 0 ) {
185 case 'r': /* number of retries */
186 if ( lutil_atoi( &retries
, optarg
) != 0 ) {
191 case 't': /* delay in seconds */
192 if ( lutil_atoi( &delay
, optarg
) != 0 ) {
198 attrs
= ldap_str2charray( optarg
, "," );
199 if ( attrs
== NULL
) {
205 scope
= ldap_pvt_str2scope( optarg
);
217 if (( sbase
== NULL
) || ( filter
== NULL
) || ( port
== -1 && uri
== NULL
))
218 usage( argv
[0], '\0' );
220 if ( *filter
== '\0' ) {
222 fprintf( stderr
, "%s: invalid EMPTY search filter.\n",
224 exit( EXIT_FAILURE
);
228 if ( argv
[optind
] != NULL
) {
229 attrs
= &argv
[optind
];
232 uri
= tester_uri( uri
, host
, port
);
234 for ( i
= 0; i
< outerloops
; i
++ ) {
235 if ( attr
!= NULL
) {
236 do_random( uri
, manager
, &passwd
,
237 sbase
, scope
, filter
, attr
,
238 attrs
, noattrs
, nobind
,
239 loops
, retries
, delay
, force
, chaserefs
);
242 do_search( uri
, manager
, &passwd
,
243 sbase
, scope
, filter
, NULL
,
244 attrs
, noattrs
, nobind
,
245 loops
, retries
, delay
, force
, chaserefs
);
249 exit( EXIT_SUCCESS
);
254 do_random( char *uri
, char *manager
, struct berval
*passwd
,
255 char *sbase
, int scope
, char *filter
, char *attr
,
256 char **srchattrs
, int noattrs
, int nobind
,
257 int innerloop
, int maxretries
, int delay
, int force
, int chaserefs
)
260 int i
= 0, do_retry
= maxretries
;
262 int rc
= LDAP_SUCCESS
;
263 int version
= LDAP_VERSION3
;
265 char **values
= NULL
;
266 LDAPMessage
*res
= NULL
, *e
= NULL
;
271 ldap_initialize( &ld
, uri
);
273 tester_perror( "ldap_initialize", NULL
);
274 exit( EXIT_FAILURE
);
277 (void) ldap_set_option( ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
278 (void) ldap_set_option( ld
, LDAP_OPT_REFERRALS
,
279 chaserefs
? LDAP_OPT_ON
: LDAP_OPT_OFF
);
281 if ( do_retry
== maxretries
) {
282 fprintf( stderr
, "PID=%ld - Search(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n",
283 (long) pid
, innerloop
, sbase
, filter
, attr
);
287 rc
= ldap_sasl_bind_s( ld
, manager
, LDAP_SASL_SIMPLE
, passwd
, NULL
, NULL
, NULL
);
288 if ( rc
!= LDAP_SUCCESS
) {
289 tester_ldap_error( ld
, "ldap_sasl_bind_s", NULL
);
292 case LDAP_UNAVAILABLE
:
297 exit( EXIT_FAILURE
);
301 rc
= ldap_search_ext_s( ld
, sbase
, LDAP_SCOPE_SUBTREE
,
302 filter
, attrs
, 0, NULL
, NULL
, NULL
, LDAP_NO_LIMIT
, &res
);
304 case LDAP_SIZELIMIT_EXCEEDED
:
305 case LDAP_TIMELIMIT_EXCEEDED
:
307 if ( ldap_count_entries( ld
, res
) == 0 ) {
309 tester_ldap_error( ld
, "ldap_search_ext_s", NULL
);
314 for ( e
= ldap_first_entry( ld
, res
); e
!= NULL
; e
= ldap_next_entry( ld
, e
) )
316 struct berval
**v
= ldap_get_values_len( ld
, e
, attr
);
319 int n
= ldap_count_values_len( v
);
322 values
= realloc( values
, ( nvalues
+ n
+ 1 )*sizeof( char * ) );
323 for ( j
= 0; j
< n
; j
++ ) {
324 values
[ nvalues
+ j
] = strdup( v
[ j
]->bv_val
);
326 values
[ nvalues
+ j
] = NULL
;
328 ldap_value_free_len( v
);
335 fprintf( stderr
, " PID=%ld - Search base=\"%s\" filter=\"%s\" got %d values.\n",
336 (long) pid
, sbase
, filter
, nvalues
);
340 if ( do_retry
== maxretries
) {
341 fprintf( stderr
, " PID=%ld - Search base=\"%s\" filter=\"%s\" got %d values.\n",
342 (long) pid
, sbase
, filter
, nvalues
);
345 for ( i
= 0; i
< innerloop
; i
++ ) {
347 #if 0 /* use high-order bits for better randomness (Numerical Recipes in "C") */
348 int r
= rand() % nvalues
;
350 int r
= ((double)nvalues
)*rand()/(RAND_MAX
+ 1.0);
352 snprintf( buf
, sizeof( buf
), "(%s=%s)", attr
, values
[ r
] );
354 do_search( uri
, manager
, passwd
,
355 sbase
, scope
, buf
, &ld
,
356 srchattrs
, noattrs
, nobind
,
357 1, maxretries
, delay
, force
, chaserefs
);
362 tester_ldap_error( ld
, "ldap_search_ext_s", NULL
);
366 fprintf( stderr
, " PID=%ld - Search done (%d).\n", (long) pid
, rc
);
369 ldap_unbind_ext( ld
, NULL
, NULL
);
374 do_search( char *uri
, char *manager
, struct berval
*passwd
,
375 char *sbase
, int scope
, char *filter
, LDAP
**ldp
,
376 char **attrs
, int noattrs
, int nobind
,
377 int innerloop
, int maxretries
, int delay
, int force
, int chaserefs
)
379 LDAP
*ld
= ldp
? *ldp
: NULL
;
380 int i
= 0, do_retry
= maxretries
;
381 int rc
= LDAP_SUCCESS
;
382 int version
= LDAP_VERSION3
;
388 ldap_initialize( &ld
, uri
);
390 tester_perror( "ldap_initialize", NULL
);
391 exit( EXIT_FAILURE
);
394 (void) ldap_set_option( ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
395 (void) ldap_set_option( ld
, LDAP_OPT_REFERRALS
,
396 chaserefs
? LDAP_OPT_ON
: LDAP_OPT_OFF
);
398 if ( do_retry
== maxretries
) {
400 "PID=%ld - Search(%d): "
401 "base=\"%s\" scope=%s filter=\"%s\" "
403 (long) pid
, innerloop
,
404 sbase
, ldap_pvt_scope2str( scope
), filter
,
405 attrs
[0], attrs
[1] ? " (more...)" : "" );
409 rc
= ldap_sasl_bind_s( ld
, manager
, LDAP_SASL_SIMPLE
, passwd
, NULL
, NULL
, NULL
);
410 if ( rc
!= LDAP_SUCCESS
) {
411 snprintf( buf
, sizeof( buf
),
412 "bindDN=\"%s\"", manager
);
413 tester_ldap_error( ld
, "ldap_sasl_bind_s", buf
);
416 case LDAP_UNAVAILABLE
:
417 if ( do_retry
> 0 ) {
418 ldap_unbind_ext( ld
, NULL
, NULL
);
430 exit( EXIT_FAILURE
);
435 for ( ; i
< innerloop
; i
++ ) {
436 LDAPMessage
*res
= NULL
;
438 rc
= ldap_search_ext_s( ld
, sbase
, scope
,
439 filter
, attrs
, noattrs
, NULL
, NULL
,
440 NULL
, LDAP_NO_LIMIT
, &res
);
446 unsigned first
= tester_ignore_err( rc
);
449 /* only log if first occurrence */
450 if ( force
< 2 || first
== 1 ) {
451 tester_ldap_error( ld
, "ldap_search_ext_s", NULL
);
456 /* busy needs special handling */
457 snprintf( buf
, sizeof( buf
),
458 "base=\"%s\" filter=\"%s\"\n",
460 tester_ldap_error( ld
, "ldap_search_ext_s", buf
);
461 if ( rc
== LDAP_BUSY
&& do_retry
> 0 ) {
462 ldap_unbind_ext( ld
, NULL
, NULL
);
475 fprintf( stderr
, " PID=%ld - Search done (%d).\n", (long) pid
, rc
);
478 ldap_unbind_ext( ld
, NULL
, NULL
);