]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-modrdn.c
Sync with HEAD
[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         pid_t   pid;
187         char    *DNs[2];
188         char    *rdns[2];
189         int     rc = LDAP_SUCCESS;
190         char    *p1, *p2;
191         int     version = LDAP_VERSION3;
192
193         pid = getpid();
194         DNs[0] = entry;
195         DNs[1] = strdup( entry );
196
197         /* reverse the RDN, make new DN */
198         p1 = strchr( entry, '=' ) + 1;
199         p2 = strchr( p1, ',' );
200
201         *p2 = '\0';
202         rdns[1] = strdup( entry );
203         *p2-- = ',';
204
205         for (i = p1 - entry;p2 >= p1;)
206                 DNs[1][i++] = *p2--;
207         
208         DNs[1][i] = '\0';
209         rdns[0] = strdup( DNs[1] );
210         DNs[1][i] = ',';
211
212 retry:;
213         ldap_initialize( &ld, uri );
214         if ( ld == NULL ) {
215                 tester_perror( "ldap_initialize", NULL );
216                 exit( EXIT_FAILURE );
217         }
218
219         (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
220         (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
221                 chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
222
223         if ( do_retry == maxretries ) {
224                 fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
225                         (long) pid, maxloop, entry );
226         }
227
228         rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
229         if ( rc != LDAP_SUCCESS ) {
230                 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
231                 switch ( rc ) {
232                 case LDAP_BUSY:
233                 case LDAP_UNAVAILABLE:
234                         if ( do_retry > 0 ) {
235                                 do_retry--;
236                                 if ( delay > 0) {
237                                     sleep( delay );
238                                 }
239                                 goto retry;
240                         }
241                 /* fallthru */
242                 default:
243                         break;
244                 }
245                 exit( EXIT_FAILURE );
246         }
247
248         for ( ; i < maxloop; i++ ) {
249                 rc = ldap_rename_s( ld, DNs[0], rdns[0], NULL, 0, NULL, NULL );
250                 if ( rc != LDAP_SUCCESS ) {
251                         tester_ldap_error( ld, "ldap_rename_s", NULL );
252                         switch ( rc ) {
253                         case LDAP_NO_SUCH_OBJECT:
254                                 /* NOTE: this likely means
255                                  * the second modrdn failed
256                                  * during the previous round... */
257                                 if ( !friendly ) {
258                                         goto done;
259                                 }
260                                 break;
261
262                         case LDAP_BUSY:
263                         case LDAP_UNAVAILABLE:
264                                 if ( do_retry > 0 ) {
265                                         do_retry--;
266                                         goto retry;
267                                 }
268                                 /* fall thru */
269
270                         default:
271                                 goto done;
272                         }
273                 }
274                 rc = ldap_rename_s( ld, DNs[1], rdns[1], NULL, 1, NULL, NULL );
275                 if ( rc != LDAP_SUCCESS ) {
276                         tester_ldap_error( ld, "ldap_rename_s", NULL );
277                         switch ( rc ) {
278                         case LDAP_NO_SUCH_OBJECT:
279                                 /* NOTE: this likely means
280                                  * the first modrdn failed
281                                  * during the previous round... */
282                                 if ( !friendly ) {
283                                         goto done;
284                                 }
285                                 break;
286
287                         case LDAP_BUSY:
288                         case LDAP_UNAVAILABLE:
289                                 if ( do_retry > 0 ) {
290                                         do_retry--;
291                                         goto retry;
292                                 }
293                                 /* fall thru */
294
295                         default:
296                                 goto done;
297                         }
298                 }
299         }
300
301 done:;
302         fprintf( stderr, " PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
303
304         ldap_unbind_ext( ld, NULL, NULL );
305 }
306
307