]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-search.c
6357f7716f8a54edbd7b2c3a905d1cd5048bf297
[openldap] / tests / progs / slapd-search.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2006 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
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>.
14  */
15 /* ACKNOWLEDGEMENTS:
16  * This work was initially developed by Kurt Spanier for inclusion
17  * in OpenLDAP Software.
18  */
19
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/stdlib.h>
25
26 #include <ac/ctype.h>
27 #include <ac/param.h>
28 #include <ac/socket.h>
29 #include <ac/string.h>
30 #include <ac/unistd.h>
31 #include <ac/wait.h>
32
33 #include <ldap.h>
34 #include <lutil.h>
35
36 #include "slapd-common.h"
37
38 #define LOOPS   100
39 #define RETRIES 0
40
41 static void
42 do_search( char *uri, char *manager, struct berval *passwd,
43         char *sbase, char *filter, LDAP **ldp,
44         int innerloop, int maxretries, int delay );
45
46 static void
47 do_random( char *uri, char *manager, struct berval *passwd,
48         char *sbase, char *filter, char *attr, int innerloop,
49         int maxretries, int delay );
50
51 static void
52 usage( char *name )
53 {
54         fprintf( stderr,
55                 "usage: %s "
56                 "-H <uri> | ([-h <host>] -p <port>) "
57                 "-D <manager> "
58                 "-w <passwd> "
59                 "-b <searchbase> "
60                 "-f <searchfilter> "
61                 "[-a <attr>] "
62                 "[-l <loops>] "
63                 "[-L <outerloops>] "
64                 "[-r <maxretries>] "
65                 "[-t <delay>]\n",
66                         name );
67         exit( EXIT_FAILURE );
68 }
69
70 int
71 main( int argc, char **argv )
72 {
73         int             i;
74         char            *uri = NULL;
75         char            *host = "localhost";
76         int             port = -1;
77         char            *manager = NULL;
78         struct berval   passwd = { 0, NULL };
79         char            *sbase = NULL;
80         char            *filter  = NULL;
81         char            *attr = NULL;
82         int             loops = LOOPS;
83         int             outerloops = 1;
84         int             retries = RETRIES;
85         int             delay = 0;
86
87         tester_init( "slapd-search" );
88
89         while ( (i = getopt( argc, argv, "a:b:D:f:H:h:l:L:p:w:r:t:" )) != EOF ) {
90                 switch( i ) {
91                 case 'H':               /* the server uri */
92                         uri = strdup( optarg );
93                         break;
94
95                 case 'h':               /* the servers host */
96                         host = strdup( optarg );
97                         break;
98
99                 case 'p':               /* the servers port */
100                         if ( lutil_atoi( &port, optarg ) != 0 ) {
101                                 usage( argv[0] );
102                         }
103                         break;
104
105                 case 'D':               /* the servers manager */
106                         manager = strdup( optarg );
107                         break;
108
109                 case 'w':               /* the server managers password */
110                         passwd.bv_val = strdup( optarg );
111                         passwd.bv_len = strlen( optarg );
112                         break;
113
114                 case 'a':
115                         attr = strdup( optarg );
116                         break;
117
118                 case 'b':               /* file with search base */
119                         sbase = strdup( optarg );
120                         break;
121
122                 case 'f':               /* the search request */
123                         filter = strdup( optarg );
124                         break;
125
126                 case 'l':               /* number of loops */
127                         if ( lutil_atoi( &loops, optarg ) != 0 ) {
128                                 usage( argv[0] );
129                         }
130                         break;
131
132                 case 'L':               /* number of loops */
133                         if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
134                                 usage( argv[0] );
135                         }
136                         break;
137
138                 case 'r':               /* number of retries */
139                         if ( lutil_atoi( &retries, optarg ) != 0 ) {
140                                 usage( argv[0] );
141                         }
142                         break;
143
144                 case 't':               /* delay in seconds */
145                         if ( lutil_atoi( &delay, optarg ) != 0 ) {
146                                 usage( argv[0] );
147                         }
148                         break;
149
150                 default:
151                         usage( argv[0] );
152                         break;
153                 }
154         }
155
156         if (( sbase == NULL ) || ( filter == NULL ) || ( port == -1 && uri == NULL ))
157                 usage( argv[0] );
158
159         if ( *filter == '\0' ) {
160
161                 fprintf( stderr, "%s: invalid EMPTY search filter.\n",
162                                 argv[0] );
163                 exit( EXIT_FAILURE );
164
165         }
166
167         uri = tester_uri( uri, host, port );
168
169         for ( i = 0; i < outerloops; i++ ) {
170                 if ( attr != NULL ) {
171                         do_random( uri, manager, &passwd, sbase, filter, attr,
172                                         loops, retries, delay );
173
174                 } else {
175                         do_search( uri, manager, &passwd, sbase, filter, NULL,
176                                         loops, retries, delay );
177                 }
178         }
179
180         exit( EXIT_SUCCESS );
181 }
182
183
184 static void
185 do_random( char *uri, char *manager, struct berval *passwd,
186         char *sbase, char *filter, char *attr,
187         int innerloop, int maxretries, int delay )
188 {
189         LDAP    *ld = NULL;
190         int     i = 0, do_retry = maxretries;
191         char    *attrs[ 2 ];
192         pid_t   pid = getpid();
193         int     rc = LDAP_SUCCESS;
194         int     version = LDAP_VERSION3;
195         int     nvalues = 0;
196         char    **values = NULL;
197         LDAPMessage *res = NULL;
198
199         attrs[ 0 ] = attr;
200         attrs[ 1 ] = NULL;
201
202         ldap_initialize( &ld, uri );
203         if ( ld == NULL ) {
204                 tester_perror( "ldap_initialize" );
205                 exit( EXIT_FAILURE );
206         }
207
208         (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
209
210         if ( do_retry == maxretries ) {
211                 fprintf( stderr, "PID=%ld - Search(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n",
212                                 (long) pid, innerloop, sbase, filter, attr );
213         }
214
215         rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
216         if ( rc != LDAP_SUCCESS ) {
217                 tester_ldap_error( ld, "ldap_sasl_bind_s" );
218                 switch ( rc ) {
219                 case LDAP_BUSY:
220                 case LDAP_UNAVAILABLE:
221                 /* fallthru */
222                 default:
223                         break;
224                 }
225                 exit( EXIT_FAILURE );
226         }
227
228         rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
229                 filter, attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
230         if ( rc != LDAP_SUCCESS ) {
231                 tester_ldap_error( ld, "ldap_search_ext_s" );
232
233         } else {
234                 LDAPMessage *e;
235                 for ( e = ldap_first_entry( ld, res ); e != NULL; e = ldap_next_entry( ld, e ) )
236                 {
237                         struct berval **v = ldap_get_values_len( ld, e, attr );
238
239                         if ( v != NULL ) {
240                                 int n = ldap_count_values_len( v );
241                                 int j;
242
243                                 values = realloc( values, ( nvalues + n + 1 )*sizeof( char * ) );
244                                 for ( j = 0; j < n; j++ ) {
245                                         values[ nvalues + j ] = strdup( v[ j ]->bv_val );
246                                 }
247                                 values[ nvalues + j ] = NULL;
248                                 nvalues += n;
249                                 ldap_value_free_len( v );
250                         }
251                 }
252
253                 ldap_msgfree( res );
254
255                 for ( i = 0; i < innerloop; i++ ) {
256                         char    buf[ BUFSIZ ];
257
258                         snprintf( buf, sizeof( buf ), "(%s=%s)", attr, values[ rand() % nvalues ] );
259
260                         do_search( uri, manager, passwd, sbase, buf, &ld,
261                                         1, maxretries, delay );
262                 }
263         }
264                 
265
266         fprintf( stderr, " PID=%ld - Search done (%d).\n", (long) pid, rc );
267
268         if ( ld != NULL ) {
269                 ldap_unbind_ext( ld, NULL, NULL );
270         }
271 }
272 static void
273 do_search( char *uri, char *manager, struct berval *passwd,
274                 char *sbase, char *filter, LDAP **ldp,
275                 int innerloop, int maxretries, int delay )
276 {
277         LDAP    *ld = ldp ? *ldp : NULL;
278         int     i = 0, do_retry = maxretries;
279         char    *attrs[] = { "cn", "sn", NULL };
280         pid_t   pid = getpid();
281         int     rc = LDAP_SUCCESS;
282         int     version = LDAP_VERSION3;
283
284 retry:;
285         if ( ld == NULL ) {
286                 ldap_initialize( &ld, uri );
287                 if ( ld == NULL ) {
288                         tester_perror( "ldap_initialize" );
289                         exit( EXIT_FAILURE );
290                 }
291
292                 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
293
294                 if ( do_retry == maxretries ) {
295                         fprintf( stderr, "PID=%ld - Search(%d): base=\"%s\", filter=\"%s\".\n",
296                                         (long) pid, innerloop, sbase, filter );
297                 }
298
299                 rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
300                 if ( rc != LDAP_SUCCESS ) {
301                         tester_ldap_error( ld, "ldap_sasl_bind_s" );
302                         switch ( rc ) {
303                         case LDAP_BUSY:
304                         case LDAP_UNAVAILABLE:
305                                 if ( do_retry > 0 ) {
306                                         ldap_unbind_ext( ld, NULL, NULL );
307                                         do_retry--;
308                                         if ( delay != 0 ) {
309                                             sleep( delay );
310                                         }
311                                         goto retry;
312                                 }
313                         /* fallthru */
314                         default:
315                                 break;
316                         }
317                         exit( EXIT_FAILURE );
318                 }
319         }
320
321         for ( ; i < innerloop; i++ ) {
322                 LDAPMessage *res;
323
324                 rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
325                                 filter, attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
326                 if ( rc != LDAP_SUCCESS ) {
327                         tester_ldap_error( ld, "ldap_search_ext_s" );
328                         if ( rc == LDAP_BUSY && do_retry > 0 ) {
329                                 ldap_unbind_ext( ld, NULL, NULL );
330                                 do_retry--;
331                                 goto retry;
332                         }
333                         if ( rc != LDAP_NO_SUCH_OBJECT ) break;
334                         continue;
335
336                 }
337
338                 ldap_msgfree( res );
339         }
340
341
342         if ( ldp != NULL ) {
343                 *ldp = ld;
344
345         } else {
346                 fprintf( stderr, " PID=%ld - Search done (%d).\n", (long) pid, rc );
347
348                 if ( ld != NULL ) {
349                         ldap_unbind_ext( ld, NULL, NULL );
350                 }
351         }
352 }