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,310 @@
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 Howard Chu, based in part
17
+ * on other OpenLDAP test tools, for inclusion 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 "slapd-common.h"
37
+
38
+ #define LOOPS 100
39
+ #define RETRIES 0
40
+
41
+ static void
42
+ do_modrdn( char *uri, char *manager, struct berval *passwd,
43
+ char *entry, int maxloop, int maxretries, int delay,
44
+ int friendly, int chaserefs );
45
+
46
+ static void
47
+ usage( char *name )
48
+ {
49
+ fprintf( stderr,
50
+ "usage: %s "
51
+ "-H <uri> | ([-h <host>] -p <port>) "
52
+ "-D <manager> "
53
+ "-w <passwd> "
54
+ "-e <entry> "
55
+ "[-i <ignore>] "
56
+ "[-l <loops>] "
57
+ "[-L <outerloops>] "
58
+ "[-r <maxretries>] "
59
+ "[-t <delay>] "
60
+ "[-F] "
61
+ "[-C]\n",
62
+ name );
63
+ exit( EXIT_FAILURE );
64
+ }
65
+
66
+ int
67
+ main( int argc, char **argv )
68
+ {
69
+ int i;
70
+ char *uri = NULL;
71
+ char *host = "localhost";
72
+ int port = -1;
73
+ char *manager = NULL;
74
+ struct berval passwd = { 0, NULL };
75
+ char *entry = NULL;
76
+ int loops = LOOPS;
77
+ int outerloops = 1;
78
+ int retries = RETRIES;
79
+ int delay = 0;
80
+ int friendly = 0;
81
+ int chaserefs = 0;
82
+
83
+ tester_init( "slapd-modrdn", TESTER_MODRDN );
84
+
85
+ while ( ( i = getopt( argc, argv, "CD:e:FH:h:i:L:l:p:r:t:w:" ) ) != EOF )
86
+ {
87
+ switch ( i ) {
88
+ case 'C':
89
+ chaserefs++;
90
+ break;
91
+
92
+ case 'F':
93
+ friendly++;
94
+ break;
95
+
96
+ case 'H': /* the server uri */
97
+ uri = strdup( optarg );
98
+ break;
99
+
100
+ case 'h': /* the servers host */
101
+ host = strdup( optarg );
102
+ break;
103
+
104
+ case 'i':
105
+ /* ignored (!) by now */
106
+ break;
107
+
108
+ case 'p': /* the servers port */
109
+ if ( lutil_atoi( &port, optarg ) != 0 ) {
110
+ usage( argv[0] );
111
+ }
112
+ break;
113
+
114
+ case 'D': /* the servers manager */
115
+ manager = strdup( optarg );
116
+ break;
117
+
118
+ case 'w': /* the server managers password */
119
+ passwd.bv_val = strdup( optarg );
120
+ passwd.bv_len = strlen( optarg );
121
+ memset( optarg, '*', passwd.bv_len );
122
+ break;
123
+
124
+ case 'e': /* entry to rename */
125
+ entry = strdup( optarg );
126
+ break;
127
+
128
+ case 'l': /* the number of loops */
129
+ if ( lutil_atoi( &loops, optarg ) != 0 ) {
130
+ usage( argv[0] );
131
+ }
132
+ break;
133
+
134
+ case 'L': /* the number of outerloops */
135
+ if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
136
+ usage( argv[0] );
137
+ }
138
+ break;
139
+
140
+ case 'r': /* the number of retries */
141
+ if ( lutil_atoi( &retries, optarg ) != 0 ) {
142
+ usage( argv[0] );
143
+ }
144
+ break;
145
+
146
+ case 't': /* delay in seconds */
147
+ if ( lutil_atoi( &delay, optarg ) != 0 ) {
148
+ usage( argv[0] );
149
+ }
150
+ break;
151
+
152
+ default:
153
+ usage( argv[0] );
154
+ break;
155
+ }
156
+ }
157
+
158
+ if (( entry == NULL ) || ( port == -1 && uri == NULL ))
159
+ usage( argv[0] );
160
+
161
+ if ( *entry == '\0' ) {
162
+
163
+ fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
164
+ argv[0] );
165
+ exit( EXIT_FAILURE );
166
+
167
+ }
168
+
169
+ uri = tester_uri( uri, host, port );
170
+
171
+ for ( i = 0; i < outerloops; i++ ) {
172
+ do_modrdn( uri, manager, &passwd, entry,
173
+ loops, retries, delay, friendly, chaserefs );
174
+ }
175
+
176
+ exit( EXIT_SUCCESS );
177
+ }
178
+
179
+
180
+ static void
181
+ do_modrdn( char *uri, char *manager,
182
+ struct berval *passwd, char *entry, int maxloop, int maxretries,
183
+ int delay, int friendly, int chaserefs )
184
+ {
185
+ LDAP *ld = NULL;
186
+ int i, do_retry = maxretries;
187
+ char *DNs[2];
188
+ char *rdns[2];
189
+ int rc = LDAP_SUCCESS;
190
+ char *p1, *p2;
191
+ int version = LDAP_VERSION3;
192
+
193
+ DNs[0] = entry;
194
+ DNs[1] = strdup( entry );
195
+
196
+ /* reverse the RDN, make new DN */
197
+ p1 = strchr( entry, '=' ) + 1;
198
+ p2 = strchr( p1, ',' );
199
+
200
+ *p2 = '\0';
201
+ rdns[1] = strdup( entry );
202
+ *p2-- = ',';
203
+
204
+ for (i = p1 - entry;p2 >= p1;)
205
+ DNs[1][i++] = *p2--;
206
+
207
+ DNs[1][i] = '\0';
208
+ rdns[0] = strdup( DNs[1] );
209
+ DNs[1][i] = ',';
210
+
211
+ i = 0;
212
+
213
+ retry:;
214
+ ldap_initialize( &ld, uri );
215
+ if ( ld == NULL ) {
216
+ tester_perror( "ldap_initialize", NULL );
217
+ exit( EXIT_FAILURE );
218
+ }
219
+
220
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
221
+ (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
222
+ chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
223
+
224
+ if ( do_retry == maxretries ) {
225
+ fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
226
+ (long) pid, maxloop, entry );
227
+ }
228
+
229
+ rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
230
+ if ( rc != LDAP_SUCCESS ) {
231
+ tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
232
+ switch ( rc ) {
233
+ case LDAP_BUSY:
234
+ case LDAP_UNAVAILABLE:
235
+ if ( do_retry > 0 ) {
236
+ do_retry--;
237
+ if ( delay > 0) {
238
+ sleep( delay );
239
+ }
240
+ goto retry;
241
+ }
242
+ /* fallthru */
243
+ default:
244
+ break;
245
+ }
246
+ exit( EXIT_FAILURE );
247
+ }
248
+
249
+ for ( ; i < maxloop; i++ ) {
250
+ rc = ldap_rename_s( ld, DNs[0], rdns[0], NULL, 0, NULL, NULL );
251
+ if ( rc != LDAP_SUCCESS ) {
252
+ tester_ldap_error( ld, "ldap_rename_s", NULL );
253
+ switch ( rc ) {
254
+ case LDAP_NO_SUCH_OBJECT:
255
+ /* NOTE: this likely means
256
+ * the second modrdn failed
257
+ * during the previous round... */
258
+ if ( !friendly ) {
259
+ goto done;
260
+ }
261
+ break;
262
+
263
+ case LDAP_BUSY:
264
+ case LDAP_UNAVAILABLE:
265
+ if ( do_retry > 0 ) {
266
+ do_retry--;
267
+ goto retry;
268
+ }
269
+ /* fall thru */
270
+
271
+ default:
272
+ goto done;
273
+ }
274
+ }
275
+ rc = ldap_rename_s( ld, DNs[1], rdns[1], NULL, 1, NULL, NULL );
276
+ if ( rc != LDAP_SUCCESS ) {
277
+ tester_ldap_error( ld, "ldap_rename_s", NULL );
278
+ switch ( rc ) {
279
+ case LDAP_NO_SUCH_OBJECT:
280
+ /* NOTE: this likely means
281
+ * the first modrdn failed
282
+ * during the previous round... */
283
+ if ( !friendly ) {
284
+ goto done;
285
+ }
286
+ break;
287
+
288
+ case LDAP_BUSY:
289
+ case LDAP_UNAVAILABLE:
290
+ if ( do_retry > 0 ) {
291
+ do_retry--;
292
+ goto retry;
293
+ }
294
+ /* fall thru */
295
+
296
+ default:
297
+ goto done;
298
+ }
299
+ }
300
+ }
301
+
302
+ done:;
303
+ fprintf( stderr, " PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
304
+
305
+ ldap_unbind_ext( ld, NULL, NULL );
306
+
307
+ free( DNs[1] );
308
+ free( rdns[0] );
309
+ free( rdns[1] );
310
+ }
@@ -0,0 +1,837 @@
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
+ /*
21
+ * This tool is a MT reader. It behaves like slapd-read however
22
+ * with one or more threads simultaneously using the same connection.
23
+ * If -M is enabled, then M threads will also perform write operations.
24
+ */
25
+
26
+ #include "portable.h"
27
+
28
+ #include <stdio.h>
29
+ #include "ldap_pvt_thread.h"
30
+
31
+ #include "ac/stdlib.h"
32
+
33
+ #include "ac/ctype.h"
34
+ #include "ac/param.h"
35
+ #include "ac/socket.h"
36
+ #include "ac/string.h"
37
+ #include "ac/unistd.h"
38
+ #include "ac/wait.h"
39
+
40
+ #include "ldap.h"
41
+ #include "lutil.h"
42
+
43
+ #include "ldap_pvt.h"
44
+
45
+ #include "slapd-common.h"
46
+
47
+ #define MAXCONN 512
48
+ #define LOOPS 100
49
+ #define RETRIES 0
50
+ #define DEFAULT_BASE "ou=people,dc=example,dc=com"
51
+
52
+ static void
53
+ do_conn( char *uri, char *manager, struct berval *passwd,
54
+ LDAP **ld, int nobind, int maxretries, int conn_num );
55
+
56
+ static void
57
+ do_read( LDAP *ld, char *entry,
58
+ char **attrs, int noattrs, int nobind, int maxloop,
59
+ int maxretries, int delay, int force, int chaserefs, int idx );
60
+
61
+ static void
62
+ do_random( LDAP *ld,
63
+ char *sbase, char *filter, char **attrs, int noattrs, int nobind,
64
+ int innerloop, int maxretries, int delay, int force, int chaserefs,
65
+ int idx );
66
+
67
+ static void
68
+ do_random2( LDAP *ld,
69
+ char *sbase, char *filter, char **attrs, int noattrs, int nobind,
70
+ int innerloop, int maxretries, int delay, int force, int chaserefs,
71
+ int idx );
72
+
73
+ static void *
74
+ do_onethread( void *arg );
75
+
76
+ static void *
77
+ do_onerwthread( void *arg );
78
+
79
+ #define MAX_THREAD 1024
80
+ /* Use same array for readers and writers, offset writers by MAX_THREAD */
81
+ int rt_pass[MAX_THREAD*2];
82
+ int rt_fail[MAX_THREAD*2];
83
+ int *rwt_pass = rt_pass + MAX_THREAD;
84
+ int *rwt_fail = rt_fail + MAX_THREAD;
85
+ ldap_pvt_thread_t rtid[MAX_THREAD*2], *rwtid = rtid + MAX_THREAD;
86
+
87
+ /*
88
+ * Shared globals (command line args)
89
+ */
90
+ LDAP *ld = NULL;
91
+ char *entry = NULL;
92
+ char *filter = NULL;
93
+ int loops = LOOPS;
94
+ int outerloops = 1;
95
+ int retries = RETRIES;
96
+ int delay = 0;
97
+ int force = 0;
98
+ int chaserefs = 0;
99
+ char *srchattrs[] = { "1.1", NULL };
100
+ char **attrs = srchattrs;
101
+ int noattrs = 0;
102
+ int nobind = 0;
103
+ int threads = 1;
104
+ int rwthreads = 0;
105
+ int verbose = 0;
106
+
107
+ int noconns = 1;
108
+ LDAP **lds = NULL;
109
+
110
+ static void
111
+ thread_error(int idx, char *string)
112
+ {
113
+ char thrstr[BUFSIZ];
114
+
115
+ snprintf(thrstr, BUFSIZ, "error on tidx: %d: %s", idx, string);
116
+ tester_error( thrstr );
117
+ }
118
+
119
+ static void
120
+ thread_output(int idx, char *string)
121
+ {
122
+ char thrstr[BUFSIZ];
123
+
124
+ snprintf(thrstr, BUFSIZ, "tidx: %d says: %s", idx, string);
125
+ tester_error( thrstr );
126
+ }
127
+
128
+ static void
129
+ thread_verbose(int idx, char *string)
130
+ {
131
+ char thrstr[BUFSIZ];
132
+
133
+ if (!verbose)
134
+ return;
135
+ snprintf(thrstr, BUFSIZ, "tidx: %d says: %s", idx, string);
136
+ tester_error( thrstr );
137
+ }
138
+
139
+ static void
140
+ usage( char *name )
141
+ {
142
+ fprintf( stderr,
143
+ "usage: %s "
144
+ "-H <uri> | ([-h <host>] -p <port>) "
145
+ "-D <manager> "
146
+ "-w <passwd> "
147
+ "-e <entry> "
148
+ "[-A] "
149
+ "[-C] "
150
+ "[-F] "
151
+ "[-N] "
152
+ "[-v] "
153
+ "[-c connections] "
154
+ "[-f filter] "
155
+ "[-i <ignore>] "
156
+ "[-l <loops>] "
157
+ "[-L <outerloops>] "
158
+ "[-m threads] "
159
+ "[-M threads] "
160
+ "[-r <maxretries>] "
161
+ "[-t <delay>] "
162
+ "[-T <attrs>] "
163
+ "[<attrs>] "
164
+ "\n",
165
+ name );
166
+ exit( EXIT_FAILURE );
167
+ }
168
+
169
+ int
170
+ main( int argc, char **argv )
171
+ {
172
+ int i;
173
+ char *uri = NULL;
174
+ char *host = "localhost";
175
+ int port = -1;
176
+ char *manager = NULL;
177
+ struct berval passwd = { 0, NULL };
178
+ char outstr[BUFSIZ];
179
+ int ptpass;
180
+ int testfail = 0;
181
+
182
+
183
+ tester_init( "slapd-mtread", TESTER_READ );
184
+
185
+ /* by default, tolerate referrals and no such object */
186
+ tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
187
+
188
+ while ( (i = getopt( argc, argv, "ACc:D:e:Ff:H:h:i:L:l:M:m:Np:r:t:T:w:v" )) != EOF ) {
189
+ switch ( i ) {
190
+ case 'A':
191
+ noattrs++;
192
+ break;
193
+
194
+ case 'C':
195
+ chaserefs++;
196
+ break;
197
+
198
+ case 'H': /* the server uri */
199
+ uri = strdup( optarg );
200
+ break;
201
+
202
+ case 'h': /* the servers host */
203
+ host = strdup( optarg );
204
+ break;
205
+
206
+ case 'i':
207
+ tester_ignore_str2errlist( optarg );
208
+ break;
209
+
210
+ case 'N':
211
+ nobind++;
212
+ break;
213
+
214
+ case 'v':
215
+ verbose++;
216
+ break;
217
+
218
+ case 'p': /* the servers port */
219
+ if ( lutil_atoi( &port, optarg ) != 0 ) {
220
+ usage( argv[0] );
221
+ }
222
+ break;
223
+
224
+ case 'D': /* the servers manager */
225
+ manager = strdup( optarg );
226
+ break;
227
+
228
+ case 'w': /* the server managers password */
229
+ passwd.bv_val = strdup( optarg );
230
+ passwd.bv_len = strlen( optarg );
231
+ memset( optarg, '*', passwd.bv_len );
232
+ break;
233
+
234
+ case 'c': /* the number of connections */
235
+ if ( lutil_atoi( &noconns, optarg ) != 0 ) {
236
+ usage( argv[0] );
237
+ }
238
+ break;
239
+
240
+ case 'e': /* DN to search for */
241
+ entry = strdup( optarg );
242
+ break;
243
+
244
+ case 'f': /* the search request */
245
+ filter = strdup( optarg );
246
+ break;
247
+
248
+ case 'F':
249
+ force++;
250
+ break;
251
+
252
+ case 'l': /* the number of loops */
253
+ if ( lutil_atoi( &loops, optarg ) != 0 ) {
254
+ usage( argv[0] );
255
+ }
256
+ break;
257
+
258
+ case 'L': /* the number of outerloops */
259
+ if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
260
+ usage( argv[0] );
261
+ }
262
+ break;
263
+
264
+ case 'M': /* the number of R/W threads */
265
+ if ( lutil_atoi( &rwthreads, optarg ) != 0 ) {
266
+ usage( argv[0] );
267
+ }
268
+ if (rwthreads > MAX_THREAD)
269
+ rwthreads = MAX_THREAD;
270
+ break;
271
+
272
+ case 'm': /* the number of threads */
273
+ if ( lutil_atoi( &threads, optarg ) != 0 ) {
274
+ usage( argv[0] );
275
+ }
276
+ if (threads > MAX_THREAD)
277
+ threads = MAX_THREAD;
278
+ break;
279
+
280
+ case 'r': /* the number of retries */
281
+ if ( lutil_atoi( &retries, optarg ) != 0 ) {
282
+ usage( argv[0] );
283
+ }
284
+ break;
285
+
286
+ case 't': /* delay in seconds */
287
+ if ( lutil_atoi( &delay, optarg ) != 0 ) {
288
+ usage( argv[0] );
289
+ }
290
+ break;
291
+
292
+ case 'T':
293
+ attrs = ldap_str2charray( optarg, "," );
294
+ if ( attrs == NULL ) {
295
+ usage( argv[0] );
296
+ }
297
+ break;
298
+
299
+ default:
300
+ usage( argv[0] );
301
+ break;
302
+ }
303
+ }
304
+
305
+ if (( entry == NULL ) || ( port == -1 && uri == NULL ))
306
+ usage( argv[0] );
307
+
308
+ if ( *entry == '\0' ) {
309
+ fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
310
+ argv[0] );
311
+ exit( EXIT_FAILURE );
312
+ }
313
+
314
+ if ( argv[optind] != NULL ) {
315
+ attrs = &argv[optind];
316
+ }
317
+
318
+ if (noconns < 1)
319
+ noconns = 1;
320
+ if (noconns > MAXCONN)
321
+ noconns = MAXCONN;
322
+ lds = (LDAP **) calloc( sizeof(LDAP *), noconns);
323
+ if (lds == NULL) {
324
+ fprintf( stderr, "%s: Memory error: calloc noconns.\n",
325
+ argv[0] );
326
+ exit( EXIT_FAILURE );
327
+ }
328
+
329
+ uri = tester_uri( uri, host, port );
330
+ /* One connection and one connection only */
331
+ do_conn( uri, manager, &passwd, &ld, nobind, retries, 0 );
332
+ lds[0] = ld;
333
+ for(i = 1; i < noconns; i++) {
334
+ do_conn( uri, manager, &passwd, &lds[i], nobind, retries, i );
335
+ }
336
+
337
+ ldap_pvt_thread_initialize();
338
+
339
+ snprintf(outstr, BUFSIZ, "MT Test Start: conns: %d (%s)", noconns, uri);
340
+ tester_error(outstr);
341
+ snprintf(outstr, BUFSIZ, "Threads: RO: %d RW: %d", threads, rwthreads);
342
+ tester_error(outstr);
343
+
344
+ /* Set up read only threads */
345
+ for ( i = 0; i < threads; i++ ) {
346
+ ldap_pvt_thread_create( &rtid[i], 0, do_onethread, &rtid[i]);
347
+ snprintf(outstr, BUFSIZ, "Created RO thread %d", i);
348
+ thread_verbose(-1, outstr);
349
+ }
350
+ /* Set up read/write threads */
351
+ for ( i = 0; i < rwthreads; i++ ) {
352
+ ldap_pvt_thread_create( &rwtid[i], 0, do_onerwthread, &rwtid[i]);
353
+ snprintf(outstr, BUFSIZ, "Created RW thread %d", i + MAX_THREAD);
354
+ thread_verbose(-1, outstr);
355
+ }
356
+
357
+ ptpass = outerloops * loops;
358
+
359
+ /* wait for read only threads to complete */
360
+ for ( i = 0; i < threads; i++ )
361
+ ldap_pvt_thread_join(rtid[i], NULL);
362
+ /* wait for read/write threads to complete */
363
+ for ( i = 0; i < rwthreads; i++ )
364
+ ldap_pvt_thread_join(rwtid[i], NULL);
365
+
366
+ for(i = 0; i < noconns; i++) {
367
+ if ( lds[i] != NULL ) {
368
+ ldap_unbind_ext( lds[i], NULL, NULL );
369
+ }
370
+ }
371
+ free( lds );
372
+
373
+ for ( i = 0; i < threads; i++ ) {
374
+ snprintf(outstr, BUFSIZ, "RO thread %d pass=%d fail=%d", i,
375
+ rt_pass[i], rt_fail[i]);
376
+ tester_error(outstr);
377
+ if (rt_fail[i] != 0 || rt_pass[i] != ptpass) {
378
+ snprintf(outstr, BUFSIZ, "FAIL RO thread %d", i);
379
+ tester_error(outstr);
380
+ testfail++;
381
+ }
382
+ }
383
+ for ( i = 0; i < rwthreads; i++ ) {
384
+ snprintf(outstr, BUFSIZ, "RW thread %d pass=%d fail=%d", i + MAX_THREAD,
385
+ rwt_pass[i], rwt_fail[i]);
386
+ tester_error(outstr);
387
+ if (rwt_fail[i] != 0 || rwt_pass[i] != ptpass) {
388
+ snprintf(outstr, BUFSIZ, "FAIL RW thread %d", i);
389
+ tester_error(outstr);
390
+ testfail++;
391
+ }
392
+ }
393
+ snprintf(outstr, BUFSIZ, "MT Test complete" );
394
+ tester_error(outstr);
395
+
396
+ if (testfail)
397
+ exit( EXIT_FAILURE );
398
+ exit( EXIT_SUCCESS );
399
+ }
400
+
401
+ static void *
402
+ do_onethread( void *arg )
403
+ {
404
+ int i, j, thisconn;
405
+ LDAP **mlds;
406
+ char thrstr[BUFSIZ];
407
+ int rc, refcnt = 0;
408
+ int idx = (ldap_pvt_thread_t *)arg - rtid;
409
+
410
+ mlds = (LDAP **) calloc( sizeof(LDAP *), noconns);
411
+ if (mlds == NULL) {
412
+ thread_error( idx, "Memory error: thread calloc for noconns" );
413
+ exit( EXIT_FAILURE );
414
+ }
415
+
416
+ for ( j = 0; j < outerloops; j++ ) {
417
+ for(i = 0; i < noconns; i++) {
418
+ mlds[i] = ldap_dup(lds[i]);
419
+ if (mlds[i] == NULL) {
420
+ thread_error( idx, "ldap_dup error" );
421
+ }
422
+ }
423
+ rc = ldap_get_option(mlds[0], LDAP_OPT_SESSION_REFCNT, &refcnt);
424
+ snprintf(thrstr, BUFSIZ,
425
+ "RO Thread conns: %d refcnt: %d (rc = %d)",
426
+ noconns, refcnt, rc);
427
+ thread_verbose(idx, thrstr);
428
+
429
+ thisconn = (idx + j) % noconns;
430
+ if (thisconn < 0 || thisconn >= noconns)
431
+ thisconn = 0;
432
+ if (mlds[thisconn] == NULL) {
433
+ thread_error( idx, "(failed to dup)");
434
+ tester_perror( "ldap_dup", "(failed to dup)" );
435
+ exit( EXIT_FAILURE );
436
+ }
437
+ snprintf(thrstr, BUFSIZ, "Using conn %d", thisconn);
438
+ thread_verbose(idx, thrstr);
439
+ if ( filter != NULL ) {
440
+ if (strchr(filter, '['))
441
+ do_random2( mlds[thisconn], entry, filter, attrs,
442
+ noattrs, nobind, loops, retries, delay, force,
443
+ chaserefs, idx );
444
+ else
445
+ do_random( mlds[thisconn], entry, filter, attrs,
446
+ noattrs, nobind, loops, retries, delay, force,
447
+ chaserefs, idx );
448
+
449
+ } else {
450
+ do_read( mlds[thisconn], entry, attrs,
451
+ noattrs, nobind, loops, retries, delay, force,
452
+ chaserefs, idx );
453
+ }
454
+ for(i = 0; i < noconns; i++) {
455
+ (void) ldap_destroy(mlds[i]);
456
+ mlds[i] = NULL;
457
+ }
458
+ }
459
+ free( mlds );
460
+ return( NULL );
461
+ }
462
+
463
+ static void *
464
+ do_onerwthread( void *arg )
465
+ {
466
+ int i, j, thisconn;
467
+ LDAP **mlds, *ld;
468
+ char thrstr[BUFSIZ];
469
+ char dn[256], uids[32], cns[32], *base;
470
+ LDAPMod *attrp[5], attrs[4];
471
+ char *oc_vals[] = { "top", "OpenLDAPperson", NULL };
472
+ char *cn_vals[] = { NULL, NULL };
473
+ char *sn_vals[] = { NULL, NULL };
474
+ char *uid_vals[] = { NULL, NULL };
475
+ int ret;
476
+ int adds = 0;
477
+ int dels = 0;
478
+ int rc, refcnt = 0;
479
+ int idx = (ldap_pvt_thread_t *)arg - rtid;
480
+
481
+ mlds = (LDAP **) calloc( sizeof(LDAP *), noconns);
482
+ if (mlds == NULL) {
483
+ thread_error( idx, "Memory error: thread calloc for noconns" );
484
+ exit( EXIT_FAILURE );
485
+ }
486
+
487
+ snprintf(uids, sizeof(uids), "rwtest%04d", idx);
488
+ snprintf(cns, sizeof(cns), "rwtest%04d", idx);
489
+ /* add setup */
490
+ for (i = 0; i < 4; i++) {
491
+ attrp[i] = &attrs[i];
492
+ attrs[i].mod_op = 0;
493
+ }
494
+ attrp[4] = NULL;
495
+ attrs[0].mod_type = "objectClass";
496
+ attrs[0].mod_values = oc_vals;
497
+ attrs[1].mod_type = "cn";
498
+ attrs[1].mod_values = cn_vals;
499
+ cn_vals[0] = &cns[0];
500
+ attrs[2].mod_type = "sn";
501
+ attrs[2].mod_values = sn_vals;
502
+ sn_vals[0] = &cns[0];
503
+ attrs[3].mod_type = "uid";
504
+ attrs[3].mod_values = uid_vals;
505
+ uid_vals[0] = &uids[0];
506
+
507
+ for ( j = 0; j < outerloops; j++ ) {
508
+ for(i = 0; i < noconns; i++) {
509
+ mlds[i] = ldap_dup(lds[i]);
510
+ if (mlds[i] == NULL) {
511
+ thread_error( idx, "ldap_dup error" );
512
+ }
513
+ }
514
+ rc = ldap_get_option(mlds[0], LDAP_OPT_SESSION_REFCNT, &refcnt);
515
+ snprintf(thrstr, BUFSIZ,
516
+ "RW Thread conns: %d refcnt: %d (rc = %d)",
517
+ noconns, refcnt, rc);
518
+ thread_verbose(idx, thrstr);
519
+
520
+ thisconn = (idx + j) % noconns;
521
+ if (thisconn < 0 || thisconn >= noconns)
522
+ thisconn = 0;
523
+ if (mlds[thisconn] == NULL) {
524
+ thread_error( idx, "(failed to dup)");
525
+ tester_perror( "ldap_dup", "(failed to dup)" );
526
+ exit( EXIT_FAILURE );
527
+ }
528
+ snprintf(thrstr, BUFSIZ, "START RW Thread using conn %d", thisconn);
529
+ thread_verbose(idx, thrstr);
530
+
531
+ ld = mlds[thisconn];
532
+ if (entry != NULL)
533
+ base = entry;
534
+ else
535
+ base = DEFAULT_BASE;
536
+ snprintf(dn, 256, "cn=%s,%s", cns, base);
537
+
538
+ adds = 0;
539
+ dels = 0;
540
+ for (i = 0; i < loops; i++) {
541
+ ret = ldap_add_ext_s(ld, dn, &attrp[0], NULL, NULL);
542
+ if (ret == LDAP_SUCCESS) {
543
+ adds++;
544
+ ret = ldap_delete_ext_s(ld, dn, NULL, NULL);
545
+ if (ret == LDAP_SUCCESS) {
546
+ dels++;
547
+ rt_pass[idx]++;
548
+ } else {
549
+ thread_output(idx, ldap_err2string(ret));
550
+ rt_fail[idx]++;
551
+ }
552
+ } else {
553
+ thread_output(idx, ldap_err2string(ret));
554
+ rt_fail[idx]++;
555
+ }
556
+ }
557
+
558
+ snprintf(thrstr, BUFSIZ,
559
+ "INNER STOP RW Thread using conn %d (%d/%d)",
560
+ thisconn, adds, dels);
561
+ thread_verbose(idx, thrstr);
562
+
563
+ for(i = 0; i < noconns; i++) {
564
+ (void) ldap_destroy(mlds[i]);
565
+ mlds[i] = NULL;
566
+ }
567
+ }
568
+
569
+ free( mlds );
570
+ return( NULL );
571
+ }
572
+
573
+ static void
574
+ do_conn( char *uri, char *manager, struct berval *passwd,
575
+ LDAP **ldp, int nobind, int maxretries, int conn_num )
576
+ {
577
+ LDAP *ld = NULL;
578
+ int version = LDAP_VERSION3;
579
+ int i = 0, do_retry = maxretries;
580
+ int rc = LDAP_SUCCESS;
581
+ char thrstr[BUFSIZ];
582
+
583
+ retry:;
584
+ ldap_initialize( &ld, uri );
585
+ if ( ld == NULL ) {
586
+ snprintf( thrstr, BUFSIZ, "connection: %d", conn_num );
587
+ tester_error( thrstr );
588
+ tester_perror( "ldap_initialize", NULL );
589
+ exit( EXIT_FAILURE );
590
+ }
591
+
592
+ (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
593
+ (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
594
+ chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
595
+
596
+ if ( do_retry == maxretries ) {
597
+ snprintf( thrstr, BUFSIZ, "do_conn #%d\n", conn_num );
598
+ thread_verbose( -1, thrstr );
599
+ }
600
+
601
+ if ( nobind == 0 ) {
602
+ rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
603
+ if ( rc != LDAP_SUCCESS ) {
604
+ snprintf( thrstr, BUFSIZ, "connection: %d", conn_num );
605
+ tester_error( thrstr );
606
+ tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
607
+ switch ( rc ) {
608
+ case LDAP_BUSY:
609
+ case LDAP_UNAVAILABLE:
610
+ if ( do_retry > 0 ) {
611
+ ldap_unbind_ext( ld, NULL, NULL );
612
+ ld = NULL;
613
+ do_retry--;
614
+ if ( delay != 0 ) {
615
+ sleep( delay );
616
+ }
617
+ goto retry;
618
+ }
619
+ /* fallthru */
620
+ default:
621
+ break;
622
+ }
623
+ exit( EXIT_FAILURE );
624
+ }
625
+ }
626
+ *ldp = ld;
627
+ }
628
+
629
+ static void
630
+ do_random( LDAP *ld,
631
+ char *sbase, char *filter, char **srchattrs, int noattrs, int nobind,
632
+ int innerloop, int maxretries, int delay, int force, int chaserefs,
633
+ int idx )
634
+ {
635
+ int i = 0, do_retry = maxretries;
636
+ char *attrs[ 2 ];
637
+ int rc = LDAP_SUCCESS;
638
+ int nvalues = 0;
639
+ char **values = NULL;
640
+ LDAPMessage *res = NULL, *e = NULL;
641
+ char thrstr[BUFSIZ];
642
+
643
+ attrs[ 0 ] = LDAP_NO_ATTRS;
644
+ attrs[ 1 ] = NULL;
645
+
646
+ snprintf( thrstr, BUFSIZ,
647
+ "Read(%d): base=\"%s\", filter=\"%s\".\n",
648
+ innerloop, sbase, filter );
649
+ thread_verbose( idx, thrstr );
650
+
651
+ rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
652
+ filter, attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
653
+ switch ( rc ) {
654
+ case LDAP_SIZELIMIT_EXCEEDED:
655
+ case LDAP_TIMELIMIT_EXCEEDED:
656
+ case LDAP_SUCCESS:
657
+ nvalues = ldap_count_entries( ld, res );
658
+ if ( nvalues == 0 ) {
659
+ if ( rc ) {
660
+ tester_ldap_error( ld, "ldap_search_ext_s", NULL );
661
+ }
662
+ break;
663
+ }
664
+
665
+ values = malloc( ( nvalues + 1 ) * sizeof( char * ) );
666
+ for ( i = 0, e = ldap_first_entry( ld, res ); e != NULL; i++, e = ldap_next_entry( ld, e ) )
667
+ {
668
+ values[ i ] = ldap_get_dn( ld, e );
669
+ }
670
+ values[ i ] = NULL;
671
+
672
+ ldap_msgfree( res );
673
+
674
+ if ( do_retry == maxretries ) {
675
+ snprintf( thrstr, BUFSIZ,
676
+ "Read base=\"%s\" filter=\"%s\" got %d values.\n",
677
+ sbase, filter, nvalues );
678
+ thread_verbose( idx, thrstr );
679
+ }
680
+
681
+ for ( i = 0; i < innerloop; i++ ) {
682
+ int r = ((double)nvalues)*rand()/(RAND_MAX + 1.0);
683
+
684
+ do_read( ld, values[ r ],
685
+ srchattrs, noattrs, nobind, 1, maxretries,
686
+ delay, force, chaserefs, idx );
687
+ }
688
+ for( i = 0; i < nvalues; i++) {
689
+ if (values[i] != NULL)
690
+ ldap_memfree( values[i] );
691
+ }
692
+ free( values );
693
+ break;
694
+
695
+ default:
696
+ tester_ldap_error( ld, "ldap_search_ext_s", NULL );
697
+ break;
698
+ }
699
+
700
+ snprintf( thrstr, BUFSIZ, "Search done (%d).\n", rc );
701
+ thread_verbose( idx, thrstr );
702
+ }
703
+
704
+ /* substitute a generated int into the filter */
705
+ static void
706
+ do_random2( LDAP *ld,
707
+ char *sbase, char *filter, char **srchattrs, int noattrs, int nobind,
708
+ int innerloop, int maxretries, int delay, int force, int chaserefs,
709
+ int idx )
710
+ {
711
+ int i = 0, do_retry = maxretries;
712
+ int rc = LDAP_SUCCESS;
713
+ int lo, hi, range;
714
+ int flen;
715
+ LDAPMessage *res = NULL, *e = NULL;
716
+ char *ptr, *ftail;
717
+ char thrstr[BUFSIZ];
718
+ char fbuf[BUFSIZ];
719
+
720
+ snprintf( thrstr, BUFSIZ,
721
+ "Read(%d): base=\"%s\", filter=\"%s\".\n",
722
+ innerloop, sbase, filter );
723
+ thread_verbose( idx, thrstr );
724
+
725
+ ptr = strchr(filter, '[');
726
+ if (!ptr)
727
+ return;
728
+ ftail = strchr(filter, ']');
729
+ if (!ftail || ftail < ptr)
730
+ return;
731
+
732
+ sscanf(ptr, "[%d-%d]", &lo, &hi);
733
+ range = hi - lo + 1;
734
+
735
+ flen = ptr - filter;
736
+ ftail++;
737
+
738
+ for ( i = 0; i < innerloop; i++ ) {
739
+ int r = ((double)range)*rand()/(RAND_MAX + 1.0);
740
+ sprintf(fbuf, "%.*s%d%s", flen, filter, r, ftail);
741
+
742
+ rc = ldap_search_ext_s( ld, sbase, LDAP_SCOPE_SUBTREE,
743
+ fbuf, srchattrs, noattrs, NULL, NULL, NULL,
744
+ LDAP_NO_LIMIT, &res );
745
+ if ( res != NULL ) {
746
+ ldap_msgfree( res );
747
+ }
748
+ if ( rc == 0 ) {
749
+ rt_pass[idx]++;
750
+ } else {
751
+ int first = tester_ignore_err( rc );
752
+ char buf[ BUFSIZ ];
753
+
754
+ rt_fail[idx]++;
755
+ snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );
756
+
757
+ /* if ignore.. */
758
+ if ( first ) {
759
+ /* only log if first occurrence */
760
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
761
+ tester_ldap_error( ld, buf, NULL );
762
+ }
763
+ continue;
764
+ }
765
+
766
+ /* busy needs special handling */
767
+ tester_ldap_error( ld, buf, NULL );
768
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
769
+ do_retry--;
770
+ continue;
771
+ }
772
+ break;
773
+ }
774
+ }
775
+
776
+ snprintf( thrstr, BUFSIZ, "Search done (%d).\n", rc );
777
+ thread_verbose( idx, thrstr );
778
+ }
779
+
780
+ static void
781
+ do_read( LDAP *ld, char *entry,
782
+ char **attrs, int noattrs, int nobind, int maxloop,
783
+ int maxretries, int delay, int force, int chaserefs, int idx )
784
+ {
785
+ int i = 0, do_retry = maxretries;
786
+ int rc = LDAP_SUCCESS;
787
+ char thrstr[BUFSIZ];
788
+
789
+ retry:;
790
+ if ( do_retry == maxretries ) {
791
+ snprintf( thrstr, BUFSIZ, "Read(%d): entry=\"%s\".\n",
792
+ maxloop, entry );
793
+ thread_verbose( idx, thrstr );
794
+ }
795
+
796
+ snprintf(thrstr, BUFSIZ, "LD %p cnt: %d (retried %d) (%s)", \
797
+ (void *) ld, maxloop, (do_retry - maxretries), entry);
798
+ thread_verbose( idx, thrstr );
799
+
800
+ for ( ; i < maxloop; i++ ) {
801
+ LDAPMessage *res = NULL;
802
+
803
+ rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
804
+ NULL, attrs, noattrs, NULL, NULL, NULL,
805
+ LDAP_NO_LIMIT, &res );
806
+ if ( res != NULL ) {
807
+ ldap_msgfree( res );
808
+ }
809
+
810
+ if ( rc == 0 ) {
811
+ rt_pass[idx]++;
812
+ } else {
813
+ int first = tester_ignore_err( rc );
814
+ char buf[ BUFSIZ ];
815
+
816
+ rt_fail[idx]++;
817
+ snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );
818
+
819
+ /* if ignore.. */
820
+ if ( first ) {
821
+ /* only log if first occurrence */
822
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
823
+ tester_ldap_error( ld, buf, NULL );
824
+ }
825
+ continue;
826
+ }
827
+
828
+ /* busy needs special handling */
829
+ tester_ldap_error( ld, buf, NULL );
830
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
831
+ do_retry--;
832
+ goto retry;
833
+ }
834
+ break;
835
+ }
836
+ }
837
+ }