slapd-read.c 8.26 KB
Newer Older
Kurt Zeilenga's avatar
Kurt Zeilenga committed
1
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
2
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
4
 * Copyright 1999-2006 The OpenLDAP Foundation.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
5
6
7
8
9
10
11
12
13
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
14
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
15
16
17
18
19
/* ACKNOWLEDGEMENTS:
 * This work was initially developed by Kurt Spanier for inclusion
 * in OpenLDAP Software.
 */

20
21
22
#include "portable.h"

#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
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
31
32
#include <ac/unistd.h>
#include <ac/wait.h>

Kurt Zeilenga's avatar
Kurt Zeilenga committed
33
#include <ldap.h>
34
#include <lutil.h>
35

36
37
#include "slapd-common.h"

38
#define LOOPS	100
39
#define RETRIES	0
40
41

static void
42
43
44
45
46
47
48
49
do_read( char *uri, char *manager, struct berval *passwd,
	char *entry, LDAP **ld, int noattrs, int maxloop,
	int maxretries, int delay, int force, int chaserefs );

static void
do_random( char *uri, char *manager, struct berval *passwd,
	char *sbase, char *filter, int noattrs,
	int innerloop, int maxretries, int delay, int force, int chaserefs );
50
51
52
53

static void
usage( char *name )
{
54
55
56
        fprintf( stderr,
		"usage: %s "
		"-H <uri> | ([-h <host>] -p <port>) "
57
58
		"-D <manager> "
		"-w <passwd> "
59
		"-e <entry> "
60
		"[-A] "
61
		"[-C] "
62
63
		"[-F] "
		"[-f filter] "
64
		"[-l <loops>] "
65
		"[-L <outerloops>] "
66
67
		"[-r <maxretries>] "
		"[-t <delay>]\n",
68
		name );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
69
	exit( EXIT_FAILURE );
70
71
72
73
74
}

int
main( int argc, char **argv )
{
Hallvard Furuseth's avatar
Hallvard Furuseth committed
75
	int		i;
76
	char		*uri = NULL;
77
78
	char		*host = "localhost";
	int		port = -1;
79
80
	char		*manager = NULL;
	struct berval	passwd = { 0, NULL };
81
	char		*entry = NULL;
82
	char		*filter  = NULL;
83
	int		loops = LOOPS;
84
	int		outerloops = 1;
85
	int		retries = RETRIES;
86
	int		delay = 0;
87
	int		force = 0;
88
	int		chaserefs = 0;
89
	int		noattrs = 0;
90

91
92
	tester_init( "slapd-read" );

93
	while ( (i = getopt( argc, argv, "ACD:H:h:p:e:Ff:l:L:r:t:w:" )) != EOF ) {
94
		switch( i ) {
95
96
97
98
		case 'A':
			noattrs++;
			break;

99
100
101
102
		case 'C':
			chaserefs++;
			break;

103
104
		case 'H':		/* the server uri */
			uri = strdup( optarg );
105
			break;
106
107
108

		case 'h':		/* the servers host */
			host = strdup( optarg );
109
110
			break;

111
		case 'p':		/* the servers port */
112
113
114
			if ( lutil_atoi( &port, optarg ) != 0 ) {
				usage( argv[0] );
			}
115
			break;
116

117
118
119
120
121
122
123
124
125
		case 'D':		/* the servers manager */
			manager = strdup( optarg );
			break;

		case 'w':		/* the server managers password */
			passwd.bv_val = strdup( optarg );
			passwd.bv_len = strlen( optarg );
			break;

126
127
128
		case 'e':		/* DN to search for */
			entry = strdup( optarg );
			break;
129

130
131
132
133
		case 'f':		/* the search request */
			filter = strdup( optarg );
			break;

134
135
136
137
		case 'F':
			force++;
			break;

138
		case 'l':		/* the number of loops */
139
140
141
			if ( lutil_atoi( &loops, optarg ) != 0 ) {
				usage( argv[0] );
			}
142
			break;
143

144
145
146
147
148
149
		case 'L':		/* the number of outerloops */
			if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
				usage( argv[0] );
			}
			break;

150
		case 'r':		/* the number of retries */
151
152
153
			if ( lutil_atoi( &retries, optarg ) != 0 ) {
				usage( argv[0] );
			}
154
155
			break;

156
		case 't':		/* delay in seconds */
157
158
159
			if ( lutil_atoi( &delay, optarg ) != 0 ) {
				usage( argv[0] );
			}
160
161
			break;

162
163
164
		default:
			usage( argv[0] );
			break;
165
166
167
		}
	}

168
	if (( entry == NULL ) || ( port == -1 && uri == NULL ))
169
170
171
172
173
		usage( argv[0] );

	if ( *entry == '\0' ) {
		fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
				argv[0] );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
174
		exit( EXIT_FAILURE );
175
176
	}

177
178
	uri = tester_uri( uri, host, port );

179
	for ( i = 0; i < outerloops; i++ ) {
180
181
182
183
184
185
186
187
188
		if ( filter != NULL ) {
			do_random( uri, manager, &passwd, entry, filter,
				noattrs, loops, retries, delay, force,
				chaserefs );

		} else {
			do_read( uri, manager, &passwd, entry, NULL, noattrs,
				loops, retries, delay, force, chaserefs );
		}
189
190
	}

Kurt Zeilenga's avatar
Kurt Zeilenga committed
191
	exit( EXIT_SUCCESS );
192
193
194
}

static void
195
196
197
do_random( char *uri, char *manager, struct berval *passwd,
	char *sbase, char *filter, int noattrs,
	int innerloop, int maxretries, int delay, int force, int chaserefs )
198
{
199
	LDAP	*ld = NULL;
200
	int  	i = 0, do_retry = maxretries;
201
	char	*attrs[ 2 ];
202
	pid_t	pid = getpid();
203
	int     rc = LDAP_SUCCESS;
204
	int	version = LDAP_VERSION3;
205
206
	int	nvalues = 0;
	char	**values = NULL;
207
	LDAPMessage *res = NULL, *e = NULL;
208
209
210
211

	attrs[ 0 ] = LDAP_NO_ATTRS;
	attrs[ 1 ] = NULL;

212
	ldap_initialize( &ld, uri );
213
	if ( ld == NULL ) {
214
		tester_perror( "ldap_initialize" );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
215
		exit( EXIT_FAILURE );
216
217
	}

218
	(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
219
220
	(void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
		chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
221

222
	if ( do_retry == maxretries ) {
223
224
		fprintf( stderr, "PID=%ld - Read(%d): base=\"%s\", filter=\"%s\".\n",
				(long) pid, innerloop, sbase, filter );
225
226
	}

227
	rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
228
	if ( rc != LDAP_SUCCESS ) {
229
		tester_ldap_error( ld, "ldap_sasl_bind_s" );
230
231
232
233
234
235
		switch ( rc ) {
		case LDAP_BUSY:
		case LDAP_UNAVAILABLE:
		/* fallthru */
		default:
			break;
236
237
238
		}
		exit( EXIT_FAILURE );
	}
239

240
241
	rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
		filter, attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
242
243
244
245
	switch ( rc ) {
	case LDAP_SIZELIMIT_EXCEEDED:
	case LDAP_TIMELIMIT_EXCEEDED:
	case LDAP_SUCCESS:
246
		nvalues = ldap_count_entries( ld, res );
247
		if ( nvalues == 0 ) {
Pierangelo Masarati's avatar
Pierangelo Masarati committed
248
249
250
			if ( rc ) {
				tester_ldap_error( ld, "ldap_search_ext_s" );
			}
251
252
			break;
		}
253

254
255
256
257
		values = malloc( ( nvalues + 1 ) * sizeof( char * ) );
		for ( i = 0, e = ldap_first_entry( ld, res ); e != NULL; i++, e = ldap_next_entry( ld, e ) )
		{
			values[ i ] = ldap_get_dn( ld, e );
258
		}
259
		values[ i ] = NULL;
260
261
262
263
264
265
266
267
268
269
270
271

		ldap_msgfree( res );

		if ( do_retry == maxretries ) {
			fprintf( stderr, "PID=%ld - got %d values.\n", (long) pid, nvalues );
		}

		for ( i = 0; i < innerloop; i++ ) {
			do_read( uri, manager, passwd, values[ rand() % nvalues ], &ld,
				noattrs, 1, maxretries, delay, force,
				chaserefs );
		}
272
		break;
273
274
275
276

	default:
		tester_ldap_error( ld, "ldap_search_ext_s" );
		break;
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
	}

	fprintf( stderr, " PID=%ld - Search done (%d).\n", (long) pid, rc );

	if ( ld != NULL ) {
		ldap_unbind_ext( ld, NULL, NULL );
	}
}

static void
do_read( char *uri, char *manager, struct berval *passwd, char *entry,
	LDAP **ldp, int noattrs, int maxloop,
	int maxretries, int delay, int force, int chaserefs )
{
	LDAP	*ld = ldp ? *ldp : NULL;
	int  	i = 0, do_retry = maxretries;
	char	*attrs[] = { "1.1", NULL };
	pid_t	pid = getpid();
	int     rc = LDAP_SUCCESS;
	int	version = LDAP_VERSION3;
	int	first = 1;

retry:;
	if ( ld == NULL ) {
		ldap_initialize( &ld, uri );
		if ( ld == NULL ) {
			tester_perror( "ldap_initialize" );
			exit( EXIT_FAILURE );
		}

		(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
		(void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
			chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );

		if ( do_retry == maxretries ) {
			fprintf( stderr, "PID=%ld - Read(%d): entry=\"%s\".\n",
				(long) pid, maxloop, entry );
		}

		rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
		if ( rc != LDAP_SUCCESS ) {
			tester_ldap_error( ld, "ldap_sasl_bind_s" );
			switch ( rc ) {
			case LDAP_BUSY:
			case LDAP_UNAVAILABLE:
				if ( do_retry > 0 ) {
					ldap_unbind_ext( ld, NULL, NULL );
					do_retry--;
					if ( delay != 0 ) {
					    sleep( delay );
					}
					goto retry;
				}
			/* fallthru */
			default:
				break;
			}
			exit( EXIT_FAILURE );
		}
	}

338
	for ( ; i < maxloop; i++ ) {
339
		LDAPMessage *res = NULL;
340

341
		rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
342
343
				NULL, attrs, noattrs, NULL, NULL, NULL,
				LDAP_NO_LIMIT, &res );
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
		switch ( rc ) {
		case LDAP_REFERRAL:
			/* don't log: it's intended */
			if ( force >= 2 ) {
				if ( !first ) {
					break;
				}
				first = 0;
			}
			tester_ldap_error( ld, "ldap_search_ext_s" );
			/* fallthru */

		case LDAP_SUCCESS:
			break;

		default:
360
			tester_ldap_error( ld, "ldap_search_ext_s" );
361
362
363
364
			if ( rc == LDAP_BUSY && do_retry > 0 ) {
				do_retry--;
				goto retry;
			}
365
366
367
368
			if ( rc != LDAP_NO_SUCH_OBJECT ) {
				goto done;
			}
			break;
369
370
		}

371
372
373
		if ( res != NULL ) {
			ldap_msgfree( res );
		}
374
375
	}

376
done:;
377
378
379
380
381
	if ( ldp != NULL ) {
		*ldp = ld;

	} else {
		fprintf( stderr, " PID=%ld - Read done (%d).\n", (long) pid, rc );
382

383
384
385
386
		if ( ld != NULL ) {
			ldap_unbind_ext( ld, NULL, NULL );
		}
	}
387
388
}