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