]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-auth.c
ITS#5211 spec says we must ignore invalid cookies
[openldap] / tests / progs / slapd-auth.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2006-2007 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[-R %:lo:hi] [-f <filter-template>] [-n <threads>]\n",
54                         name );
55         exit( EXIT_FAILURE );
56 }
57
58 static char *filter = "(uid=user.%d)";
59
60 static char hname[1024];
61 static char *uri = "ldap:///";
62 static char     *base;
63 static char     *pass;
64
65 static int tdur, r1per, r1lo, r1hi, r2per, r2lo, r2hi;
66 static int threads = 1;
67
68 static volatile int *r1binds, *r2binds;
69 static int *r1old, *r2old;
70 static volatile int finish;
71
72 int
73 main( int argc, char **argv )
74 {
75         int             i;
76
77         while ( (i = getopt( argc, argv, "b:H:w:f:n:t:r:R:" )) != EOF ) {
78                 switch( i ) {
79                         case 'b':               /* base DN of a tree of user DNs */
80                                 base = strdup( optarg );
81                                 break;
82
83                         case 'H':               /* the server uri */
84                                 uri = strdup( optarg );
85                                 break;
86
87                         case 'w':
88                                 pass = strdup( optarg );
89                                 break;
90
91                         case 't':               /* the duration to run */
92                                 if ( lutil_atoi( &tdur, optarg ) != 0 ) {
93                                         usage( argv[0] );
94                                 }
95                                 break;
96
97                         case 'r':               /* the uid range */
98                                 if ( sscanf(optarg, "%d:%d", &r1lo, &r1hi) != 2 ) {
99                                         usage( argv[0] );
100                                 }
101                                 break;
102
103                         case 'R':               /* percentage:2nd uid range */
104                                 if ( sscanf(optarg, "%d:%d:%d", &r2per, &r2lo, &r2hi) != 3 ) {
105                                         usage( argv[0] );
106                                 }
107                                 break;
108
109                         case 'f':
110                                 filter = optarg;
111                                 break;
112
113                         case 'n':
114                                 if ( lutil_atoi( &threads, optarg ) != 0 || threads < 1 ) {
115                                         usage( argv[0] );
116                                 }
117                                 break;
118                                 
119                         default:
120                                 usage( argv[0] );
121                                 break;
122                 }
123         }
124
125         if ( tdur == 0 || r1hi <= r1lo )
126                 usage( argv[0] );
127
128         r1per = 100 - r2per;
129         if ( r1per < 1 )
130                 usage( argv[0] );
131
132         r1binds = calloc( threads*4, sizeof( int ));
133         r2binds = r1binds + threads;
134         r1old = (int *)r2binds + threads;
135         r2old = r1old + threads;
136
137         do_time( );
138
139         exit( EXIT_SUCCESS );
140 }
141
142 static void *
143 my_task( void *my_num )
144 {
145         LDAP    *ld = NULL;
146         ber_int_t msgid;
147         LDAPMessage *res, *msg;
148         char *attrs[] = { "1.1", NULL };
149         int     rc = LDAP_SUCCESS;
150         int             tid = *(int *)my_num;
151
152         ldap_initialize( &ld, uri );
153         if ( ld == NULL ) {
154                 perror( "ldap_initialize" );
155                 return NULL;
156         }
157
158         {
159                 int version = LDAP_VERSION3;
160                 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
161                         &version ); 
162         }
163         (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
164
165         r1binds[tid] = 0;
166
167         for (;;) {
168                 char dn[BUFSIZ], *ptr, fstr[256];
169                 int j, isr1;
170                 
171                 if ( finish )
172                         break;
173
174                 j = rand() % 100;
175                 if ( j < r1per ) {
176                         j = rand() % r1hi;
177                         isr1 = 1;
178                 } else {
179                         j = rand() % (r2hi - r2lo + 1 );
180                         j += r2lo;
181                         isr1 = 0;
182                 }
183                 sprintf(fstr, filter, j);
184
185                 rc = ldap_search_ext( ld, base, LDAP_SCOPE_SUB,
186                         fstr, attrs, 0, NULL, NULL, 0, 0, &msgid );
187                 if ( rc != LDAP_SUCCESS ) {
188                         ldap_perror( ld, "ldap_search_ex" );
189                         return NULL;
190                 }
191
192                 while (( rc=ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
193                         BerElement *ber;
194                         struct berval bv;
195                         char *ptr;
196                         int done = 0;
197
198                         for (msg = ldap_first_message( ld, res ); msg;
199                                 msg = ldap_next_message( ld, msg )) {
200                                 switch ( ldap_msgtype( msg )) {
201                                 case LDAP_RES_SEARCH_ENTRY:
202                                         rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
203                                         strcpy(dn, bv.bv_val );
204                                         ber_free( ber, 0 );
205                                         break;
206                                 case LDAP_RES_SEARCH_RESULT:
207                                         done = 1;
208                                         break;
209                                 }
210                                 if ( done )
211                                         break;
212                         }
213                         ldap_msgfree( res );
214                         if ( done ) break;
215                 }
216
217                 rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
218                 if ( rc != LDAP_SUCCESS ) {
219                         ldap_perror( ld, "ldap_bind" );
220                 }
221                 if ( isr1 )
222                         r1binds[tid]++;
223                 else
224                         r2binds[tid]++;
225         }
226
227         ldap_unbind( ld );
228
229         return NULL;
230 }
231
232 static int
233 do_time( )
234 {
235         struct timeval tv;
236         time_t now, prevt, start;
237
238         int r1new, r2new;
239         int dt, dr1, dr2, rr1, rr2;
240         int dr10, dr20;
241         int i;
242
243         gethostname(hname, sizeof(hname));
244         printf("%s(tid)\tdeltaT\tauth1\tauth2\trate1\trate2\tRate1+2\n", hname);
245         srand(getpid());
246
247         prevt = start = time(0L);
248
249         for ( i = 0; i<threads; i++ ) {
250                 ldap_pvt_thread_t thr;
251                 r1binds[i] = i;
252                 ldap_pvt_thread_create( &thr, 1, my_task, (void *)&r1binds[i] );
253         }
254
255         for (;;) {
256                 tv.tv_sec = 30;
257                 tv.tv_usec = 0;
258
259                 select(0, NULL, NULL, NULL, &tv);
260
261                 now = time(0L);
262
263                 dt = now - prevt;
264                 prevt = now;
265
266                 dr10 = 0;
267                 dr20 = 0;
268
269                 for ( i = 0; i < threads; i++ ) {
270                         r1new = r1binds[i];
271                         r2new = r2binds[i];
272
273                         dr1 = r1new - r1old[i];
274                         dr2 = r2new - r2old[i];
275                         rr1 = dr1 / dt;
276                         rr2 = dr2 / dt;
277
278                         printf("%s(%d)\t%d\t%d\t%d\t%d\t%d\t%d\n",
279                                 hname, i, dt, dr1, dr2, rr1, rr2, rr1 + rr2);
280
281                         dr10 += dr1;
282                         dr20 += dr2;
283
284                         r1old[i] = r1new;
285                         r2old[i] = r2new;
286                 }
287                 if ( i > 1 ) {
288                         rr1 = dr10 / dt;
289                         rr2 = dr20 / dt;
290                         
291                         printf("%s(sum)\t%d\t%d\t%d\t%d\t%d\t%d\n",
292                                 hname, 0, dr10, dr20, rr1, rr2, rr1 + rr2);
293                 }
294
295                 if ( now - start >= tdur ) {
296                         finish = 1;
297                         break;
298                 }
299         }
300         return 0;
301 }