ruby-ldap 0.9.19 → 0.9.20

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.
@@ -1,335 +0,0 @@
1
- /* $OpenLDAP$ */
2
- /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3
- *
4
- * Copyright 2006-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 for inclusion
17
- * in OpenLDAP Software.
18
- */
19
-
20
- #include "portable.h"
21
-
22
- #include <stdio.h>
23
-
24
- #include <ac/stdlib.h>
25
-
26
- #include <ac/ctype.h>
27
- #include <ac/param.h>
28
- #include <ac/socket.h>
29
- #include <ac/string.h>
30
- #include <ac/unistd.h>
31
- #include <ac/wait.h>
32
- #include <ac/time.h>
33
- #include <ac/signal.h>
34
-
35
- #include <ldap.h>
36
- #include <ldap_pvt_thread.h>
37
- #include <lutil.h>
38
-
39
- static int
40
- do_time( );
41
-
42
- /* This program is a simplified version of SLAMD's WeightedAuthRate jobclass.
43
- * It doesn't offer as much configurability, but it's a good starting point.
44
- * When run without the -R option it will behave as a Standard AuthRate job.
45
- * Eventually this will grow into a set of C-based load generators for the SLAMD
46
- * framework. This code is anywhere from 2 to 10 times more efficient than the
47
- * original Java code, allowing servers to be fully loaded without requiring
48
- * anywhere near as much load-generation hardware.
49
- */
50
- static void
51
- usage( char *name )
52
- {
53
- fprintf( stderr, "usage: %s -H <uri> -b <baseDN> -w <passwd> -t <seconds> -r lo:hi\n\t"
54
- "[-R %:lo:hi] [-f <filter-template>] [-n <threads>] [-D <bindDN>] [-i <seconds>]\n",
55
- name );
56
- exit( EXIT_FAILURE );
57
- }
58
-
59
- static char *filter = "(uid=user.%d)";
60
-
61
- static char hname[1024];
62
- static char *uri = "ldap:///";
63
- static char *base;
64
- static char *pass;
65
- static char *binder;
66
-
67
- static int tdur, r1per, r1lo, r1hi, r2per, r2lo, r2hi;
68
- static int threads = 1;
69
-
70
- static int interval = 30;
71
-
72
- static volatile int *r1binds, *r2binds;
73
- static int *r1old, *r2old;
74
- static volatile int finish;
75
-
76
- int
77
- main( int argc, char **argv )
78
- {
79
- int i;
80
-
81
- while ( (i = getopt( argc, argv, "b:D:H:w:f:n:i:t:r:R:" )) != EOF ) {
82
- switch( i ) {
83
- case 'b': /* base DN of a tree of user DNs */
84
- base = strdup( optarg );
85
- break;
86
-
87
- case 'D':
88
- binder = strdup( optarg );
89
- break;
90
-
91
- case 'H': /* the server uri */
92
- uri = strdup( optarg );
93
- break;
94
-
95
- case 'w':
96
- pass = strdup( optarg );
97
- break;
98
-
99
- case 't': /* the duration to run */
100
- if ( lutil_atoi( &tdur, optarg ) != 0 ) {
101
- usage( argv[0] );
102
- }
103
- break;
104
-
105
- case 'i': /* the time interval */
106
- if ( lutil_atoi( &interval, optarg ) != 0 ) {
107
- usage( argv[0] );
108
- }
109
- break;
110
-
111
- case 'r': /* the uid range */
112
- if ( sscanf(optarg, "%d:%d", &r1lo, &r1hi) != 2 ) {
113
- usage( argv[0] );
114
- }
115
- break;
116
-
117
- case 'R': /* percentage:2nd uid range */
118
- if ( sscanf(optarg, "%d:%d:%d", &r2per, &r2lo, &r2hi) != 3 ) {
119
- usage( argv[0] );
120
- }
121
- break;
122
-
123
- case 'f':
124
- filter = optarg;
125
- break;
126
-
127
- case 'n':
128
- if ( lutil_atoi( &threads, optarg ) != 0 || threads < 1 ) {
129
- usage( argv[0] );
130
- }
131
- break;
132
-
133
- default:
134
- usage( argv[0] );
135
- break;
136
- }
137
- }
138
-
139
- if ( tdur == 0 || r1hi <= r1lo )
140
- usage( argv[0] );
141
-
142
- r1per = 100 - r2per;
143
- if ( r1per < 1 )
144
- usage( argv[0] );
145
-
146
- r1binds = calloc( threads*4, sizeof( int ));
147
- r2binds = r1binds + threads;
148
- r1old = (int *)r2binds + threads;
149
- r2old = r1old + threads;
150
-
151
- do_time( );
152
-
153
- exit( EXIT_SUCCESS );
154
- }
155
-
156
- static void *
157
- my_task( void *my_num )
158
- {
159
- LDAP *ld = NULL, *sld = NULL;
160
- ber_int_t msgid;
161
- LDAPMessage *res, *msg;
162
- char *attrs[] = { "1.1", NULL };
163
- int rc = LDAP_SUCCESS;
164
- int tid = *(int *)my_num;
165
-
166
- ldap_initialize( &ld, uri );
167
- if ( ld == NULL ) {
168
- perror( "ldap_initialize" );
169
- return NULL;
170
- }
171
-
172
- {
173
- int version = LDAP_VERSION3;
174
- (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
175
- &version );
176
- }
177
- (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
178
-
179
- ldap_initialize( &sld, uri );
180
- if ( sld == NULL ) {
181
- perror( "ldap_initialize" );
182
- return NULL;
183
- }
184
-
185
- {
186
- int version = LDAP_VERSION3;
187
- (void) ldap_set_option( sld, LDAP_OPT_PROTOCOL_VERSION,
188
- &version );
189
- }
190
- (void) ldap_set_option( sld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
191
- if ( binder ) {
192
- rc = ldap_bind_s( sld, binder, pass, LDAP_AUTH_SIMPLE );
193
- if ( rc != LDAP_SUCCESS ) {
194
- ldap_perror( sld, "ldap_bind" );
195
- }
196
- }
197
-
198
- r1binds[tid] = 0;
199
-
200
- for (;;) {
201
- char dn[BUFSIZ], *ptr, fstr[256];
202
- int j, isr1;
203
-
204
- if ( finish )
205
- break;
206
-
207
- j = rand() % 100;
208
- if ( j < r1per ) {
209
- j = rand() % r1hi;
210
- isr1 = 1;
211
- } else {
212
- j = rand() % (r2hi - r2lo + 1 );
213
- j += r2lo;
214
- isr1 = 0;
215
- }
216
- sprintf(fstr, filter, j);
217
-
218
- rc = ldap_search_ext( sld, base, LDAP_SCOPE_SUB,
219
- fstr, attrs, 0, NULL, NULL, 0, 0, &msgid );
220
- if ( rc != LDAP_SUCCESS ) {
221
- ldap_perror( sld, "ldap_search_ex" );
222
- return NULL;
223
- }
224
-
225
- while (( rc=ldap_result( sld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
226
- BerElement *ber;
227
- struct berval bv;
228
- char *ptr;
229
- int done = 0;
230
-
231
- for (msg = ldap_first_message( sld, res ); msg;
232
- msg = ldap_next_message( sld, msg )) {
233
- switch ( ldap_msgtype( msg )) {
234
- case LDAP_RES_SEARCH_ENTRY:
235
- rc = ldap_get_dn_ber( sld, msg, &ber, &bv );
236
- strcpy(dn, bv.bv_val );
237
- ber_free( ber, 0 );
238
- break;
239
- case LDAP_RES_SEARCH_RESULT:
240
- done = 1;
241
- break;
242
- }
243
- if ( done )
244
- break;
245
- }
246
- ldap_msgfree( res );
247
- if ( done ) break;
248
- }
249
-
250
- rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
251
- if ( rc != LDAP_SUCCESS ) {
252
- ldap_perror( ld, "ldap_bind" );
253
- }
254
- if ( isr1 )
255
- r1binds[tid]++;
256
- else
257
- r2binds[tid]++;
258
- }
259
-
260
- ldap_unbind( sld );
261
- ldap_unbind( ld );
262
-
263
- return NULL;
264
- }
265
-
266
- static int
267
- do_time( )
268
- {
269
- struct timeval tv;
270
- time_t now, prevt, start;
271
-
272
- int r1new, r2new;
273
- int dt, dr1, dr2, rr1, rr2;
274
- int dr10, dr20;
275
- int i;
276
-
277
- gethostname(hname, sizeof(hname));
278
- printf("%s(tid)\tdeltaT\tauth1\tauth2\trate1\trate2\tRate1+2\n", hname);
279
- srand(getpid());
280
-
281
- prevt = start = time(0L);
282
-
283
- for ( i = 0; i<threads; i++ ) {
284
- ldap_pvt_thread_t thr;
285
- r1binds[i] = i;
286
- ldap_pvt_thread_create( &thr, 1, my_task, (void *)&r1binds[i] );
287
- }
288
-
289
- for (;;) {
290
- tv.tv_sec = interval;
291
- tv.tv_usec = 0;
292
-
293
- select(0, NULL, NULL, NULL, &tv);
294
-
295
- now = time(0L);
296
-
297
- dt = now - prevt;
298
- prevt = now;
299
-
300
- dr10 = 0;
301
- dr20 = 0;
302
-
303
- for ( i = 0; i < threads; i++ ) {
304
- r1new = r1binds[i];
305
- r2new = r2binds[i];
306
-
307
- dr1 = r1new - r1old[i];
308
- dr2 = r2new - r2old[i];
309
- rr1 = dr1 / dt;
310
- rr2 = dr2 / dt;
311
-
312
- printf("%s(%d)\t%d\t%d\t%d\t%d\t%d\t%d\n",
313
- hname, i, dt, dr1, dr2, rr1, rr2, rr1 + rr2);
314
-
315
- dr10 += dr1;
316
- dr20 += dr2;
317
-
318
- r1old[i] = r1new;
319
- r2old[i] = r2new;
320
- }
321
- if ( i > 1 ) {
322
- rr1 = dr10 / dt;
323
- rr2 = dr20 / dt;
324
-
325
- printf("%s(sum)\t%d\t%d\t%d\t%d\t%d\t%d\n",
326
- hname, 0, dr10, dr20, rr1, rr2, rr1 + rr2);
327
- }
328
-
329
- if ( now - start >= tdur ) {
330
- finish = 1;
331
- break;
332
- }
333
- }
334
- return 0;
335
- }
@@ -1,609 +0,0 @@
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 for inclusion
17
- * in OpenLDAP Software.
18
- */
19
-
20
- #include "portable.h"
21
-
22
- #include <stdio.h>
23
-
24
- #include "ac/stdlib.h"
25
- #include "ac/time.h"
26
-
27
- #include "ac/ctype.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
- #include "ac/time.h"
34
-
35
- #include "ldap.h"
36
- #include "lutil.h"
37
- #include "lber_pvt.h"
38
- #include "ldap_pvt.h"
39
-
40
- #include "slapd-common.h"
41
-
42
- #define LOOPS 100
43
-
44
- static int
45
- do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
46
- int force, int chaserefs, int noinit, LDAP **ldp,
47
- int action_type, void *action );
48
-
49
- static int
50
- do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
51
- int maxloop, int force, int chaserefs, int noinit, int delay,
52
- int action_type, void *action );
53
-
54
- /* This program can be invoked two ways: if -D is used to specify a Bind DN,
55
- * that DN will be used repeatedly for all of the Binds. If instead -b is used
56
- * to specify a base DN, a search will be done for all "person" objects under
57
- * that base DN. Then DNs from this list will be randomly selected for each
58
- * Bind request. All of the users must have identical passwords. Also it is
59
- * assumed that the users are all onelevel children of the base.
60
- */
61
- static void
62
- usage( char *name, char opt )
63
- {
64
- if ( opt ) {
65
- fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
66
- name, opt );
67
- }
68
-
69
- fprintf( stderr, "usage: %s "
70
- "[-H uri | -h <host> [-p port]] "
71
- "[-D <dn> [-w <passwd>]] "
72
- "[-b <baseDN> [-f <searchfilter>] [-a pwattr]] "
73
- "[-l <loops>] "
74
- "[-L <outerloops>] "
75
- "[-B <extra>[,...]] "
76
- "[-F] "
77
- "[-C] "
78
- "[-I] "
79
- "[-i <ignore>] "
80
- "[-t delay]\n",
81
- name );
82
- exit( EXIT_FAILURE );
83
- }
84
-
85
- int
86
- main( int argc, char **argv )
87
- {
88
- int i;
89
- char *uri = NULL;
90
- char *host = "localhost";
91
- char *dn = NULL;
92
- char *base = NULL;
93
- char *filter = "(objectClass=person)";
94
- struct berval pass = { 0, NULL };
95
- char *pwattr = NULL;
96
- int port = -1;
97
- int loops = LOOPS;
98
- int outerloops = 1;
99
- int force = 0;
100
- int chaserefs = 0;
101
- int noinit = 1;
102
- int delay = 0;
103
-
104
- /* extra action to do after bind... */
105
- struct berval type[] = {
106
- BER_BVC( "tester=" ),
107
- BER_BVC( "add=" ),
108
- BER_BVC( "bind=" ),
109
- BER_BVC( "modify=" ),
110
- BER_BVC( "modrdn=" ),
111
- BER_BVC( "read=" ),
112
- BER_BVC( "search=" ),
113
- BER_BVNULL
114
- };
115
-
116
- LDAPURLDesc *extra_ludp = NULL;
117
-
118
- tester_init( "slapd-bind", TESTER_BIND );
119
-
120
- /* by default, tolerate invalid credentials */
121
- tester_ignore_str2errlist( "INVALID_CREDENTIALS" );
122
-
123
- while ( ( i = getopt( argc, argv, "a:B:b:D:Ff:H:h:Ii:L:l:p:t:w:" ) ) != EOF )
124
- {
125
- switch ( i ) {
126
- case 'a':
127
- pwattr = optarg;
128
- break;
129
-
130
- case 'b': /* base DN of a tree of user DNs */
131
- base = optarg;
132
- break;
133
-
134
- case 'B':
135
- {
136
- int c;
137
-
138
- for ( c = 0; type[c].bv_val; c++ ) {
139
- if ( strncasecmp( optarg, type[c].bv_val, type[c].bv_len ) == 0 )
140
- {
141
- break;
142
- }
143
- }
144
-
145
- if ( type[c].bv_val == NULL ) {
146
- usage( argv[0], 'B' );
147
- }
148
-
149
- switch ( c ) {
150
- case TESTER_TESTER:
151
- case TESTER_BIND:
152
- /* invalid */
153
- usage( argv[0], 'B' );
154
-
155
- case TESTER_SEARCH:
156
- {
157
- if ( ldap_url_parse( &optarg[type[c].bv_len], &extra_ludp ) != LDAP_URL_SUCCESS )
158
- {
159
- usage( argv[0], 'B' );
160
- }
161
- } break;
162
-
163
- case TESTER_ADDEL:
164
- case TESTER_MODIFY:
165
- case TESTER_MODRDN:
166
- case TESTER_READ:
167
- /* nothing to do */
168
- break;
169
-
170
- default:
171
- assert( 0 );
172
- }
173
-
174
- } break;
175
-
176
- case 'C':
177
- chaserefs++;
178
- break;
179
-
180
- case 'H': /* the server uri */
181
- uri = optarg;
182
- break;
183
-
184
- case 'h': /* the servers host */
185
- host = optarg;
186
- break;
187
-
188
- case 'i':
189
- tester_ignore_str2errlist( optarg );
190
- break;
191
-
192
- case 'p': /* the servers port */
193
- if ( lutil_atoi( &port, optarg ) != 0 ) {
194
- usage( argv[0], 'p' );
195
- }
196
- break;
197
-
198
- case 'D':
199
- dn = optarg;
200
- break;
201
-
202
- case 'w':
203
- ber_str2bv( optarg, 0, 1, &pass );
204
- memset( optarg, '*', pass.bv_len );
205
- break;
206
-
207
- case 'l': /* the number of loops */
208
- if ( lutil_atoi( &loops, optarg ) != 0 ) {
209
- usage( argv[0], 'l' );
210
- }
211
- break;
212
-
213
- case 'L': /* the number of outerloops */
214
- if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
215
- usage( argv[0], 'L' );
216
- }
217
- break;
218
-
219
- case 'f':
220
- filter = optarg;
221
- break;
222
-
223
- case 'F':
224
- force++;
225
- break;
226
-
227
- case 'I':
228
- /* reuse connection */
229
- noinit = 0;
230
- break;
231
-
232
- case 't':
233
- /* sleep between binds */
234
- if ( lutil_atoi( &delay, optarg ) != 0 ) {
235
- usage( argv[0], 't' );
236
- }
237
- break;
238
-
239
- default:
240
- usage( argv[0], i );
241
- break;
242
- }
243
- }
244
-
245
- if ( port == -1 && uri == NULL ) {
246
- usage( argv[0], '\0' );
247
- }
248
-
249
- uri = tester_uri( uri, host, port );
250
-
251
- for ( i = 0; i < outerloops; i++ ) {
252
- int rc;
253
-
254
- if ( base != NULL ) {
255
- rc = do_base( uri, dn, &pass, base, filter, pwattr, loops,
256
- force, chaserefs, noinit, delay, -1, NULL );
257
- } else {
258
- rc = do_bind( uri, dn, &pass, loops,
259
- force, chaserefs, noinit, NULL, -1, NULL );
260
- }
261
- if ( rc == LDAP_SERVER_DOWN )
262
- break;
263
- }
264
-
265
- exit( EXIT_SUCCESS );
266
- }
267
-
268
-
269
- static int
270
- do_bind( char *uri, char *dn, struct berval *pass, int maxloop,
271
- int force, int chaserefs, int noinit, LDAP **ldp,
272
- int action_type, void *action )
273
- {
274
- LDAP *ld = ldp ? *ldp : NULL;
275
- int i, rc = -1;
276
-
277
- /* for internal search */
278
- int timelimit = 0;
279
- int sizelimit = 0;
280
-
281
- switch ( action_type ) {
282
- case -1:
283
- break;
284
-
285
- case TESTER_SEARCH:
286
- {
287
- LDAPURLDesc *ludp = (LDAPURLDesc *)action;
288
-
289
- assert( action != NULL );
290
-
291
- if ( ludp->lud_exts != NULL ) {
292
- for ( i = 0; ludp->lud_exts[ i ] != NULL; i++ ) {
293
- char *ext = ludp->lud_exts[ i ];
294
- int crit = 0;
295
-
296
- if (ext[0] == '!') {
297
- crit++;
298
- ext++;
299
- }
300
-
301
- if ( strncasecmp( ext, "x-timelimit=", STRLENOF( "x-timelimit=" ) ) == 0 ) {
302
- if ( lutil_atoi( &timelimit, &ext[ STRLENOF( "x-timelimit=" ) ] ) && crit ) {
303
- tester_error( "unable to parse critical extension x-timelimit" );
304
- }
305
-
306
- } else if ( strncasecmp( ext, "x-sizelimit=", STRLENOF( "x-sizelimit=" ) ) == 0 ) {
307
- if ( lutil_atoi( &sizelimit, &ext[ STRLENOF( "x-sizelimit=" ) ] ) && crit ) {
308
- tester_error( "unable to parse critical extension x-sizelimit" );
309
- }
310
-
311
- } else if ( crit ) {
312
- tester_error( "unknown critical extension" );
313
- }
314
- }
315
- }
316
- } break;
317
-
318
- default:
319
- /* nothing to do yet */
320
- break;
321
- }
322
-
323
- if ( maxloop > 1 ) {
324
- fprintf( stderr, "PID=%ld - Bind(%d): dn=\"%s\".\n",
325
- (long) pid, maxloop, dn );
326
- }
327
-
328
- for ( i = 0; i < maxloop; i++ ) {
329
- if ( !noinit || ld == NULL ) {
330
- int version = LDAP_VERSION3;
331
- ldap_initialize( &ld, uri );
332
- if ( ld == NULL ) {
333
- tester_perror( "ldap_initialize", NULL );
334
- rc = -1;
335
- break;
336
- }
337
-
338
- (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
339
- &version );
340
- (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
341
- chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF );
342
- }
343
-
344
- rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL );
345
- if ( rc ) {
346
- int first = tester_ignore_err( rc );
347
-
348
- /* if ignore.. */
349
- if ( first ) {
350
- /* only log if first occurrence */
351
- if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
352
- tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
353
- }
354
- rc = LDAP_SUCCESS;
355
-
356
- } else {
357
- tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
358
- }
359
- }
360
-
361
- switch ( action_type ) {
362
- case -1:
363
- break;
364
-
365
- case TESTER_SEARCH:
366
- {
367
- LDAPURLDesc *ludp = (LDAPURLDesc *)action;
368
- LDAPMessage *res = NULL;
369
- struct timeval tv = { 0 }, *tvp = NULL;
370
-
371
- if ( timelimit ) {
372
- tv.tv_sec = timelimit;
373
- tvp = &tv;
374
- }
375
-
376
- assert( action != NULL );
377
-
378
- rc = ldap_search_ext_s( ld,
379
- ludp->lud_dn, ludp->lud_scope,
380
- ludp->lud_filter, ludp->lud_attrs, 0,
381
- NULL, NULL, tvp, sizelimit, &res );
382
- ldap_msgfree( res );
383
- } break;
384
-
385
- default:
386
- /* nothing to do yet */
387
- break;
388
- }
389
-
390
- if ( !noinit ) {
391
- ldap_unbind_ext( ld, NULL, NULL );
392
- ld = NULL;
393
- }
394
-
395
- if ( rc != LDAP_SUCCESS ) {
396
- break;
397
- }
398
- }
399
-
400
- if ( maxloop > 1 ) {
401
- fprintf( stderr, " PID=%ld - Bind done (%d).\n", (long) pid, rc );
402
- }
403
-
404
- if ( ldp && noinit ) {
405
- *ldp = ld;
406
-
407
- } else if ( ld != NULL ) {
408
- ldap_unbind_ext( ld, NULL, NULL );
409
- }
410
-
411
- return rc;
412
- }
413
-
414
-
415
- static int
416
- do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
417
- int maxloop, int force, int chaserefs, int noinit, int delay,
418
- int action_type, void *action )
419
- {
420
- LDAP *ld = NULL;
421
- int i = 0;
422
- int rc = LDAP_SUCCESS;
423
- ber_int_t msgid;
424
- LDAPMessage *res, *msg;
425
- char **dns = NULL;
426
- struct berval *creds = NULL;
427
- char *attrs[] = { LDAP_NO_ATTRS, NULL };
428
- int ndns = 0;
429
- #ifdef _WIN32
430
- DWORD beg, end;
431
- #else
432
- struct timeval beg, end;
433
- #endif
434
- int version = LDAP_VERSION3;
435
- char *nullstr = "";
436
-
437
- ldap_initialize( &ld, uri );
438
- if ( ld == NULL ) {
439
- tester_perror( "ldap_initialize", NULL );
440
- exit( EXIT_FAILURE );
441
- }
442
-
443
- (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
444
- (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
445
- chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF );
446
-
447
- rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL );
448
- if ( rc != LDAP_SUCCESS ) {
449
- tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
450
- exit( EXIT_FAILURE );
451
- }
452
-
453
- fprintf( stderr, "PID=%ld - Bind(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n",
454
- (long) pid, maxloop, base, filter, pwattr );
455
-
456
- if ( pwattr != NULL ) {
457
- attrs[ 0 ] = pwattr;
458
- }
459
- rc = ldap_search_ext( ld, base, LDAP_SCOPE_SUBTREE,
460
- filter, attrs, 0, NULL, NULL, 0, 0, &msgid );
461
- if ( rc != LDAP_SUCCESS ) {
462
- tester_ldap_error( ld, "ldap_search_ext", NULL );
463
- exit( EXIT_FAILURE );
464
- }
465
-
466
- while ( ( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res ) ) > 0 )
467
- {
468
- BerElement *ber;
469
- struct berval bv;
470
- int done = 0;
471
-
472
- for ( msg = ldap_first_message( ld, res ); msg;
473
- msg = ldap_next_message( ld, msg ) )
474
- {
475
- switch ( ldap_msgtype( msg ) ) {
476
- case LDAP_RES_SEARCH_ENTRY:
477
- rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
478
- dns = realloc( dns, (ndns + 1)*sizeof(char *) );
479
- dns[ndns] = ber_strdup( bv.bv_val );
480
- if ( pwattr != NULL ) {
481
- struct berval **values = ldap_get_values_len( ld, msg, pwattr );
482
-
483
- creds = realloc( creds, (ndns + 1)*sizeof(struct berval) );
484
- if ( values == NULL ) {
485
- novals:;
486
- creds[ndns].bv_len = 0;
487
- creds[ndns].bv_val = nullstr;
488
-
489
- } else {
490
- static struct berval cleartext = BER_BVC( "{CLEARTEXT} " );
491
- struct berval value = *values[ 0 ];
492
-
493
- if ( value.bv_val[ 0 ] == '{' ) {
494
- char *end = ber_bvchr( &value, '}' );
495
-
496
- if ( end ) {
497
- if ( ber_bvcmp( &value, &cleartext ) == 0 ) {
498
- value.bv_val += cleartext.bv_len;
499
- value.bv_len -= cleartext.bv_len;
500
-
501
- } else {
502
- ldap_value_free_len( values );
503
- goto novals;
504
- }
505
- }
506
-
507
- }
508
-
509
- ber_dupbv( &creds[ndns], &value );
510
- ldap_value_free_len( values );
511
- }
512
- }
513
- ndns++;
514
- ber_free( ber, 0 );
515
- break;
516
-
517
- case LDAP_RES_SEARCH_RESULT:
518
- done = 1;
519
- break;
520
- }
521
- if ( done )
522
- break;
523
- }
524
- ldap_msgfree( res );
525
- if ( done ) break;
526
- }
527
-
528
- #ifdef _WIN32
529
- beg = GetTickCount();
530
- #else
531
- gettimeofday( &beg, NULL );
532
- #endif
533
-
534
- if ( ndns == 0 ) {
535
- tester_error( "No DNs" );
536
- return 1;
537
- }
538
-
539
- fprintf( stderr, " PID=%ld - Bind base=\"%s\" filter=\"%s\" got %d values.\n",
540
- (long) pid, base, filter, ndns );
541
-
542
- /* Ok, got list of DNs, now start binding to each */
543
- for ( i = 0; i < maxloop; i++ ) {
544
- int j;
545
- struct berval cred = { 0, NULL };
546
-
547
-
548
- #if 0 /* use high-order bits for better randomness (Numerical Recipes in "C") */
549
- j = rand() % ndns;
550
- #endif
551
- j = ((double)ndns)*rand()/(RAND_MAX + 1.0);
552
-
553
- if ( creds && !BER_BVISEMPTY( &creds[j] ) ) {
554
- cred = creds[j];
555
- }
556
-
557
- if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld,
558
- action_type, action ) && !force )
559
- {
560
- break;
561
- }
562
-
563
- if ( delay ) {
564
- sleep( delay );
565
- }
566
- }
567
-
568
- if ( ld != NULL ) {
569
- ldap_unbind_ext( ld, NULL, NULL );
570
- ld = NULL;
571
- }
572
-
573
- #ifdef _WIN32
574
- end = GetTickCount();
575
- end -= beg;
576
-
577
- fprintf( stderr, " PID=%ld - Bind done %d in %d.%03d seconds.\n",
578
- (long) pid, i, end / 1000, end % 1000 );
579
- #else
580
- gettimeofday( &end, NULL );
581
- end.tv_usec -= beg.tv_usec;
582
- if (end.tv_usec < 0 ) {
583
- end.tv_usec += 1000000;
584
- end.tv_sec -= 1;
585
- }
586
- end.tv_sec -= beg.tv_sec;
587
-
588
- fprintf( stderr, " PID=%ld - Bind done %d in %ld.%06ld seconds.\n",
589
- (long) pid, i, (long) end.tv_sec, (long) end.tv_usec );
590
- #endif
591
-
592
- if ( dns ) {
593
- for ( i = 0; i < ndns; i++ ) {
594
- ber_memfree( dns[i] );
595
- }
596
- free( dns );
597
- }
598
-
599
- if ( creds ) {
600
- for ( i = 0; i < ndns; i++ ) {
601
- if ( creds[i].bv_val != nullstr ) {
602
- ber_memfree( creds[i].bv_val );
603
- }
604
- }
605
- free( creds );
606
- }
607
-
608
- return 0;
609
- }