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