Back to index

openldap  2.4.31
slapd-modrdn.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1999-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* ACKNOWLEDGEMENTS:
00016  * This work was initially developed by Howard Chu, based in part
00017  * on other OpenLDAP test tools, for inclusion in OpenLDAP Software.
00018  */
00019 
00020 #include "portable.h"
00021 
00022 #include <stdio.h>
00023 
00024 #include "ac/stdlib.h"
00025 
00026 #include "ac/ctype.h"
00027 #include "ac/param.h"
00028 #include "ac/socket.h"
00029 #include "ac/string.h"
00030 #include "ac/unistd.h"
00031 #include "ac/wait.h"
00032 
00033 #include "ldap.h"
00034 #include "lutil.h"
00035 
00036 #include "slapd-common.h"
00037 
00038 #define LOOPS 100
00039 #define RETRIES      0
00040 
00041 static void
00042 do_modrdn( char *uri, char *manager, struct berval *passwd,
00043               char *entry, int maxloop, int maxretries, int delay,
00044               int friendly, int chaserefs );
00045 
00046 static void
00047 usage( char *name )
00048 {
00049         fprintf( stderr,
00050               "usage: %s "
00051               "-H <uri> | ([-h <host>] -p <port>) "
00052               "-D <manager> "
00053               "-w <passwd> "
00054               "-e <entry> "
00055               "[-i <ignore>] "
00056               "[-l <loops>] "
00057               "[-L <outerloops>] "
00058               "[-r <maxretries>] "
00059               "[-t <delay>] "
00060               "[-F] "
00061               "[-C]\n",
00062                      name );
00063        exit( EXIT_FAILURE );
00064 }
00065 
00066 int
00067 main( int argc, char **argv )
00068 {
00069        int           i;
00070        char          *uri = NULL;
00071        char          *host = "localhost";
00072        int           port = -1;
00073        char          *manager = NULL;
00074        struct berval passwd = { 0, NULL };
00075        char          *entry = NULL;
00076        int           loops = LOOPS;
00077        int           outerloops = 1;
00078        int           retries = RETRIES;
00079        int           delay = 0;
00080        int           friendly = 0;
00081        int           chaserefs = 0;
00082 
00083        tester_init( "slapd-modrdn", TESTER_MODRDN );
00084 
00085        while ( ( i = getopt( argc, argv, "CD:e:FH:h:i:L:l:p:r:t:w:" ) ) != EOF )
00086        {
00087               switch ( i ) {
00088               case 'C':
00089                      chaserefs++;
00090                      break;
00091 
00092               case 'F':
00093                      friendly++;
00094                      break;
00095 
00096               case 'H':            /* the server uri */
00097                      uri = strdup( optarg );
00098                      break;
00099 
00100               case 'h':            /* the servers host */
00101                      host = strdup( optarg );
00102                      break;
00103 
00104               case 'i':
00105                      /* ignored (!) by now */
00106                      break;
00107 
00108               case 'p':            /* the servers port */
00109                      if ( lutil_atoi( &port, optarg ) != 0 ) {
00110                             usage( argv[0] );
00111                      }
00112                      break;
00113 
00114               case 'D':            /* the servers manager */
00115                      manager = strdup( optarg );
00116                      break;
00117 
00118               case 'w':            /* the server managers password */
00119                      passwd.bv_val = strdup( optarg );
00120                      passwd.bv_len = strlen( optarg );
00121                      memset( optarg, '*', passwd.bv_len );
00122                      break;
00123 
00124               case 'e':            /* entry to rename */
00125                      entry = strdup( optarg );
00126                      break;
00127 
00128               case 'l':            /* the number of loops */
00129                      if ( lutil_atoi( &loops, optarg ) != 0 ) {
00130                             usage( argv[0] );
00131                      }
00132                      break;
00133 
00134               case 'L':            /* the number of outerloops */
00135                      if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
00136                             usage( argv[0] );
00137                      }
00138                      break;
00139 
00140               case 'r':            /* the number of retries */
00141                      if ( lutil_atoi( &retries, optarg ) != 0 ) {
00142                             usage( argv[0] );
00143                      }
00144                      break;
00145 
00146               case 't':            /* delay in seconds */
00147                      if ( lutil_atoi( &delay, optarg ) != 0 ) {
00148                             usage( argv[0] );
00149                      }
00150                      break;
00151 
00152               default:
00153                      usage( argv[0] );
00154                      break;
00155               }
00156        }
00157 
00158        if (( entry == NULL ) || ( port == -1 && uri == NULL ))
00159               usage( argv[0] );
00160 
00161        if ( *entry == '\0' ) {
00162 
00163               fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
00164                             argv[0] );
00165               exit( EXIT_FAILURE );
00166 
00167        }
00168 
00169        uri = tester_uri( uri, host, port );
00170 
00171        for ( i = 0; i < outerloops; i++ ) {
00172               do_modrdn( uri, manager, &passwd, entry,
00173                      loops, retries, delay, friendly, chaserefs );
00174        }
00175 
00176        exit( EXIT_SUCCESS );
00177 }
00178 
00179 
00180 static void
00181 do_modrdn( char *uri, char *manager,
00182        struct berval *passwd, char *entry, int maxloop, int maxretries,
00183        int delay, int friendly, int chaserefs )
00184 {
00185        LDAP   *ld = NULL;
00186        int    i, do_retry = maxretries;
00187        char   *DNs[2];
00188        char   *rdns[2];
00189        int    rc = LDAP_SUCCESS;
00190        char   *p1, *p2;
00191        int    version = LDAP_VERSION3;
00192 
00193        DNs[0] = entry;
00194        DNs[1] = strdup( entry );
00195 
00196        /* reverse the RDN, make new DN */
00197        p1 = strchr( entry, '=' ) + 1;
00198        p2 = strchr( p1, ',' );
00199 
00200        *p2 = '\0';
00201        rdns[1] = strdup( entry );
00202        *p2-- = ',';
00203 
00204        for (i = p1 - entry;p2 >= p1;)
00205               DNs[1][i++] = *p2--;
00206        
00207        DNs[1][i] = '\0';
00208        rdns[0] = strdup( DNs[1] );
00209        DNs[1][i] = ',';
00210 
00211        i = 0;
00212 
00213 retry:;
00214        ldap_initialize( &ld, uri );
00215        if ( ld == NULL ) {
00216               tester_perror( "ldap_initialize", NULL );
00217               exit( EXIT_FAILURE );
00218        }
00219 
00220        (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
00221        (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
00222               chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
00223 
00224        if ( do_retry == maxretries ) {
00225               fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n",
00226                      (long) pid, maxloop, entry );
00227        }
00228 
00229        rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
00230        if ( rc != LDAP_SUCCESS ) {
00231               tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
00232               switch ( rc ) {
00233               case LDAP_BUSY:
00234               case LDAP_UNAVAILABLE:
00235                      if ( do_retry > 0 ) {
00236                             do_retry--;
00237                             if ( delay > 0) {
00238                                 sleep( delay );
00239                             }
00240                             goto retry;
00241                      }
00242               /* fallthru */
00243               default:
00244                      break;
00245               }
00246               exit( EXIT_FAILURE );
00247        }
00248 
00249        for ( ; i < maxloop; i++ ) {
00250               rc = ldap_rename_s( ld, DNs[0], rdns[0], NULL, 0, NULL, NULL );
00251               if ( rc != LDAP_SUCCESS ) {
00252                      tester_ldap_error( ld, "ldap_rename_s", NULL );
00253                      switch ( rc ) {
00254                      case LDAP_NO_SUCH_OBJECT:
00255                             /* NOTE: this likely means
00256                              * the second modrdn failed
00257                              * during the previous round... */
00258                             if ( !friendly ) {
00259                                    goto done;
00260                             }
00261                             break;
00262 
00263                      case LDAP_BUSY:
00264                      case LDAP_UNAVAILABLE:
00265                             if ( do_retry > 0 ) {
00266                                    do_retry--;
00267                                    goto retry;
00268                             }
00269                             /* fall thru */
00270 
00271                      default:
00272                             goto done;
00273                      }
00274               }
00275               rc = ldap_rename_s( ld, DNs[1], rdns[1], NULL, 1, NULL, NULL );
00276               if ( rc != LDAP_SUCCESS ) {
00277                      tester_ldap_error( ld, "ldap_rename_s", NULL );
00278                      switch ( rc ) {
00279                      case LDAP_NO_SUCH_OBJECT:
00280                             /* NOTE: this likely means
00281                              * the first modrdn failed
00282                              * during the previous round... */
00283                             if ( !friendly ) {
00284                                    goto done;
00285                             }
00286                             break;
00287 
00288                      case LDAP_BUSY:
00289                      case LDAP_UNAVAILABLE:
00290                             if ( do_retry > 0 ) {
00291                                    do_retry--;
00292                                    goto retry;
00293                             }
00294                             /* fall thru */
00295 
00296                      default:
00297                             goto done;
00298                      }
00299               }
00300        }
00301 
00302 done:;
00303        fprintf( stderr, "  PID=%ld - Modrdn done (%d).\n", (long) pid, rc );
00304 
00305        ldap_unbind_ext( ld, NULL, NULL );
00306 
00307        free( DNs[1] );
00308        free( rdns[0] );
00309        free( rdns[1] );
00310 }