]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-modrdn.c
gently handle LDAP_UNAVAILABLE for a few times
[openldap] / tests / progs / slapd-modrdn.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2005 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 #define LDAP_DEPRECATED 1
34 #include <ldap.h>
35
36 #define LOOPS   100
37 #define RETRIES 0
38
39 static void
40 do_modrdn( char *uri, char *host, int port, char *manager, char *passwd,
41                 char *entry, int maxloop, int maxretries, int delay );
42
43 static void
44 usage( char *name )
45 {
46         fprintf( stderr,
47                 "usage: %s "
48                 "-H <uri> | ([-h <host>] -p <port>) "
49                 "-D <manager> "
50                 "-w <passwd> "
51                 "-e <entry> "
52                 "[-l <loops>] "
53                 "[-r <maxretries>] "
54                 "[-t <delay>]\n",
55                         name );
56         exit( EXIT_FAILURE );
57 }
58
59 int
60 main( int argc, char **argv )
61 {
62         int             i;
63         char            *uri = NULL;
64         char            *host = "localhost";
65         int             port = -1;
66         char            *manager = NULL;
67         char            *passwd = NULL;
68         char            *entry = NULL;
69         int             loops = LOOPS;
70         int             retries = RETRIES;
71         int             delay = 0;
72
73         while ( (i = getopt( argc, argv, "H:h:p:D:w:e:l:r:t:" )) != EOF ) {
74                 switch( i ) {
75                 case 'H':               /* the server uri */
76                         uri = strdup( optarg );
77                         break;
78
79                 case 'h':               /* the servers host */
80                         host = strdup( optarg );
81                         break;
82
83                 case 'p':               /* the servers port */
84                         port = atoi( optarg );
85                         break;
86
87                 case 'D':               /* the servers manager */
88                         manager = strdup( optarg );
89                         break;
90
91                 case 'w':               /* the server managers password */
92                         passwd = strdup( optarg );
93                         break;
94
95                 case 'e':               /* entry to rename */
96                         entry = strdup( optarg );
97                         break;
98
99                 case 'l':               /* the number of loops */
100                         loops = atoi( optarg );
101                         break;
102
103                 case 'r':               /* the number of retries */
104                         retries = atoi( optarg );
105                         break;
106
107                 case 't':               /* delay in seconds */
108                         delay = atoi( optarg );
109                         break;
110
111                 default:
112                         usage( argv[0] );
113                         break;
114                 }
115         }
116
117         if (( entry == NULL ) || ( port == -1 && uri == NULL ))
118                 usage( argv[0] );
119
120         if ( *entry == '\0' ) {
121
122                 fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
123                                 argv[0] );
124                 exit( EXIT_FAILURE );
125
126         }
127
128         do_modrdn( uri, host, port, manager, passwd, entry, loops, retries, delay );
129         exit( EXIT_SUCCESS );
130 }
131
132
133 static void
134 do_modrdn( char *uri, char *host, int port, char *manager,
135         char *passwd, char *entry, int maxloop, int maxretries, int delay )
136 {
137         LDAP    *ld = NULL;
138         int     i = 0, do_retry = maxretries;
139         pid_t   pid;
140         char *DNs[2];
141         char *rdns[2];
142         int         rc = LDAP_SUCCESS;
143
144
145         pid = getpid();
146         DNs[0] = entry;
147         DNs[1] = strdup( entry );
148
149         /* reverse the RDN, make new DN */
150         {
151                 char *p1, *p2;
152
153                 p1 = strchr( entry, '=' ) + 1;
154                 p2 = strchr( p1, ',' );
155
156                 *p2 = '\0';
157                 rdns[1] = strdup( entry );
158                 *p2-- = ',';
159
160                 for (i = p1 - entry;p2 >= p1;)
161                         DNs[1][i++] = *p2--;
162                 
163                 DNs[1][i] = '\0';
164                 rdns[0] = strdup( DNs[1] );
165                 DNs[1][i] = ',';
166         }
167
168 retry:;
169         if ( uri ) {
170                 ldap_initialize( &ld, uri );
171         } else {
172                 ld = ldap_init( host, port );
173         }
174         if ( ld == NULL ) {
175                 perror( "ldap_init" );
176                 exit( EXIT_FAILURE );
177         }
178
179         {
180                 int version = LDAP_VERSION3;
181                 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
182                         &version ); 
183         }
184
185         if ( do_retry == maxretries ) {
186                 fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
187                         (long) pid, maxloop, entry );
188         }
189
190         rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
191         if ( rc != LDAP_SUCCESS ) {
192                 ldap_perror( ld, "ldap_bind" );
193                 switch ( rc ) {
194                 case LDAP_BUSY:
195                 case LDAP_UNAVAILABLE:
196                         if ( do_retry > 0 ) {
197                                 do_retry--;
198                                 if ( delay > 0) {
199                                     sleep( delay );
200                                 }
201                                 goto retry;
202                         }
203                 /* fallthru */
204                 default:
205                         break;
206                 }
207                 exit( EXIT_FAILURE );
208         }
209
210         for ( ; i < maxloop; i++ ) {
211                 rc = ldap_modrdn2_s( ld, DNs[0], rdns[0], 0 );
212                 if ( rc != LDAP_SUCCESS ) {
213                         ldap_perror( ld, "ldap_modrdn" );
214                         switch ( rc ) {
215                         case LDAP_NO_SUCH_OBJECT:
216                                 /* NOTE: this likely means
217                                  * the second modrdn failed
218                                  * during the previous round... */
219                                 break;
220
221                         case LDAP_BUSY:
222                         case LDAP_UNAVAILABLE:
223                                 if ( do_retry > 0 ) {
224                                         do_retry--;
225                                         goto retry;
226                                 }
227                                 /* fall thru */
228
229                         default:
230                                 goto done;
231                         }
232                 }
233                 rc = ldap_modrdn2_s( ld, DNs[1], rdns[1], 1 );
234                 if ( rc != LDAP_SUCCESS ) {
235                         ldap_perror( ld, "ldap_modrdn" );
236                         switch ( rc ) {
237                         case LDAP_NO_SUCH_OBJECT:
238                                 break;
239
240                         case LDAP_BUSY:
241                         case LDAP_UNAVAILABLE:
242                                 if ( do_retry > 0 ) {
243                                         do_retry--;
244                                         goto retry;
245                                 }
246                                 /* fall thru */
247
248                         default:
249                                 goto done;
250                         }
251                 }
252         }
253
254 done:;
255         fprintf( stderr, " PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
256
257         ldap_unbind( ld );
258 }
259
260