]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-modrdn.c
add support for extra ops after bind; allow to skip bind for slapd-search/read
[openldap] / tests / progs / slapd-modrdn.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2006 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, "CFH:h:i:p:D:w:e:l:L:r:t:" )) != EOF ) {
86                 switch( i ) {
87                 case 'C':
88                         chaserefs++;
89                         break;
90
91                 case 'F':
92                         friendly++;
93                         break;
94
95                 case 'H':               /* the server uri */
96                         uri = strdup( optarg );
97                         break;
98
99                 case 'h':               /* the servers host */
100                         host = strdup( optarg );
101                         break;
102
103                 case 'i':
104                         /* ignored (!) by now */
105                         break;
106
107                 case 'p':               /* the servers port */
108                         if ( lutil_atoi( &port, optarg ) != 0 ) {
109                                 usage( argv[0] );
110                         }
111                         break;
112
113                 case 'D':               /* the servers manager */
114                         manager = strdup( optarg );
115                         break;
116
117                 case 'w':               /* the server managers password */
118                         passwd.bv_val = strdup( optarg );
119                         passwd.bv_len = strlen( optarg );
120                         memset( optarg, '*', passwd.bv_len );
121                         break;
122
123                 case 'e':               /* entry to rename */
124                         entry = strdup( optarg );
125                         break;
126
127                 case 'l':               /* the number of loops */
128                         if ( lutil_atoi( &loops, optarg ) != 0 ) {
129                                 usage( argv[0] );
130                         }
131                         break;
132
133                 case 'L':               /* the number of outerloops */
134                         if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
135                                 usage( argv[0] );
136                         }
137                         break;
138
139                 case 'r':               /* the number of retries */
140                         if ( lutil_atoi( &retries, optarg ) != 0 ) {
141                                 usage( argv[0] );
142                         }
143                         break;
144
145                 case 't':               /* delay in seconds */
146                         if ( lutil_atoi( &delay, optarg ) != 0 ) {
147                                 usage( argv[0] );
148                         }
149                         break;
150
151                 default:
152                         usage( argv[0] );
153                         break;
154                 }
155         }
156
157         if (( entry == NULL ) || ( port == -1 && uri == NULL ))
158                 usage( argv[0] );
159
160         if ( *entry == '\0' ) {
161
162                 fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
163                                 argv[0] );
164                 exit( EXIT_FAILURE );
165
166         }
167
168         uri = tester_uri( uri, host, port );
169
170         for ( i = 0; i < outerloops; i++ ) {
171                 do_modrdn( uri, manager, &passwd, entry,
172                         loops, retries, delay, friendly, chaserefs );
173         }
174
175         exit( EXIT_SUCCESS );
176 }
177
178
179 static void
180 do_modrdn( char *uri, char *manager,
181         struct berval *passwd, char *entry, int maxloop, int maxretries,
182         int delay, int friendly, int chaserefs )
183 {
184         LDAP    *ld = NULL;
185         int     i = 0, do_retry = maxretries;
186         char    *DNs[2];
187         char    *rdns[2];
188         int     rc = LDAP_SUCCESS;
189         char    *p1, *p2;
190         int     version = LDAP_VERSION3;
191
192         DNs[0] = entry;
193         DNs[1] = strdup( entry );
194
195         /* reverse the RDN, make new DN */
196         p1 = strchr( entry, '=' ) + 1;
197         p2 = strchr( p1, ',' );
198
199         *p2 = '\0';
200         rdns[1] = strdup( entry );
201         *p2-- = ',';
202
203         for (i = p1 - entry;p2 >= p1;)
204                 DNs[1][i++] = *p2--;
205         
206         DNs[1][i] = '\0';
207         rdns[0] = strdup( DNs[1] );
208         DNs[1][i] = ',';
209
210 retry:;
211         ldap_initialize( &ld, uri );
212         if ( ld == NULL ) {
213                 tester_perror( "ldap_initialize", NULL );
214                 exit( EXIT_FAILURE );
215         }
216
217         (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
218         (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
219                 chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
220
221         if ( do_retry == maxretries ) {
222                 fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
223                         (long) pid, maxloop, entry );
224         }
225
226         rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
227         if ( rc != LDAP_SUCCESS ) {
228                 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
229                 switch ( rc ) {
230                 case LDAP_BUSY:
231                 case LDAP_UNAVAILABLE:
232                         if ( do_retry > 0 ) {
233                                 do_retry--;
234                                 if ( delay > 0) {
235                                     sleep( delay );
236                                 }
237                                 goto retry;
238                         }
239                 /* fallthru */
240                 default:
241                         break;
242                 }
243                 exit( EXIT_FAILURE );
244         }
245
246         for ( ; i < maxloop; i++ ) {
247                 rc = ldap_rename_s( ld, DNs[0], rdns[0], NULL, 0, NULL, NULL );
248                 if ( rc != LDAP_SUCCESS ) {
249                         tester_ldap_error( ld, "ldap_rename_s", NULL );
250                         switch ( rc ) {
251                         case LDAP_NO_SUCH_OBJECT:
252                                 /* NOTE: this likely means
253                                  * the second modrdn failed
254                                  * during the previous round... */
255                                 if ( !friendly ) {
256                                         goto done;
257                                 }
258                                 break;
259
260                         case LDAP_BUSY:
261                         case LDAP_UNAVAILABLE:
262                                 if ( do_retry > 0 ) {
263                                         do_retry--;
264                                         goto retry;
265                                 }
266                                 /* fall thru */
267
268                         default:
269                                 goto done;
270                         }
271                 }
272                 rc = ldap_rename_s( ld, DNs[1], rdns[1], NULL, 1, NULL, NULL );
273                 if ( rc != LDAP_SUCCESS ) {
274                         tester_ldap_error( ld, "ldap_rename_s", NULL );
275                         switch ( rc ) {
276                         case LDAP_NO_SUCH_OBJECT:
277                                 /* NOTE: this likely means
278                                  * the first modrdn failed
279                                  * during the previous round... */
280                                 if ( !friendly ) {
281                                         goto done;
282                                 }
283                                 break;
284
285                         case LDAP_BUSY:
286                         case LDAP_UNAVAILABLE:
287                                 if ( do_retry > 0 ) {
288                                         do_retry--;
289                                         goto retry;
290                                 }
291                                 /* fall thru */
292
293                         default:
294                                 goto done;
295                         }
296                 }
297         }
298
299 done:;
300         fprintf( stderr, " PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
301
302         ldap_unbind_ext( ld, NULL, NULL );
303 }
304
305