ruby-ldap 0.9.18 → 0.9.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -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