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,1197 @@
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/dirent.h"
28
+ #include "ac/param.h"
29
+ #include "ac/socket.h"
30
+ #include "ac/string.h"
31
+ #include "ac/unistd.h"
32
+ #include "ac/wait.h"
33
+
34
+
35
+ #include "ldap_defaults.h"
36
+ #include "lutil.h"
37
+
38
+ #include "ldap.h"
39
+ #include "ldap_pvt.h"
40
+ #include "lber_pvt.h"
41
+ #include "slapd-common.h"
42
+
43
+ #ifdef _WIN32
44
+ #define EXE ".exe"
45
+ #else
46
+ #define EXE
47
+ #endif
48
+
49
+ #define SEARCHCMD "slapd-search" EXE
50
+ #define READCMD "slapd-read" EXE
51
+ #define ADDCMD "slapd-addel" EXE
52
+ #define MODRDNCMD "slapd-modrdn" EXE
53
+ #define MODIFYCMD "slapd-modify" EXE
54
+ #define BINDCMD "slapd-bind" EXE
55
+ #define MAXARGS 100
56
+ #define MAXREQS 5000
57
+ #define LOOPS 100
58
+ #define OUTERLOOPS "1"
59
+ #define RETRIES "0"
60
+
61
+ #define TSEARCHFILE "do_search.0"
62
+ #define TREADFILE "do_read.0"
63
+ #define TADDFILE "do_add."
64
+ #define TMODRDNFILE "do_modrdn.0"
65
+ #define TMODIFYFILE "do_modify.0"
66
+ #define TBINDFILE "do_bind.0"
67
+
68
+ static char *get_file_name( char *dirname, char *filename );
69
+ static int get_search_filters( char *filename, char *filters[], char *attrs[], char *bases[], LDAPURLDesc *luds[] );
70
+ static int get_read_entries( char *filename, char *entries[], char *filters[] );
71
+ static void fork_child( char *prog, char **args );
72
+ static void wait4kids( int nkidval );
73
+
74
+ static int maxkids = 20;
75
+ static int nkids;
76
+
77
+ #ifdef HAVE_WINSOCK
78
+ static HANDLE *children;
79
+ static char argbuf[BUFSIZ];
80
+ #define ArgDup(x) strdup(strcat(strcat(strcpy(argbuf,"\""),x),"\""))
81
+ #else
82
+ #define ArgDup(x) strdup(x)
83
+ #endif
84
+
85
+ static void
86
+ usage( char *name, char opt )
87
+ {
88
+ if ( opt ) {
89
+ fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
90
+ name, opt );
91
+ }
92
+
93
+ fprintf( stderr,
94
+ "usage: %s "
95
+ "-H <uri> | ([-h <host>] -p <port>) "
96
+ "-D <manager> "
97
+ "-w <passwd> "
98
+ "-d <datadir> "
99
+ "[-i <ignore>] "
100
+ "[-j <maxchild>] "
101
+ "[-l {<loops>|<type>=<loops>[,...]}] "
102
+ "[-L <outerloops>] "
103
+ "-P <progdir> "
104
+ "[-r <maxretries>] "
105
+ "[-t <delay>] "
106
+ "[-C] "
107
+ "[-F] "
108
+ "[-I] "
109
+ "[-N]\n",
110
+ name );
111
+ exit( EXIT_FAILURE );
112
+ }
113
+
114
+ int
115
+ main( int argc, char **argv )
116
+ {
117
+ int i, j;
118
+ char *uri = NULL;
119
+ char *host = "localhost";
120
+ char *port = NULL;
121
+ char *manager = NULL;
122
+ char *passwd = NULL;
123
+ char *dirname = NULL;
124
+ char *progdir = NULL;
125
+ int loops = LOOPS;
126
+ char *outerloops = OUTERLOOPS;
127
+ char *retries = RETRIES;
128
+ char *delay = "0";
129
+ DIR *datadir;
130
+ struct dirent *file;
131
+ int friendly = 0;
132
+ int chaserefs = 0;
133
+ int noattrs = 0;
134
+ int nobind = 0;
135
+ int noinit = 1;
136
+ char *ignore = NULL;
137
+ /* search */
138
+ char *sfile = NULL;
139
+ char *sreqs[MAXREQS];
140
+ char *sattrs[MAXREQS];
141
+ char *sbase[MAXREQS];
142
+ LDAPURLDesc *slud[MAXREQS];
143
+ int snum = 0;
144
+ char *sargs[MAXARGS];
145
+ int sanum;
146
+ int sextra_args = 0;
147
+ char scmd[MAXPATHLEN];
148
+ int swamp = 0;
149
+ char swampopt[sizeof("-SSS")];
150
+ /* static so that its address can be used in initializer below. */
151
+ static char sloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
152
+ /* read */
153
+ char *rfile = NULL;
154
+ char *rreqs[MAXREQS];
155
+ int rnum = 0;
156
+ char *rargs[MAXARGS];
157
+ char *rflts[MAXREQS];
158
+ int ranum;
159
+ int rextra_args = 0;
160
+ char rcmd[MAXPATHLEN];
161
+ static char rloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
162
+ /* addel */
163
+ char *afiles[MAXREQS];
164
+ int anum = 0;
165
+ char *aargs[MAXARGS];
166
+ int aanum;
167
+ char acmd[MAXPATHLEN];
168
+ static char aloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
169
+ /* modrdn */
170
+ char *nfile = NULL;
171
+ char *nreqs[MAXREQS];
172
+ int nnum = 0;
173
+ char *nargs[MAXARGS];
174
+ int nanum;
175
+ char ncmd[MAXPATHLEN];
176
+ static char nloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
177
+ /* modify */
178
+ char *mfile = NULL;
179
+ char *mreqs[MAXREQS];
180
+ char *mdn[MAXREQS];
181
+ int mnum = 0;
182
+ char *margs[MAXARGS];
183
+ int manum;
184
+ char mcmd[MAXPATHLEN];
185
+ static char mloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
186
+ /* bind */
187
+ char *bfile = NULL;
188
+ char *breqs[MAXREQS];
189
+ char *bcreds[MAXREQS];
190
+ char *battrs[MAXREQS];
191
+ int bnum = 0;
192
+ char *bargs[MAXARGS];
193
+ int banum;
194
+ char bcmd[MAXPATHLEN];
195
+ static char bloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
196
+ char **bargs_extra = NULL;
197
+
198
+ char *friendlyOpt = NULL;
199
+ int pw_ask = 0;
200
+ char *pw_file = NULL;
201
+
202
+ /* extra action to do after bind... */
203
+ typedef struct extra_t {
204
+ char *action;
205
+ struct extra_t *next;
206
+ } extra_t;
207
+
208
+ extra_t *extra = NULL;
209
+ int nextra = 0;
210
+
211
+ tester_init( "slapd-tester", TESTER_TESTER );
212
+
213
+ sloops[0] = '\0';
214
+ rloops[0] = '\0';
215
+ aloops[0] = '\0';
216
+ nloops[0] = '\0';
217
+ mloops[0] = '\0';
218
+ bloops[0] = '\0';
219
+
220
+ while ( ( i = getopt( argc, argv, "AB:CD:d:FH:h:Ii:j:L:l:NP:p:r:St:Ww:y:" ) ) != EOF )
221
+ {
222
+ switch ( i ) {
223
+ case 'A':
224
+ noattrs++;
225
+ break;
226
+
227
+ case 'B': {
228
+ char **p,
229
+ **b = ldap_str2charray( optarg, "," );
230
+ extra_t **epp;
231
+
232
+ for ( epp = &extra; *epp; epp = &(*epp)->next )
233
+ ;
234
+
235
+ for ( p = b; p[0]; p++ ) {
236
+ *epp = calloc( 1, sizeof( extra_t ) );
237
+ (*epp)->action = p[0];
238
+ epp = &(*epp)->next;
239
+ nextra++;
240
+ }
241
+
242
+ ldap_memfree( b );
243
+ } break;
244
+
245
+ case 'C':
246
+ chaserefs++;
247
+ break;
248
+
249
+ case 'D': /* slapd manager */
250
+ manager = ArgDup( optarg );
251
+ break;
252
+
253
+ case 'd': /* data directory */
254
+ dirname = strdup( optarg );
255
+ break;
256
+
257
+ case 'F':
258
+ friendly++;
259
+ break;
260
+
261
+ case 'H': /* slapd uri */
262
+ uri = strdup( optarg );
263
+ break;
264
+
265
+ case 'h': /* slapd host */
266
+ host = strdup( optarg );
267
+ break;
268
+
269
+ case 'I':
270
+ noinit = 0;
271
+ break;
272
+
273
+ case 'i':
274
+ ignore = optarg;
275
+ break;
276
+
277
+ case 'j': /* the number of parallel clients */
278
+ if ( lutil_atoi( &maxkids, optarg ) != 0 ) {
279
+ usage( argv[0], 'j' );
280
+ }
281
+ break;
282
+
283
+ case 'l': /* the number of loops per client */
284
+ if ( !isdigit( (unsigned char) optarg[0] ) ) {
285
+ char **p,
286
+ **l = ldap_str2charray( optarg, "," );
287
+
288
+ for ( p = l; p[0]; p++) {
289
+ struct {
290
+ struct berval type;
291
+ char *buf;
292
+ } types[] = {
293
+ { BER_BVC( "add=" ), aloops },
294
+ { BER_BVC( "bind=" ), bloops },
295
+ { BER_BVC( "modify=" ), mloops },
296
+ { BER_BVC( "modrdn=" ), nloops },
297
+ { BER_BVC( "read=" ), rloops },
298
+ { BER_BVC( "search=" ), sloops },
299
+ { BER_BVNULL, NULL }
300
+ };
301
+ int c, n;
302
+
303
+ for ( c = 0; types[c].type.bv_val; c++ ) {
304
+ if ( strncasecmp( p[0], types[c].type.bv_val, types[c].type.bv_len ) == 0 ) {
305
+ break;
306
+ }
307
+ }
308
+
309
+ if ( types[c].type.bv_val == NULL ) {
310
+ usage( argv[0], 'l' );
311
+ }
312
+
313
+ if ( lutil_atoi( &n, &p[0][types[c].type.bv_len] ) != 0 ) {
314
+ usage( argv[0], 'l' );
315
+ }
316
+
317
+ snprintf( types[c].buf, sizeof( aloops ), "%d", n );
318
+ }
319
+
320
+ ldap_charray_free( l );
321
+
322
+ } else if ( lutil_atoi( &loops, optarg ) != 0 ) {
323
+ usage( argv[0], 'l' );
324
+ }
325
+ break;
326
+
327
+ case 'L': /* the number of outerloops per client */
328
+ outerloops = strdup( optarg );
329
+ break;
330
+
331
+ case 'N':
332
+ nobind++;
333
+ break;
334
+
335
+ case 'P': /* prog directory */
336
+ progdir = strdup( optarg );
337
+ break;
338
+
339
+ case 'p': /* the servers port number */
340
+ port = strdup( optarg );
341
+ break;
342
+
343
+ case 'r': /* the number of retries in case of error */
344
+ retries = strdup( optarg );
345
+ break;
346
+
347
+ case 'S':
348
+ swamp++;
349
+ break;
350
+
351
+ case 't': /* the delay in seconds between each retry */
352
+ delay = strdup( optarg );
353
+ break;
354
+
355
+ case 'w': /* the managers passwd */
356
+ passwd = ArgDup( optarg );
357
+ memset( optarg, '*', strlen( optarg ) );
358
+ break;
359
+
360
+ case 'W':
361
+ pw_ask++;
362
+ break;
363
+
364
+ case 'y':
365
+ pw_file = optarg;
366
+ break;
367
+
368
+ default:
369
+ usage( argv[0], '\0' );
370
+ break;
371
+ }
372
+ }
373
+
374
+ if (( dirname == NULL ) || ( port == NULL && uri == NULL ) ||
375
+ ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
376
+ {
377
+ usage( argv[0], '\0' );
378
+ }
379
+
380
+ #ifdef HAVE_WINSOCK
381
+ children = malloc( maxkids * sizeof(HANDLE) );
382
+ #endif
383
+ /* get the file list */
384
+ if ( ( datadir = opendir( dirname )) == NULL ) {
385
+ fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
386
+ argv[0], dirname );
387
+ exit( EXIT_FAILURE );
388
+ }
389
+
390
+ /* look for search, read, modrdn, and add/delete files */
391
+ for ( file = readdir( datadir ); file; file = readdir( datadir )) {
392
+
393
+ if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
394
+ sfile = get_file_name( dirname, file->d_name );
395
+ continue;
396
+ } else if ( !strcasecmp( file->d_name, TREADFILE )) {
397
+ rfile = get_file_name( dirname, file->d_name );
398
+ continue;
399
+ } else if ( !strcasecmp( file->d_name, TMODRDNFILE )) {
400
+ nfile = get_file_name( dirname, file->d_name );
401
+ continue;
402
+ } else if ( !strcasecmp( file->d_name, TMODIFYFILE )) {
403
+ mfile = get_file_name( dirname, file->d_name );
404
+ continue;
405
+ } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
406
+ && ( anum < MAXREQS )) {
407
+ afiles[anum++] = get_file_name( dirname, file->d_name );
408
+ continue;
409
+ } else if ( !strcasecmp( file->d_name, TBINDFILE )) {
410
+ bfile = get_file_name( dirname, file->d_name );
411
+ continue;
412
+ }
413
+ }
414
+
415
+ closedir( datadir );
416
+
417
+ if ( pw_ask ) {
418
+ passwd = getpassphrase( _("Enter LDAP Password: ") );
419
+
420
+ } else if ( pw_file ) {
421
+ struct berval pw;
422
+
423
+ if ( lutil_get_filed_password( pw_file, &pw ) ) {
424
+ exit( EXIT_FAILURE );
425
+ }
426
+
427
+ passwd = pw.bv_val;
428
+ }
429
+
430
+ if ( !sfile && !rfile && !nfile && !mfile && !bfile && !anum ) {
431
+ fprintf( stderr, "no data files found.\n" );
432
+ exit( EXIT_FAILURE );
433
+ }
434
+
435
+ /* look for search requests */
436
+ if ( sfile ) {
437
+ snum = get_search_filters( sfile, sreqs, sattrs, sbase, slud );
438
+ if ( snum < 0 ) {
439
+ fprintf( stderr,
440
+ "unable to parse file \"%s\" line %d\n",
441
+ sfile, -2*(snum + 1));
442
+ exit( EXIT_FAILURE );
443
+ }
444
+ }
445
+
446
+ /* look for read requests */
447
+ if ( rfile ) {
448
+ rnum = get_read_entries( rfile, rreqs, rflts );
449
+ if ( rnum < 0 ) {
450
+ fprintf( stderr,
451
+ "unable to parse file \"%s\" line %d\n",
452
+ rfile, -2*(rnum + 1) );
453
+ exit( EXIT_FAILURE );
454
+ }
455
+ }
456
+
457
+ /* look for modrdn requests */
458
+ if ( nfile ) {
459
+ nnum = get_read_entries( nfile, nreqs, NULL );
460
+ if ( nnum < 0 ) {
461
+ fprintf( stderr,
462
+ "unable to parse file \"%s\" line %d\n",
463
+ nfile, -2*(nnum + 1) );
464
+ exit( EXIT_FAILURE );
465
+ }
466
+ }
467
+
468
+ /* look for modify requests */
469
+ if ( mfile ) {
470
+ mnum = get_search_filters( mfile, mreqs, NULL, mdn, NULL );
471
+ if ( mnum < 0 ) {
472
+ fprintf( stderr,
473
+ "unable to parse file \"%s\" line %d\n",
474
+ mfile, -2*(mnum + 1) );
475
+ exit( EXIT_FAILURE );
476
+ }
477
+ }
478
+
479
+ /* look for bind requests */
480
+ if ( bfile ) {
481
+ bnum = get_search_filters( bfile, bcreds, battrs, breqs, NULL );
482
+ if ( bnum < 0 ) {
483
+ fprintf( stderr,
484
+ "unable to parse file \"%s\" line %d\n",
485
+ bfile, -2*(bnum + 1) );
486
+ exit( EXIT_FAILURE );
487
+ }
488
+ }
489
+
490
+ /* setup friendly option */
491
+ switch ( friendly ) {
492
+ case 0:
493
+ break;
494
+
495
+ case 1:
496
+ friendlyOpt = "-F";
497
+ break;
498
+
499
+ default:
500
+ /* NOTE: right now we don't need it more than twice */
501
+ case 2:
502
+ friendlyOpt = "-FF";
503
+ break;
504
+ }
505
+
506
+ /* setup swamp option */
507
+ if ( swamp ) {
508
+ swampopt[0] = '-';
509
+ if ( swamp > 3 ) swamp = 3;
510
+ swampopt[swamp + 1] = '\0';
511
+ for ( ; swamp-- > 0; ) swampopt[swamp + 1] = 'S';
512
+ }
513
+
514
+ /* setup loop options */
515
+ if ( sloops[0] == '\0' ) snprintf( sloops, sizeof( sloops ), "%d", 10 * loops );
516
+ if ( rloops[0] == '\0' ) snprintf( rloops, sizeof( rloops ), "%d", 20 * loops );
517
+ if ( aloops[0] == '\0' ) snprintf( aloops, sizeof( aloops ), "%d", loops );
518
+ if ( nloops[0] == '\0' ) snprintf( nloops, sizeof( nloops ), "%d", loops );
519
+ if ( mloops[0] == '\0' ) snprintf( mloops, sizeof( mloops ), "%d", loops );
520
+ if ( bloops[0] == '\0' ) snprintf( bloops, sizeof( bloops ), "%d", 20 * loops );
521
+
522
+ /*
523
+ * generate the search clients
524
+ */
525
+
526
+ sanum = 0;
527
+ snprintf( scmd, sizeof scmd, "%s" LDAP_DIRSEP SEARCHCMD,
528
+ progdir );
529
+ sargs[sanum++] = scmd;
530
+ if ( uri ) {
531
+ sargs[sanum++] = "-H";
532
+ sargs[sanum++] = uri;
533
+ } else {
534
+ sargs[sanum++] = "-h";
535
+ sargs[sanum++] = host;
536
+ sargs[sanum++] = "-p";
537
+ sargs[sanum++] = port;
538
+ }
539
+ sargs[sanum++] = "-D";
540
+ sargs[sanum++] = manager;
541
+ sargs[sanum++] = "-w";
542
+ sargs[sanum++] = passwd;
543
+ sargs[sanum++] = "-l";
544
+ sargs[sanum++] = sloops;
545
+ sargs[sanum++] = "-L";
546
+ sargs[sanum++] = outerloops;
547
+ sargs[sanum++] = "-r";
548
+ sargs[sanum++] = retries;
549
+ sargs[sanum++] = "-t";
550
+ sargs[sanum++] = delay;
551
+ if ( friendly ) {
552
+ sargs[sanum++] = friendlyOpt;
553
+ }
554
+ if ( chaserefs ) {
555
+ sargs[sanum++] = "-C";
556
+ }
557
+ if ( noattrs ) {
558
+ sargs[sanum++] = "-A";
559
+ }
560
+ if ( nobind ) {
561
+ sargs[sanum++] = "-N";
562
+ }
563
+ if ( ignore ) {
564
+ sargs[sanum++] = "-i";
565
+ sargs[sanum++] = ignore;
566
+ }
567
+ if ( swamp ) {
568
+ sargs[sanum++] = swampopt;
569
+ }
570
+ sargs[sanum++] = "-b";
571
+ sargs[sanum++] = NULL; /* will hold the search base */
572
+ sargs[sanum++] = "-s";
573
+ sargs[sanum++] = NULL; /* will hold the search scope */
574
+ sargs[sanum++] = "-f";
575
+ sargs[sanum++] = NULL; /* will hold the search request */
576
+
577
+ sargs[sanum++] = NULL;
578
+ sargs[sanum++] = NULL; /* might hold the "attr" request */
579
+ sextra_args += 2;
580
+
581
+ sargs[sanum] = NULL;
582
+
583
+ /*
584
+ * generate the read clients
585
+ */
586
+
587
+ ranum = 0;
588
+ snprintf( rcmd, sizeof rcmd, "%s" LDAP_DIRSEP READCMD,
589
+ progdir );
590
+ rargs[ranum++] = rcmd;
591
+ if ( uri ) {
592
+ rargs[ranum++] = "-H";
593
+ rargs[ranum++] = uri;
594
+ } else {
595
+ rargs[ranum++] = "-h";
596
+ rargs[ranum++] = host;
597
+ rargs[ranum++] = "-p";
598
+ rargs[ranum++] = port;
599
+ }
600
+ rargs[ranum++] = "-D";
601
+ rargs[ranum++] = manager;
602
+ rargs[ranum++] = "-w";
603
+ rargs[ranum++] = passwd;
604
+ rargs[ranum++] = "-l";
605
+ rargs[ranum++] = rloops;
606
+ rargs[ranum++] = "-L";
607
+ rargs[ranum++] = outerloops;
608
+ rargs[ranum++] = "-r";
609
+ rargs[ranum++] = retries;
610
+ rargs[ranum++] = "-t";
611
+ rargs[ranum++] = delay;
612
+ if ( friendly ) {
613
+ rargs[ranum++] = friendlyOpt;
614
+ }
615
+ if ( chaserefs ) {
616
+ rargs[ranum++] = "-C";
617
+ }
618
+ if ( noattrs ) {
619
+ rargs[ranum++] = "-A";
620
+ }
621
+ if ( ignore ) {
622
+ rargs[ranum++] = "-i";
623
+ rargs[ranum++] = ignore;
624
+ }
625
+ if ( swamp ) {
626
+ rargs[ranum++] = swampopt;
627
+ }
628
+ rargs[ranum++] = "-e";
629
+ rargs[ranum++] = NULL; /* will hold the read entry */
630
+
631
+ rargs[ranum++] = NULL;
632
+ rargs[ranum++] = NULL; /* might hold the filter arg */
633
+ rextra_args += 2;
634
+
635
+ rargs[ranum] = NULL;
636
+
637
+ /*
638
+ * generate the modrdn clients
639
+ */
640
+
641
+ nanum = 0;
642
+ snprintf( ncmd, sizeof ncmd, "%s" LDAP_DIRSEP MODRDNCMD,
643
+ progdir );
644
+ nargs[nanum++] = ncmd;
645
+ if ( uri ) {
646
+ nargs[nanum++] = "-H";
647
+ nargs[nanum++] = uri;
648
+ } else {
649
+ nargs[nanum++] = "-h";
650
+ nargs[nanum++] = host;
651
+ nargs[nanum++] = "-p";
652
+ nargs[nanum++] = port;
653
+ }
654
+ nargs[nanum++] = "-D";
655
+ nargs[nanum++] = manager;
656
+ nargs[nanum++] = "-w";
657
+ nargs[nanum++] = passwd;
658
+ nargs[nanum++] = "-l";
659
+ nargs[nanum++] = nloops;
660
+ nargs[nanum++] = "-L";
661
+ nargs[nanum++] = outerloops;
662
+ nargs[nanum++] = "-r";
663
+ nargs[nanum++] = retries;
664
+ nargs[nanum++] = "-t";
665
+ nargs[nanum++] = delay;
666
+ if ( friendly ) {
667
+ nargs[nanum++] = friendlyOpt;
668
+ }
669
+ if ( chaserefs ) {
670
+ nargs[nanum++] = "-C";
671
+ }
672
+ if ( ignore ) {
673
+ nargs[nanum++] = "-i";
674
+ nargs[nanum++] = ignore;
675
+ }
676
+ nargs[nanum++] = "-e";
677
+ nargs[nanum++] = NULL; /* will hold the modrdn entry */
678
+ nargs[nanum] = NULL;
679
+
680
+ /*
681
+ * generate the modify clients
682
+ */
683
+
684
+ manum = 0;
685
+ snprintf( mcmd, sizeof mcmd, "%s" LDAP_DIRSEP MODIFYCMD,
686
+ progdir );
687
+ margs[manum++] = mcmd;
688
+ if ( uri ) {
689
+ margs[manum++] = "-H";
690
+ margs[manum++] = uri;
691
+ } else {
692
+ margs[manum++] = "-h";
693
+ margs[manum++] = host;
694
+ margs[manum++] = "-p";
695
+ margs[manum++] = port;
696
+ }
697
+ margs[manum++] = "-D";
698
+ margs[manum++] = manager;
699
+ margs[manum++] = "-w";
700
+ margs[manum++] = passwd;
701
+ margs[manum++] = "-l";
702
+ margs[manum++] = mloops;
703
+ margs[manum++] = "-L";
704
+ margs[manum++] = outerloops;
705
+ margs[manum++] = "-r";
706
+ margs[manum++] = retries;
707
+ margs[manum++] = "-t";
708
+ margs[manum++] = delay;
709
+ if ( friendly ) {
710
+ margs[manum++] = friendlyOpt;
711
+ }
712
+ if ( chaserefs ) {
713
+ margs[manum++] = "-C";
714
+ }
715
+ if ( ignore ) {
716
+ margs[manum++] = "-i";
717
+ margs[manum++] = ignore;
718
+ }
719
+ margs[manum++] = "-e";
720
+ margs[manum++] = NULL; /* will hold the modify entry */
721
+ margs[manum++] = "-a";;
722
+ margs[manum++] = NULL; /* will hold the ava */
723
+ margs[manum] = NULL;
724
+
725
+ /*
726
+ * generate the add/delete clients
727
+ */
728
+
729
+ aanum = 0;
730
+ snprintf( acmd, sizeof acmd, "%s" LDAP_DIRSEP ADDCMD,
731
+ progdir );
732
+ aargs[aanum++] = acmd;
733
+ if ( uri ) {
734
+ aargs[aanum++] = "-H";
735
+ aargs[aanum++] = uri;
736
+ } else {
737
+ aargs[aanum++] = "-h";
738
+ aargs[aanum++] = host;
739
+ aargs[aanum++] = "-p";
740
+ aargs[aanum++] = port;
741
+ }
742
+ aargs[aanum++] = "-D";
743
+ aargs[aanum++] = manager;
744
+ aargs[aanum++] = "-w";
745
+ aargs[aanum++] = passwd;
746
+ aargs[aanum++] = "-l";
747
+ aargs[aanum++] = aloops;
748
+ aargs[aanum++] = "-L";
749
+ aargs[aanum++] = outerloops;
750
+ aargs[aanum++] = "-r";
751
+ aargs[aanum++] = retries;
752
+ aargs[aanum++] = "-t";
753
+ aargs[aanum++] = delay;
754
+ if ( friendly ) {
755
+ aargs[aanum++] = friendlyOpt;
756
+ }
757
+ if ( chaserefs ) {
758
+ aargs[aanum++] = "-C";
759
+ }
760
+ if ( ignore ) {
761
+ aargs[aanum++] = "-i";
762
+ aargs[aanum++] = ignore;
763
+ }
764
+ aargs[aanum++] = "-f";
765
+ aargs[aanum++] = NULL; /* will hold the add data file */
766
+ aargs[aanum] = NULL;
767
+
768
+ /*
769
+ * generate the bind clients
770
+ */
771
+
772
+ banum = 0;
773
+ snprintf( bcmd, sizeof bcmd, "%s" LDAP_DIRSEP BINDCMD,
774
+ progdir );
775
+ bargs[banum++] = bcmd;
776
+ if ( !noinit ) {
777
+ bargs[banum++] = "-I"; /* init on each bind */
778
+ }
779
+ if ( uri ) {
780
+ bargs[banum++] = "-H";
781
+ bargs[banum++] = uri;
782
+ } else {
783
+ bargs[banum++] = "-h";
784
+ bargs[banum++] = host;
785
+ bargs[banum++] = "-p";
786
+ bargs[banum++] = port;
787
+ }
788
+ bargs[banum++] = "-l";
789
+ bargs[banum++] = bloops;
790
+ bargs[banum++] = "-L";
791
+ bargs[banum++] = outerloops;
792
+ #if 0
793
+ bargs[banum++] = "-r";
794
+ bargs[banum++] = retries;
795
+ bargs[banum++] = "-t";
796
+ bargs[banum++] = delay;
797
+ #endif
798
+ if ( friendly ) {
799
+ bargs[banum++] = friendlyOpt;
800
+ }
801
+ if ( chaserefs ) {
802
+ bargs[banum++] = "-C";
803
+ }
804
+ if ( ignore ) {
805
+ bargs[banum++] = "-i";
806
+ bargs[banum++] = ignore;
807
+ }
808
+ if ( nextra ) {
809
+ bargs[banum++] = "-B";
810
+ bargs_extra = &bargs[banum++];
811
+ }
812
+ bargs[banum++] = "-D";
813
+ bargs[banum++] = NULL;
814
+ bargs[banum++] = "-w";
815
+ bargs[banum++] = NULL;
816
+ bargs[banum] = NULL;
817
+
818
+ #define DOREQ(n,j) ((n) && ((maxkids > (n)) ? ((j) < maxkids ) : ((j) < (n))))
819
+
820
+ for ( j = 0; j < MAXREQS; j++ ) {
821
+ /* search */
822
+ if ( DOREQ( snum, j ) ) {
823
+ int jj = j % snum;
824
+ int x = sanum - sextra_args;
825
+
826
+ /* base */
827
+ if ( sbase[jj] != NULL ) {
828
+ sargs[sanum - 7] = sbase[jj];
829
+
830
+ } else {
831
+ sargs[sanum - 7] = slud[jj]->lud_dn;
832
+ }
833
+
834
+ /* scope */
835
+ if ( slud[jj] != NULL ) {
836
+ sargs[sanum - 5] = (char *)ldap_pvt_scope2str( slud[jj]->lud_scope );
837
+
838
+ } else {
839
+ sargs[sanum - 5] = "sub";
840
+ }
841
+
842
+ /* filter */
843
+ if ( sreqs[jj] != NULL ) {
844
+ sargs[sanum - 3] = sreqs[jj];
845
+
846
+ } else if ( slud[jj]->lud_filter != NULL ) {
847
+ sargs[sanum - 3] = slud[jj]->lud_filter;
848
+
849
+ } else {
850
+ sargs[sanum - 3] = "(objectClass=*)";
851
+ }
852
+
853
+ /* extras */
854
+ sargs[x] = NULL;
855
+
856
+ /* attr */
857
+ if ( sattrs[jj] != NULL ) {
858
+ sargs[x++] = "-a";
859
+ sargs[x++] = sattrs[jj];
860
+ }
861
+
862
+ /* attrs */
863
+ if ( slud[jj] != NULL && slud[jj]->lud_attrs != NULL ) {
864
+ int i;
865
+
866
+ for ( i = 0; slud[jj]->lud_attrs[ i ] != NULL && x + i < MAXARGS - 1; i++ ) {
867
+ sargs[x + i] = slud[jj]->lud_attrs[ i ];
868
+ }
869
+ sargs[x + i] = NULL;
870
+ }
871
+
872
+ fork_child( scmd, sargs );
873
+ }
874
+
875
+ /* read */
876
+ if ( DOREQ( rnum, j ) ) {
877
+ int jj = j % rnum;
878
+ int x = ranum - rextra_args;
879
+
880
+ rargs[ranum - 3] = rreqs[jj];
881
+ if ( rflts[jj] != NULL ) {
882
+ rargs[x++] = "-f";
883
+ rargs[x++] = rflts[jj];
884
+ }
885
+ rargs[x] = NULL;
886
+ fork_child( rcmd, rargs );
887
+ }
888
+
889
+ /* rename */
890
+ if ( j < nnum ) {
891
+ nargs[nanum - 1] = nreqs[j];
892
+ fork_child( ncmd, nargs );
893
+ }
894
+
895
+ /* modify */
896
+ if ( j < mnum ) {
897
+ margs[manum - 3] = mdn[j];
898
+ margs[manum - 1] = mreqs[j];
899
+ fork_child( mcmd, margs );
900
+ }
901
+
902
+ /* add/delete */
903
+ if ( j < anum ) {
904
+ aargs[aanum - 1] = afiles[j];
905
+ fork_child( acmd, aargs );
906
+ }
907
+
908
+ /* bind */
909
+ if ( DOREQ( bnum, j ) ) {
910
+ int jj = j % bnum;
911
+
912
+ if ( nextra ) {
913
+ int n = ((double)nextra)*rand()/(RAND_MAX + 1.0);
914
+ extra_t *e;
915
+
916
+ for ( e = extra; n-- > 0; e = e->next )
917
+ ;
918
+ *bargs_extra = e->action;
919
+ }
920
+
921
+ if ( battrs[jj] != NULL ) {
922
+ bargs[banum - 3] = manager ? manager : "";
923
+ bargs[banum - 1] = passwd ? passwd : "";
924
+
925
+ bargs[banum + 0] = "-b";
926
+ bargs[banum + 1] = breqs[jj];
927
+ bargs[banum + 2] = "-f";
928
+ bargs[banum + 3] = bcreds[jj];
929
+ bargs[banum + 4] = "-a";
930
+ bargs[banum + 5] = battrs[jj];
931
+ bargs[banum + 6] = NULL;
932
+
933
+ } else {
934
+ bargs[banum - 3] = breqs[jj];
935
+ bargs[banum - 1] = bcreds[jj];
936
+ bargs[banum] = NULL;
937
+ }
938
+
939
+ fork_child( bcmd, bargs );
940
+ bargs[banum] = NULL;
941
+ }
942
+ }
943
+
944
+ wait4kids( -1 );
945
+
946
+ exit( EXIT_SUCCESS );
947
+ }
948
+
949
+ static char *
950
+ get_file_name( char *dirname, char *filename )
951
+ {
952
+ char buf[MAXPATHLEN];
953
+
954
+ snprintf( buf, sizeof buf, "%s" LDAP_DIRSEP "%s",
955
+ dirname, filename );
956
+ return( strdup( buf ));
957
+ }
958
+
959
+
960
+ static int
961
+ get_search_filters( char *filename, char *filters[], char *attrs[], char *bases[], LDAPURLDesc *luds[] )
962
+ {
963
+ FILE *fp;
964
+ int filter = 0;
965
+
966
+ if ( (fp = fopen( filename, "r" )) != NULL ) {
967
+ char line[BUFSIZ];
968
+
969
+ while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
970
+ char *nl;
971
+ int got_URL = 0;
972
+
973
+ if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
974
+ *nl = '\0';
975
+
976
+ if ( luds ) luds[filter] = NULL;
977
+
978
+ if ( luds && strncmp( line, "ldap:///", STRLENOF( "ldap:///" ) ) == 0 ) {
979
+ LDAPURLDesc *lud;
980
+
981
+ got_URL = 1;
982
+ bases[filter] = NULL;
983
+ if ( ldap_url_parse( line, &lud ) != LDAP_URL_SUCCESS ) {
984
+ filter = -filter - 1;
985
+ break;
986
+ }
987
+
988
+ if ( lud->lud_dn == NULL || lud->lud_exts != NULL ) {
989
+ filter = -filter - 1;
990
+ ldap_free_urldesc( lud );
991
+ break;
992
+ }
993
+
994
+ luds[filter] = lud;
995
+
996
+ } else {
997
+ bases[filter] = ArgDup( line );
998
+ }
999
+ if ( fgets( line, BUFSIZ, fp ) == NULL )
1000
+ *line = '\0';
1001
+ if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
1002
+ *nl = '\0';
1003
+
1004
+ filters[filter] = ArgDup( line );
1005
+ if ( attrs ) {
1006
+ if ( filters[filter][0] == '+') {
1007
+ char *sep = strchr( filters[filter], ':' );
1008
+
1009
+ attrs[ filter ] = &filters[ filter ][ 1 ];
1010
+ if ( sep != NULL ) {
1011
+ sep[ 0 ] = '\0';
1012
+ /* NOTE: don't free this! */
1013
+ filters[ filter ] = &sep[ 1 ];
1014
+ }
1015
+
1016
+ } else {
1017
+ attrs[ filter ] = NULL;
1018
+ }
1019
+ }
1020
+ filter++;
1021
+
1022
+ }
1023
+ fclose( fp );
1024
+ }
1025
+
1026
+ return filter;
1027
+ }
1028
+
1029
+
1030
+ static int
1031
+ get_read_entries( char *filename, char *entries[], char *filters[] )
1032
+ {
1033
+ FILE *fp;
1034
+ int entry = 0;
1035
+
1036
+ if ( (fp = fopen( filename, "r" )) != NULL ) {
1037
+ char line[BUFSIZ];
1038
+
1039
+ while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
1040
+ char *nl;
1041
+
1042
+ if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
1043
+ *nl = '\0';
1044
+ if ( filters != NULL && line[0] == '+' ) {
1045
+ LDAPURLDesc *lud;
1046
+
1047
+ if ( ldap_url_parse( &line[1], &lud ) != LDAP_URL_SUCCESS ) {
1048
+ entry = -entry - 1;
1049
+ break;
1050
+ }
1051
+
1052
+ if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
1053
+ ldap_free_urldesc( lud );
1054
+ entry = -entry - 1;
1055
+ break;
1056
+ }
1057
+
1058
+ entries[entry] = ArgDup( lud->lud_dn );
1059
+
1060
+ if ( lud->lud_filter ) {
1061
+ filters[entry] = ArgDup( lud->lud_filter );
1062
+
1063
+ } else {
1064
+ filters[entry] = ArgDup( "(objectClass=*)" );
1065
+ }
1066
+ ldap_free_urldesc( lud );
1067
+
1068
+ } else {
1069
+ if ( filters != NULL )
1070
+ filters[entry] = NULL;
1071
+
1072
+ entries[entry] = ArgDup( line );
1073
+ }
1074
+
1075
+ entry++;
1076
+
1077
+ }
1078
+ fclose( fp );
1079
+ }
1080
+
1081
+ return( entry );
1082
+ }
1083
+
1084
+ #ifndef HAVE_WINSOCK
1085
+ static void
1086
+ fork_child( char *prog, char **args )
1087
+ {
1088
+ /* note: obscures global pid var; intended */
1089
+ pid_t pid;
1090
+
1091
+ wait4kids( maxkids );
1092
+
1093
+ switch ( pid = fork() ) {
1094
+ case 0: /* child */
1095
+ #ifdef HAVE_EBCDIC
1096
+ /* The __LIBASCII execvp only handles ASCII "prog",
1097
+ * we still need to translate the arg vec ourselves.
1098
+ */
1099
+ { char *arg2[MAXREQS];
1100
+ int i;
1101
+
1102
+ for (i=0; args[i]; i++) {
1103
+ arg2[i] = ArgDup(args[i]);
1104
+ __atoe(arg2[i]);
1105
+ }
1106
+ arg2[i] = NULL;
1107
+ args = arg2; }
1108
+ #endif
1109
+ execvp( prog, args );
1110
+ tester_perror( "execvp", NULL );
1111
+ { int i;
1112
+ for (i=0; args[i]; i++);
1113
+ fprintf(stderr,"%d args\n", i);
1114
+ for (i=0; args[i]; i++)
1115
+ fprintf(stderr,"%d %s\n", i, args[i]);
1116
+ }
1117
+
1118
+ exit( EXIT_FAILURE );
1119
+ break;
1120
+
1121
+ case -1: /* trouble */
1122
+ tester_perror( "fork", NULL );
1123
+ break;
1124
+
1125
+ default: /* parent */
1126
+ nkids++;
1127
+ break;
1128
+ }
1129
+ }
1130
+
1131
+ static void
1132
+ wait4kids( int nkidval )
1133
+ {
1134
+ int status;
1135
+
1136
+ while ( nkids >= nkidval ) {
1137
+ pid_t pid = wait( &status );
1138
+
1139
+ if ( WIFSTOPPED(status) ) {
1140
+ fprintf( stderr,
1141
+ "stopping: child PID=%ld stopped with signal %d\n",
1142
+ (long) pid, (int) WSTOPSIG(status) );
1143
+
1144
+ } else if ( WIFSIGNALED(status) ) {
1145
+ fprintf( stderr,
1146
+ "stopping: child PID=%ld terminated with signal %d%s\n",
1147
+ (long) pid, (int) WTERMSIG(status),
1148
+ #ifdef WCOREDUMP
1149
+ WCOREDUMP(status) ? ", core dumped" : ""
1150
+ #else
1151
+ ""
1152
+ #endif
1153
+ );
1154
+ exit( WEXITSTATUS(status) );
1155
+
1156
+ } else if ( WEXITSTATUS(status) != 0 ) {
1157
+ fprintf( stderr,
1158
+ "stopping: child PID=%ld exited with status %d\n",
1159
+ (long) pid, (int) WEXITSTATUS(status) );
1160
+ exit( WEXITSTATUS(status) );
1161
+
1162
+ } else {
1163
+ nkids--;
1164
+ }
1165
+ }
1166
+ }
1167
+ #else
1168
+
1169
+ static void
1170
+ wait4kids( int nkidval )
1171
+ {
1172
+ int rc, i;
1173
+
1174
+ while ( nkids >= nkidval ) {
1175
+ rc = WaitForMultipleObjects( nkids, children, FALSE, INFINITE );
1176
+ for ( i=rc - WAIT_OBJECT_0; i<nkids-1; i++)
1177
+ children[i] = children[i+1];
1178
+ nkids--;
1179
+ }
1180
+ }
1181
+
1182
+ static void
1183
+ fork_child( char *prog, char **args )
1184
+ {
1185
+ int rc;
1186
+
1187
+ wait4kids( maxkids );
1188
+
1189
+ rc = _spawnvp( _P_NOWAIT, prog, args );
1190
+
1191
+ if ( rc == -1 ) {
1192
+ tester_perror( "_spawnvp", NULL );
1193
+ } else {
1194
+ children[nkids++] = (HANDLE)rc;
1195
+ }
1196
+ }
1197
+ #endif