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