ruby-ldap 0.9.18 → 0.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,568 @@
1
+ /* $OpenLDAP$ */
2
+ /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
+ *
4
+ * Copyright 1999-2016 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 "ldap_pvt.h"
37
+
38
+ #include "slapd-common.h"
39
+
40
+ #define LOOPS 100
41
+ #define RETRIES 0
42
+
43
+ static void
44
+ do_read( char *uri, char *manager, struct berval *passwd,
45
+ char *entry, LDAP **ld,
46
+ char **attrs, int noattrs, int nobind, int maxloop,
47
+ int maxretries, int delay, int force, int chaserefs );
48
+
49
+ static void
50
+ do_random( char *uri, char *manager, struct berval *passwd,
51
+ char *sbase, char *filter, char **attrs, int noattrs, int nobind,
52
+ int innerloop, int maxretries, int delay, int force, int chaserefs );
53
+
54
+ static void
55
+ usage( char *name )
56
+ {
57
+ fprintf( stderr,
58
+ "usage: %s "
59
+ "-H <uri> | ([-h <host>] -p <port>) "
60
+ "-D <manager> "
61
+ "-w <passwd> "
62
+ "-e <entry> "
63
+ "[-A] "
64
+ "[-C] "
65
+ "[-F] "
66
+ "[-N] "
67
+ "[-f filter] "
68
+ "[-i <ignore>] "
69
+ "[-l <loops>] "
70
+ "[-L <outerloops>] "
71
+ "[-r <maxretries>] "
72
+ "[-t <delay>] "
73
+ "[-T <attrs>] "
74
+ "[<attrs>] "
75
+ "\n",
76
+ name );
77
+ exit( EXIT_FAILURE );
78
+ }
79
+
80
+ /* -S: just send requests without reading responses
81
+ * -SS: send all requests asynchronous and immediately start reading responses
82
+ * -SSS: send all requests asynchronous; then read responses
83
+ */
84
+ static int swamp;
85
+
86
+ int
87
+ main( int argc, char **argv )
88
+ {
89
+ int i;
90
+ char *uri = NULL;
91
+ char *host = "localhost";
92
+ int port = -1;
93
+ char *manager = NULL;
94
+ struct berval passwd = { 0, NULL };
95
+ char *entry = NULL;
96
+ char *filter = NULL;
97
+ int loops = LOOPS;
98
+ int outerloops = 1;
99
+ int retries = RETRIES;
100
+ int delay = 0;
101
+ int force = 0;
102
+ int chaserefs = 0;
103
+ char *srchattrs[] = { "1.1", NULL };
104
+ char **attrs = srchattrs;
105
+ int noattrs = 0;
106
+ int nobind = 0;
107
+
108
+ tester_init( "slapd-read", TESTER_READ );
109
+
110
+ /* by default, tolerate referrals and no such object */
111
+ tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
112
+
113
+ while ( (i = getopt( argc, argv, "ACD:e:Ff:H:h:i:L:l:p:r:St:T:w:" )) != EOF ) {
114
+ switch ( i ) {
115
+ case 'A':
116
+ noattrs++;
117
+ break;
118
+
119
+ case 'C':
120
+ chaserefs++;
121
+ break;
122
+
123
+ case 'H': /* the server uri */
124
+ uri = strdup( optarg );
125
+ break;
126
+
127
+ case 'h': /* the servers host */
128
+ host = strdup( optarg );
129
+ break;
130
+
131
+ case 'i':
132
+ tester_ignore_str2errlist( optarg );
133
+ break;
134
+
135
+ case 'N':
136
+ nobind++;
137
+ break;
138
+
139
+ case 'p': /* the servers port */
140
+ if ( lutil_atoi( &port, optarg ) != 0 ) {
141
+ usage( argv[0] );
142
+ }
143
+ break;
144
+
145
+ case 'D': /* the servers manager */
146
+ manager = strdup( optarg );
147
+ break;
148
+
149
+ case 'w': /* the server managers password */
150
+ passwd.bv_val = strdup( optarg );
151
+ passwd.bv_len = strlen( optarg );
152
+ memset( optarg, '*', passwd.bv_len );
153
+ break;
154
+
155
+ case 'e': /* DN to search for */
156
+ entry = strdup( optarg );
157
+ break;
158
+
159
+ case 'f': /* the search request */
160
+ filter = strdup( optarg );
161
+ break;
162
+
163
+ case 'F':
164
+ force++;
165
+ break;
166
+
167
+ case 'l': /* the number of loops */
168
+ if ( lutil_atoi( &loops, optarg ) != 0 ) {
169
+ usage( argv[0] );
170
+ }
171
+ break;
172
+
173
+ case 'L': /* the number of outerloops */
174
+ if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
175
+ usage( argv[0] );
176
+ }
177
+ break;
178
+
179
+ case 'r': /* the number of retries */
180
+ if ( lutil_atoi( &retries, optarg ) != 0 ) {
181
+ usage( argv[0] );
182
+ }
183
+ break;
184
+
185
+ case 'S':
186
+ swamp++;
187
+ break;
188
+
189
+ case 't': /* delay in seconds */
190
+ if ( lutil_atoi( &delay, optarg ) != 0 ) {
191
+ usage( argv[0] );
192
+ }
193
+ break;
194
+
195
+ case 'T':
196
+ attrs = ldap_str2charray( optarg, "," );
197
+ if ( attrs == NULL ) {
198
+ usage( argv[0] );
199
+ }
200
+ break;
201
+
202
+ default:
203
+ usage( argv[0] );
204
+ break;
205
+ }
206
+ }
207
+
208
+ if (( entry == NULL ) || ( port == -1 && uri == NULL ))
209
+ usage( argv[0] );
210
+
211
+ if ( *entry == '\0' ) {
212
+ fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
213
+ argv[0] );
214
+ exit( EXIT_FAILURE );
215
+ }
216
+
217
+ if ( argv[optind] != NULL ) {
218
+ attrs = &argv[optind];
219
+ }
220
+
221
+ uri = tester_uri( uri, host, port );
222
+
223
+ for ( i = 0; i < outerloops; i++ ) {
224
+ if ( filter != NULL ) {
225
+ do_random( uri, manager, &passwd, entry, filter, attrs,
226
+ noattrs, nobind, loops, retries, delay, force,
227
+ chaserefs );
228
+
229
+ } else {
230
+ do_read( uri, manager, &passwd, entry, NULL, attrs,
231
+ noattrs, nobind, loops, retries, delay, force,
232
+ chaserefs );
233
+ }
234
+ }
235
+
236
+ exit( EXIT_SUCCESS );
237
+ }
238
+
239
+ static void
240
+ do_random( char *uri, char *manager, struct berval *passwd,
241
+ char *sbase, char *filter, char **srchattrs, int noattrs, int nobind,
242
+ int innerloop, int maxretries, int delay, int force, int chaserefs )
243
+ {
244
+ LDAP *ld = NULL;
245
+ int i = 0, do_retry = maxretries;
246
+ char *attrs[ 2 ];
247
+ int rc = LDAP_SUCCESS;
248
+ int version = LDAP_VERSION3;
249
+ int nvalues = 0;
250
+ char **values = NULL;
251
+ LDAPMessage *res = NULL, *e = NULL;
252
+
253
+ attrs[ 0 ] = LDAP_NO_ATTRS;
254
+ attrs[ 1 ] = NULL;
255
+
256
+ ldap_initialize( &ld, uri );
257
+ if ( ld == NULL ) {
258
+ tester_perror( "ldap_initialize", NULL );
259
+ exit( EXIT_FAILURE );
260
+ }
261
+
262
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
263
+ (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
264
+ chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
265
+
266
+ if ( do_retry == maxretries ) {
267
+ fprintf( stderr, "PID=%ld - Read(%d): base=\"%s\", filter=\"%s\".\n",
268
+ (long) pid, innerloop, sbase, filter );
269
+ }
270
+
271
+ if ( nobind == 0 ) {
272
+ rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
273
+ if ( rc != LDAP_SUCCESS ) {
274
+ tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
275
+ switch ( rc ) {
276
+ case LDAP_BUSY:
277
+ case LDAP_UNAVAILABLE:
278
+ /* fallthru */
279
+ default:
280
+ break;
281
+ }
282
+ exit( EXIT_FAILURE );
283
+ }
284
+ }
285
+
286
+ rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
287
+ filter, attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
288
+ switch ( rc ) {
289
+ case LDAP_SIZELIMIT_EXCEEDED:
290
+ case LDAP_TIMELIMIT_EXCEEDED:
291
+ case LDAP_SUCCESS:
292
+ nvalues = ldap_count_entries( ld, res );
293
+ if ( nvalues == 0 ) {
294
+ if ( rc ) {
295
+ tester_ldap_error( ld, "ldap_search_ext_s", NULL );
296
+ }
297
+ break;
298
+ }
299
+
300
+ values = malloc( ( nvalues + 1 ) * sizeof( char * ) );
301
+ for ( i = 0, e = ldap_first_entry( ld, res ); e != NULL; i++, e = ldap_next_entry( ld, e ) )
302
+ {
303
+ values[ i ] = ldap_get_dn( ld, e );
304
+ }
305
+ values[ i ] = NULL;
306
+
307
+ ldap_msgfree( res );
308
+
309
+ if ( do_retry == maxretries ) {
310
+ fprintf( stderr, " PID=%ld - Read base=\"%s\" filter=\"%s\" got %d values.\n",
311
+ (long) pid, sbase, filter, nvalues );
312
+ }
313
+
314
+ for ( i = 0; i < innerloop; i++ ) {
315
+ #if 0 /* use high-order bits for better randomness (Numerical Recipes in "C") */
316
+ int r = rand() % nvalues;
317
+ #endif
318
+ int r = ((double)nvalues)*rand()/(RAND_MAX + 1.0);
319
+
320
+ do_read( uri, manager, passwd, values[ r ], &ld,
321
+ srchattrs, noattrs, nobind, 1, maxretries,
322
+ delay, force, chaserefs );
323
+ }
324
+ free( values );
325
+ break;
326
+
327
+ default:
328
+ tester_ldap_error( ld, "ldap_search_ext_s", NULL );
329
+ break;
330
+ }
331
+
332
+ fprintf( stderr, " PID=%ld - Read done (%d).\n", (long) pid, rc );
333
+
334
+ if ( ld != NULL ) {
335
+ ldap_unbind_ext( ld, NULL, NULL );
336
+ }
337
+ }
338
+
339
+ static void
340
+ do_read( char *uri, char *manager, struct berval *passwd, char *entry,
341
+ LDAP **ldp, char **attrs, int noattrs, int nobind, int maxloop,
342
+ int maxretries, int delay, int force, int chaserefs )
343
+ {
344
+ LDAP *ld = ldp ? *ldp : NULL;
345
+ int i = 0, do_retry = maxretries;
346
+ int rc = LDAP_SUCCESS;
347
+ int version = LDAP_VERSION3;
348
+ int *msgids = NULL, active = 0;
349
+
350
+ /* make room for msgid */
351
+ if ( swamp > 1 ) {
352
+ msgids = (int *)calloc( sizeof(int), maxloop );
353
+ }
354
+
355
+ retry:;
356
+ if ( ld == NULL ) {
357
+ ldap_initialize( &ld, uri );
358
+ if ( ld == NULL ) {
359
+ tester_perror( "ldap_initialize", NULL );
360
+ exit( EXIT_FAILURE );
361
+ }
362
+
363
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
364
+ (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
365
+ chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
366
+
367
+ if ( do_retry == maxretries ) {
368
+ fprintf( stderr, "PID=%ld - Read(%d): entry=\"%s\".\n",
369
+ (long) pid, maxloop, entry );
370
+ }
371
+
372
+ if ( nobind == 0 ) {
373
+ rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
374
+ if ( rc != LDAP_SUCCESS ) {
375
+ tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
376
+ switch ( rc ) {
377
+ case LDAP_BUSY:
378
+ case LDAP_UNAVAILABLE:
379
+ if ( do_retry > 0 ) {
380
+ ldap_unbind_ext( ld, NULL, NULL );
381
+ ld = NULL;
382
+ do_retry--;
383
+ if ( delay != 0 ) {
384
+ sleep( delay );
385
+ }
386
+ goto retry;
387
+ }
388
+ /* fallthru */
389
+ default:
390
+ break;
391
+ }
392
+ exit( EXIT_FAILURE );
393
+ }
394
+ }
395
+ }
396
+
397
+ if ( swamp > 1 ) {
398
+ do {
399
+ LDAPMessage *res = NULL;
400
+ int j, msgid;
401
+
402
+ if ( i < maxloop ) {
403
+ rc = ldap_search_ext( ld, entry, LDAP_SCOPE_BASE,
404
+ NULL, attrs, noattrs, NULL, NULL,
405
+ NULL, LDAP_NO_LIMIT, &msgids[i] );
406
+
407
+ active++;
408
+ #if 0
409
+ fprintf( stderr,
410
+ ">>> PID=%ld - Read maxloop=%d cnt=%d active=%d msgid=%d: "
411
+ "entry=\"%s\"\n",
412
+ (long) pid, maxloop, i, active, msgids[i],
413
+ entry );
414
+ #endif
415
+ i++;
416
+
417
+ if ( rc ) {
418
+ char buf[BUFSIZ];
419
+ int first = tester_ignore_err( rc );
420
+ /* if ignore.. */
421
+ if ( first ) {
422
+ /* only log if first occurrence */
423
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
424
+ tester_ldap_error( ld, "ldap_search_ext", NULL );
425
+ }
426
+ continue;
427
+ }
428
+
429
+ /* busy needs special handling */
430
+ snprintf( buf, sizeof( buf ), "entry=\"%s\"\n", entry );
431
+ tester_ldap_error( ld, "ldap_search_ext", buf );
432
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
433
+ ldap_unbind_ext( ld, NULL, NULL );
434
+ ld = NULL;
435
+ do_retry--;
436
+ goto retry;
437
+ }
438
+ break;
439
+ }
440
+
441
+ if ( swamp > 2 ) {
442
+ continue;
443
+ }
444
+ }
445
+
446
+ rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res );
447
+ switch ( rc ) {
448
+ case -1:
449
+ /* gone really bad */
450
+ #if 0
451
+ fprintf( stderr,
452
+ ">>> PID=%ld - Read maxloop=%d cnt=%d active=%d: "
453
+ "entry=\"%s\" ldap_result()=%d\n",
454
+ (long) pid, maxloop, i, active, entry, rc );
455
+ #endif
456
+ goto cleanup;
457
+
458
+ case 0:
459
+ /* timeout (impossible) */
460
+ break;
461
+
462
+ case LDAP_RES_SEARCH_ENTRY:
463
+ case LDAP_RES_SEARCH_REFERENCE:
464
+ /* ignore */
465
+ break;
466
+
467
+ case LDAP_RES_SEARCH_RESULT:
468
+ /* just remove, no error checking (TODO?) */
469
+ msgid = ldap_msgid( res );
470
+ ldap_parse_result( ld, res, &rc, NULL, NULL, NULL, NULL, 1 );
471
+ res = NULL;
472
+
473
+ /* linear search, bah */
474
+ for ( j = 0; j < i; j++ ) {
475
+ if ( msgids[ j ] == msgid ) {
476
+ msgids[ j ] = -1;
477
+ active--;
478
+ #if 0
479
+ fprintf( stderr,
480
+ "<<< PID=%ld - ReadDone maxloop=%d cnt=%d active=%d msgid=%d: "
481
+ "entry=\"%s\"\n",
482
+ (long) pid, maxloop, j, active, msgid, entry );
483
+ #endif
484
+ break;
485
+ }
486
+ }
487
+ break;
488
+
489
+ default:
490
+ /* other messages unexpected */
491
+ fprintf( stderr,
492
+ "### PID=%ld - Read(%d): "
493
+ "entry=\"%s\" attrs=%s%s. unexpected response tag=%d\n",
494
+ (long) pid, maxloop,
495
+ entry, attrs[0], attrs[1] ? " (more...)" : "", rc );
496
+ break;
497
+ }
498
+
499
+ if ( res != NULL ) {
500
+ ldap_msgfree( res );
501
+ }
502
+ } while ( i < maxloop || active > 0 );
503
+
504
+ } else {
505
+ for ( ; i < maxloop; i++ ) {
506
+ LDAPMessage *res = NULL;
507
+
508
+ if (swamp) {
509
+ int msgid;
510
+ rc = ldap_search_ext( ld, entry, LDAP_SCOPE_BASE,
511
+ NULL, attrs, noattrs, NULL, NULL,
512
+ NULL, LDAP_NO_LIMIT, &msgid );
513
+ if ( rc == LDAP_SUCCESS ) continue;
514
+ else break;
515
+ }
516
+
517
+ rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
518
+ NULL, attrs, noattrs, NULL, NULL, NULL,
519
+ LDAP_NO_LIMIT, &res );
520
+ if ( res != NULL ) {
521
+ ldap_msgfree( res );
522
+ }
523
+
524
+ if ( rc ) {
525
+ int first = tester_ignore_err( rc );
526
+ char buf[ BUFSIZ ];
527
+
528
+ snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );
529
+
530
+ /* if ignore.. */
531
+ if ( first ) {
532
+ /* only log if first occurrence */
533
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
534
+ tester_ldap_error( ld, buf, NULL );
535
+ }
536
+ continue;
537
+ }
538
+
539
+ /* busy needs special handling */
540
+ tester_ldap_error( ld, buf, NULL );
541
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
542
+ ldap_unbind_ext( ld, NULL, NULL );
543
+ ld = NULL;
544
+ do_retry--;
545
+ goto retry;
546
+ }
547
+ break;
548
+ }
549
+ }
550
+ }
551
+
552
+ cleanup:;
553
+ if ( msgids != NULL ) {
554
+ free( msgids );
555
+ }
556
+
557
+ if ( ldp != NULL ) {
558
+ *ldp = ld;
559
+
560
+ } else {
561
+ fprintf( stderr, " PID=%ld - Read done (%d).\n", (long) pid, rc );
562
+
563
+ if ( ld != NULL ) {
564
+ ldap_unbind_ext( ld, NULL, NULL );
565
+ }
566
+ }
567
+ }
568
+