]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-modrdn.c
8c9f45760c072ef0bf66076fef160ba551500471
[openldap] / tests / progs / slapd-modrdn.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2018 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( struct tester_conn_args *config,
43                 char *entry, int friendly );
44
45 static void
46 usage( char *name, char opt )
47 {
48         if ( opt ) {
49                 fprintf( stderr, "%s: unable to handle option \'%c\'\n\n",
50                         name, opt );
51         }
52
53         fprintf( stderr, "usage: %s " TESTER_COMMON_HELP
54                 "-e <entry> "
55                 "[-F]\n",
56                 name );
57         exit( EXIT_FAILURE );
58 }
59
60 int
61 main( int argc, char **argv )
62 {
63         int             i;
64         char            *entry = NULL;
65         int             friendly = 0;
66         struct tester_conn_args *config;
67
68         config = tester_init( "slapd-modrdn", TESTER_MODRDN );
69
70         while ( ( i = getopt( argc, argv, TESTER_COMMON_OPTS "e:F" ) ) != EOF )
71         {
72                 switch ( i ) {
73                 case 'F':
74                         friendly++;
75                         break;
76
77                 case 'i':
78                         /* ignored (!) by now */
79                         break;
80
81                 case 'e':               /* entry to rename */
82                         entry = strdup( optarg );
83                         break;
84
85                 default:
86                         if ( tester_config_opt( config, i, optarg ) == LDAP_SUCCESS ) {
87                                 break;
88                         }
89                         usage( argv[0], i );
90                         break;
91                 }
92         }
93
94         if ( entry == NULL )
95                 usage( argv[0], 0 );
96
97         if ( *entry == '\0' ) {
98
99                 fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
100                                 argv[0] );
101                 exit( EXIT_FAILURE );
102
103         }
104
105         tester_config_finish( config );
106
107         for ( i = 0; i < config->outerloops; i++ ) {
108                 do_modrdn( config, entry, friendly );
109         }
110
111         exit( EXIT_SUCCESS );
112 }
113
114
115 static void
116 do_modrdn( struct tester_conn_args *config,
117         char *entry, int friendly )
118 {
119         LDAP    *ld = NULL;
120         int     i, do_retry = config->retries;
121         char    *DNs[2];
122         char    *rdns[2];
123         int     rc = LDAP_SUCCESS;
124         char    *p1, *p2;
125
126         DNs[0] = entry;
127         DNs[1] = strdup( entry );
128
129         /* reverse the RDN, make new DN */
130         p1 = strchr( entry, '=' ) + 1;
131         p2 = strchr( p1, ',' );
132
133         *p2 = '\0';
134         rdns[1] = strdup( entry );
135         *p2-- = ',';
136
137         for (i = p1 - entry;p2 >= p1;)
138                 DNs[1][i++] = *p2--;
139         
140         DNs[1][i] = '\0';
141         rdns[0] = strdup( DNs[1] );
142         DNs[1][i] = ',';
143
144         i = 0;
145
146 retry:;
147         tester_init_ld( &ld, config, 0 );
148
149         if ( do_retry == config->retries ) {
150                 fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
151                         (long) pid, config->loops, entry );
152         }
153
154         for ( ; i < config->loops; i++ ) {
155                 rc = ldap_rename_s( ld, DNs[0], rdns[0], NULL, 0, NULL, NULL );
156                 if ( rc != LDAP_SUCCESS ) {
157                         tester_ldap_error( ld, "ldap_rename_s", NULL );
158                         switch ( rc ) {
159                         case LDAP_NO_SUCH_OBJECT:
160                                 /* NOTE: this likely means
161                                  * the second modrdn failed
162                                  * during the previous round... */
163                                 if ( !friendly ) {
164                                         goto done;
165                                 }
166                                 break;
167
168                         case LDAP_BUSY:
169                         case LDAP_UNAVAILABLE:
170                                 if ( do_retry > 0 ) {
171                                         do_retry--;
172                                         goto retry;
173                                 }
174                                 /* fall thru */
175
176                         default:
177                                 goto done;
178                         }
179                 }
180                 rc = ldap_rename_s( ld, DNs[1], rdns[1], NULL, 1, NULL, NULL );
181                 if ( rc != LDAP_SUCCESS ) {
182                         tester_ldap_error( ld, "ldap_rename_s", NULL );
183                         switch ( rc ) {
184                         case LDAP_NO_SUCH_OBJECT:
185                                 /* NOTE: this likely means
186                                  * the first modrdn failed
187                                  * during the previous round... */
188                                 if ( !friendly ) {
189                                         goto done;
190                                 }
191                                 break;
192
193                         case LDAP_BUSY:
194                         case LDAP_UNAVAILABLE:
195                                 if ( do_retry > 0 ) {
196                                         do_retry--;
197                                         goto retry;
198                                 }
199                                 /* fall thru */
200
201                         default:
202                                 goto done;
203                         }
204                 }
205         }
206
207 done:;
208         fprintf( stderr, "  PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
209
210         ldap_unbind_ext( ld, NULL, NULL );
211
212         free( DNs[1] );
213         free( rdns[0] );
214         free( rdns[1] );
215 }