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