Back to index

openldap  2.4.31
slapd-modify.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 
00016 #include "portable.h"
00017 
00018 #include <stdio.h>
00019 
00020 #include "ac/stdlib.h"
00021 
00022 #include "ac/ctype.h"
00023 #include "ac/param.h"
00024 #include "ac/socket.h"
00025 #include "ac/string.h"
00026 #include "ac/unistd.h"
00027 #include "ac/wait.h"
00028 
00029 #include "ldap.h"
00030 #include "lutil.h"
00031 
00032 #include "slapd-common.h"
00033 
00034 #define LOOPS 100
00035 #define RETRIES 0
00036 
00037 static void
00038 do_modify( char *uri, char *manager, struct berval *passwd,
00039               char *entry, char *attr, char *value, int maxloop,
00040               int maxretries, int delay, int friendly, int chaserefs );
00041 
00042 
00043 static void
00044 usage( char *name )
00045 {
00046         fprintf( stderr,
00047               "usage: %s "
00048               "-H <uri> | ([-h <host>] -p <port>) "
00049               "-D <manager> "
00050               "-w <passwd> "
00051               "-e <entry> "
00052               "[-i <ignore>] "
00053               "[-l <loops>] "
00054               "[-L <outerloops>] "
00055               "[-r <maxretries>] "
00056               "[-t <delay>] "
00057               "[-F] "
00058               "[-C]\n",
00059                      name );
00060        exit( EXIT_FAILURE );
00061 }
00062 
00063 int
00064 main( int argc, char **argv )
00065 {
00066        int           i;
00067        char          *uri = NULL;
00068        char          *host = "localhost";
00069        int           port = -1;
00070        char          *manager = NULL;
00071        struct berval passwd = { 0, NULL };
00072        char          *entry = NULL;
00073        char          *ava = NULL;
00074        char          *value = NULL;
00075        int           loops = LOOPS;
00076        int           outerloops = 1;
00077        int           retries = RETRIES;
00078        int           delay = 0;
00079        int           friendly = 0;
00080        int           chaserefs = 0;
00081 
00082        tester_init( "slapd-modify", TESTER_MODIFY );
00083 
00084        while ( ( i = getopt( argc, argv, "a:CD:e:FH:h:i:L:l:p:r:t:w:" ) ) != EOF )
00085        {
00086               switch ( i ) {
00087               case 'C':
00088                      chaserefs++;
00089                      break;
00090 
00091               case 'F':
00092                      friendly++;
00093                      break;
00094 
00095               case 'H':            /* the server uri */
00096                      uri = strdup( optarg );
00097                      break;
00098 
00099               case 'h':            /* the servers host */
00100                      host = strdup( optarg );
00101                      break;
00102 
00103               case 'i':
00104                      /* ignored (!) by now */
00105                      break;
00106 
00107               case 'p':            /* the servers port */
00108                      if ( lutil_atoi( &port, optarg ) != 0 ) {
00109                             usage( argv[0] );
00110                      }
00111                      break;
00112 
00113               case 'D':            /* the servers manager */
00114                      manager = strdup( optarg );
00115                      break;
00116 
00117               case 'w':            /* the server managers password */
00118                      passwd.bv_val = strdup( optarg );
00119                      passwd.bv_len = strlen( optarg );
00120                      memset( optarg, '*', passwd.bv_len );
00121                      break;
00122 
00123               case 'e':            /* entry to modify */
00124                      entry = strdup( optarg );
00125                      break;
00126 
00127               case 'a':
00128                      ava = strdup( optarg );
00129                      break;
00130 
00131               case 'l':            /* the number of loops */
00132                      if ( lutil_atoi( &loops, optarg ) != 0 ) {
00133                             usage( argv[0] );
00134                      }
00135                      break;
00136 
00137               case 'L':            /* the number of outerloops */
00138                      if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
00139                             usage( argv[0] );
00140                      }
00141                      break;
00142 
00143               case 'r':            /* number of retries */
00144                      if ( lutil_atoi( &retries, optarg ) != 0 ) {
00145                             usage( argv[0] );
00146                      }
00147                      break;
00148 
00149               case 't':            /* delay in seconds */
00150                      if ( lutil_atoi( &delay, optarg ) != 0 ) {
00151                             usage( argv[0] );
00152                      }
00153                      break;
00154 
00155               default:
00156                      usage( argv[0] );
00157                      break;
00158               }
00159        }
00160 
00161        if (( entry == NULL ) || ( ava == NULL ) || ( port == -1 && uri == NULL ))
00162               usage( argv[0] );
00163 
00164        if ( *entry == '\0' ) {
00165 
00166               fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
00167                             argv[0] );
00168               exit( EXIT_FAILURE );
00169 
00170        }
00171        if ( *ava  == '\0' ) {
00172               fprintf( stderr, "%s: invalid EMPTY AVA.\n",
00173                             argv[0] );
00174               exit( EXIT_FAILURE );
00175        }
00176        
00177        if ( !( value = strchr( ava, ':' ))) {
00178               fprintf( stderr, "%s: invalid AVA.\n",
00179                             argv[0] );
00180               exit( EXIT_FAILURE );
00181        }
00182        *value++ = '\0'; 
00183        while ( *value && isspace( (unsigned char) *value ))
00184               value++;
00185 
00186        uri = tester_uri( uri, host, port );
00187 
00188        for ( i = 0; i < outerloops; i++ ) {
00189               do_modify( uri, manager, &passwd, entry, ava, value,
00190                             loops, retries, delay, friendly, chaserefs );
00191        }
00192 
00193        exit( EXIT_SUCCESS );
00194 }
00195 
00196 
00197 static void
00198 do_modify( char *uri, char *manager,
00199        struct berval *passwd, char *entry, char* attr, char* value,
00200        int maxloop, int maxretries, int delay, int friendly, int chaserefs )
00201 {
00202        LDAP   *ld = NULL;
00203        int    i = 0, do_retry = maxretries;
00204        int     rc = LDAP_SUCCESS;
00205 
00206        struct ldapmod mod;
00207        struct ldapmod *mods[2];
00208        char *values[2];
00209        int version = LDAP_VERSION3;
00210 
00211        values[0] = value;
00212        values[1] = NULL;
00213        mod.mod_op = LDAP_MOD_ADD;
00214        mod.mod_type = attr;
00215        mod.mod_values = values;
00216        mods[0] = &mod;
00217        mods[1] = NULL;
00218 
00219 retry:;
00220        ldap_initialize( &ld, uri );
00221        if ( ld == NULL ) {
00222               tester_perror( "ldap_initialize", NULL );
00223               exit( EXIT_FAILURE );
00224        }
00225 
00226        (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
00227        (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
00228               chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
00229 
00230        if ( do_retry == maxretries ) {
00231               fprintf( stderr, "PID=%ld - Modify(%d): entry=\"%s\".\n",
00232                      (long) pid, maxloop, entry );
00233        }
00234 
00235        rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
00236        if ( rc != LDAP_SUCCESS ) {
00237               tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
00238               switch ( rc ) {
00239               case LDAP_BUSY:
00240               case LDAP_UNAVAILABLE:
00241                      if ( do_retry > 0 ) {
00242                             do_retry--;
00243                             if ( delay > 0 ) {
00244                                 sleep( delay );
00245                             }
00246                             goto retry;
00247                      }
00248               /* fallthru */
00249               default:
00250                      break;
00251               }
00252               exit( EXIT_FAILURE );
00253        }
00254 
00255        for ( ; i < maxloop; i++ ) {
00256               mod.mod_op = LDAP_MOD_ADD;
00257               rc = ldap_modify_ext_s( ld, entry, mods, NULL, NULL );
00258               if ( rc != LDAP_SUCCESS ) {
00259                      tester_ldap_error( ld, "ldap_modify_ext_s", NULL );
00260                      switch ( rc ) {
00261                      case LDAP_TYPE_OR_VALUE_EXISTS:
00262                             /* NOTE: this likely means
00263                              * the second modify failed
00264                              * during the previous round... */
00265                             if ( !friendly ) {
00266                                    goto done;
00267                             }
00268                             break;
00269 
00270                      case LDAP_BUSY:
00271                      case LDAP_UNAVAILABLE:
00272                             if ( do_retry > 0 ) {
00273                                    do_retry--;
00274                                    goto retry;
00275                             }
00276                             /* fall thru */
00277 
00278                      default:
00279                             goto done;
00280                      }
00281               }
00282               
00283               mod.mod_op = LDAP_MOD_DELETE;
00284               rc = ldap_modify_ext_s( ld, entry, mods, NULL, NULL );
00285               if ( rc != LDAP_SUCCESS ) {
00286                      tester_ldap_error( ld, "ldap_modify_ext_s", NULL );
00287                      switch ( rc ) {
00288                      case LDAP_NO_SUCH_ATTRIBUTE:
00289                             /* NOTE: this likely means
00290                              * the first modify failed
00291                              * during the previous round... */
00292                             if ( !friendly ) {
00293                                    goto done;
00294                             }
00295                             break;
00296 
00297                      case LDAP_BUSY:
00298                      case LDAP_UNAVAILABLE:
00299                             if ( do_retry > 0 ) {
00300                                    do_retry--;
00301                                    goto retry;
00302                             }
00303                             /* fall thru */
00304 
00305                      default:
00306                             goto done;
00307                      }
00308               }
00309 
00310        }
00311 
00312 done:;
00313        fprintf( stderr, "  PID=%ld - Modify done (%d).\n", (long) pid, rc );
00314 
00315        ldap_unbind_ext( ld, NULL, NULL );
00316 }
00317 
00318