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