]> git.sur5r.net Git - openldap/blobdiff - tests/progs/slapd-modify.c
Merge remote branch 'origin/mdb.master' into OPENLDAP_REL_ENG_2_4
[openldap] / tests / progs / slapd-modify.c
index b639df553908dd065281e8020b2e37334780b25a..0c7c5e429917daa143df8eb68e677fa23d875d72 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2005 The OpenLDAP Foundation.
+ * Copyright 1999-2012 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <stdio.h>
 
-#include <ac/stdlib.h>
+#include "ac/stdlib.h"
 
-#include <ac/ctype.h>
-#include <ac/param.h>
-#include <ac/socket.h>
-#include <ac/string.h>
-#include <ac/unistd.h>
-#include <ac/wait.h>
+#include "ac/ctype.h"
+#include "ac/param.h"
+#include "ac/socket.h"
+#include "ac/string.h"
+#include "ac/unistd.h"
+#include "ac/wait.h"
 
-#define LDAP_DEPRECATED 1
-#include <ldap.h>
+#include "ldap.h"
+#include "lutil.h"
+
+#include "slapd-common.h"
 
 #define LOOPS  100
 #define RETRIES 0
 
 static void
-do_modify( char *uri, char *host, int port, char *manager, char *passwd,
+do_modify( char *uri, char *manager, struct berval *passwd,
                char *entry, char *attr, char *value, int maxloop,
-               int maxretries );
+               int maxretries, int delay, int friendly, int chaserefs );
 
 
 static void
 usage( char *name )
 {
-       fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -e <entry> [-l <loops>]\n",
+        fprintf( stderr,
+               "usage: %s "
+               "-H <uri> | ([-h <host>] -p <port>) "
+               "-D <manager> "
+               "-w <passwd> "
+               "-e <entry> "
+               "[-i <ignore>] "
+               "[-l <loops>] "
+               "[-L <outerloops>] "
+               "[-r <maxretries>] "
+               "[-t <delay>] "
+               "[-F] "
+               "[-C]\n",
                        name );
        exit( EXIT_FAILURE );
 }
@@ -54,15 +68,30 @@ main( int argc, char **argv )
        char            *host = "localhost";
        int             port = -1;
        char            *manager = NULL;
-       char            *passwd = NULL;
+       struct berval   passwd = { 0, NULL };
        char            *entry = NULL;
        char            *ava = NULL;
        char            *value = NULL;
        int             loops = LOOPS;
+       int             outerloops = 1;
        int             retries = RETRIES;
+       int             delay = 0;
+       int             friendly = 0;
+       int             chaserefs = 0;
+
+       tester_init( "slapd-modify", TESTER_MODIFY );
+
+       while ( ( i = getopt( argc, argv, "a:CD:e:FH:h:i:L:l:p:r:t:w:" ) ) != EOF )
+       {
+               switch ( i ) {
+               case 'C':
+                       chaserefs++;
+                       break;
+
+               case 'F':
+                       friendly++;
+                       break;
 
-       while ( (i = getopt( argc, argv, "H:h:p:D:w:e:a:l:r:" )) != EOF ) {
-               switch( i ) {
                case 'H':               /* the server uri */
                        uri = strdup( optarg );
                        break;
@@ -71,8 +100,14 @@ main( int argc, char **argv )
                        host = strdup( optarg );
                        break;
 
+               case 'i':
+                       /* ignored (!) by now */
+                       break;
+
                case 'p':               /* the servers port */
-                       port = atoi( optarg );
+                       if ( lutil_atoi( &port, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
                        break;
 
                case 'D':               /* the servers manager */
@@ -80,7 +115,9 @@ main( int argc, char **argv )
                        break;
 
                case 'w':               /* the server managers password */
-                       passwd = strdup( optarg );
+                       passwd.bv_val = strdup( optarg );
+                       passwd.bv_len = strlen( optarg );
+                       memset( optarg, '*', passwd.bv_len );
                        break;
 
                case 'e':               /* entry to modify */
@@ -92,11 +129,27 @@ main( int argc, char **argv )
                        break;
 
                case 'l':               /* the number of loops */
-                       loops = atoi( optarg );
+                       if ( lutil_atoi( &loops, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
+                       break;
+
+               case 'L':               /* the number of outerloops */
+                       if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
+                       break;
+
+               case 'r':               /* number of retries */
+                       if ( lutil_atoi( &retries, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
                        break;
 
-               case 'r':
-                       retries = atoi( optarg );
+               case 't':               /* delay in seconds */
+                       if ( lutil_atoi( &delay, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
                        break;
 
                default:
@@ -130,28 +183,31 @@ main( int argc, char **argv )
        while ( *value && isspace( (unsigned char) *value ))
                value++;
 
-       do_modify( uri, host, port, manager, passwd, entry, ava, value,
-                       loops, retries );
+       uri = tester_uri( uri, host, port );
+
+       for ( i = 0; i < outerloops; i++ ) {
+               do_modify( uri, manager, &passwd, entry, ava, value,
+                               loops, retries, delay, friendly, chaserefs );
+       }
+
        exit( EXIT_SUCCESS );
 }
 
 
 static void
-do_modify( char *uri, char *host, int port, char *manager,
-       char *passwd, char *entry, char* attr, char* value,
-       int maxloop, int maxretries )
+do_modify( char *uri, char *manager,
+       struct berval *passwd, char *entry, char* attr, char* value,
+       int maxloop, int maxretries, int delay, int friendly, int chaserefs )
 {
        LDAP    *ld = NULL;
        int     i = 0, do_retry = maxretries;
-       pid_t   pid;
        int     rc = LDAP_SUCCESS;
 
        struct ldapmod mod;
        struct ldapmod *mods[2];
        char *values[2];
+       int version = LDAP_VERSION3;
 
-       pid = getpid();
-       
        values[0] = value;
        values[1] = NULL;
        mod.mod_op = LDAP_MOD_ADD;
@@ -161,36 +217,32 @@ do_modify( char *uri, char *host, int port, char *manager,
        mods[1] = NULL;
 
 retry:;
-       if ( uri ) {
-               ldap_initialize( &ld, uri );
-       } else {
-               ld = ldap_init( host, port );
-       }
+       ldap_initialize( &ld, uri );
        if ( ld == NULL ) {
-               perror( "ldap_init" );
+               tester_perror( "ldap_initialize", NULL );
                exit( EXIT_FAILURE );
        }
 
-       {
-               int version = LDAP_VERSION3;
-               (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
-                       &version ); 
-       }
+       (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); 
+       (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
+               chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
 
        if ( do_retry == maxretries ) {
                fprintf( stderr, "PID=%ld - Modify(%d): entry=\"%s\".\n",
                        (long) pid, maxloop, entry );
        }
 
-       rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
+       rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
        if ( rc != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_bind" );
+               tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
                switch ( rc ) {
                case LDAP_BUSY:
                case LDAP_UNAVAILABLE:
-                       if ( do_retry == 1 ) {
-                               do_retry = 0;
-                               sleep( 1 );
+                       if ( do_retry > 0 ) {
+                               do_retry--;
+                               if ( delay > 0 ) {
+                                   sleep( delay );
+                               }
                                goto retry;
                        }
                /* fallthru */
@@ -202,34 +254,65 @@ retry:;
 
        for ( ; i < maxloop; i++ ) {
                mod.mod_op = LDAP_MOD_ADD;
-               rc = ldap_modify_s( ld, entry, mods );
+               rc = ldap_modify_ext_s( ld, entry, mods, NULL, NULL );
                if ( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_modify" );
-                       if ( rc == LDAP_BUSY && do_retry > 0 ) {
-                               do_retry--;
-                               goto retry;
+                       tester_ldap_error( ld, "ldap_modify_ext_s", NULL );
+                       switch ( rc ) {
+                       case LDAP_TYPE_OR_VALUE_EXISTS:
+                               /* NOTE: this likely means
+                                * the second modify failed
+                                * during the previous round... */
+                               if ( !friendly ) {
+                                       goto done;
+                               }
+                               break;
+
+                       case LDAP_BUSY:
+                       case LDAP_UNAVAILABLE:
+                               if ( do_retry > 0 ) {
+                                       do_retry--;
+                                       goto retry;
+                               }
+                               /* fall thru */
+
+                       default:
+                               goto done;
                        }
-                       if ( rc != LDAP_NO_SUCH_OBJECT ) break;
-                       continue;
                }
                
                mod.mod_op = LDAP_MOD_DELETE;
-               rc = ldap_modify_s( ld, entry, mods );
+               rc = ldap_modify_ext_s( ld, entry, mods, NULL, NULL );
                if ( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_modify" );
-                       if ( rc == LDAP_BUSY && do_retry > 0 ) {
-                               do_retry--;
-                               goto retry;
+                       tester_ldap_error( ld, "ldap_modify_ext_s", NULL );
+                       switch ( rc ) {
+                       case LDAP_NO_SUCH_ATTRIBUTE:
+                               /* NOTE: this likely means
+                                * the first modify failed
+                                * during the previous round... */
+                               if ( !friendly ) {
+                                       goto done;
+                               }
+                               break;
+
+                       case LDAP_BUSY:
+                       case LDAP_UNAVAILABLE:
+                               if ( do_retry > 0 ) {
+                                       do_retry--;
+                                       goto retry;
+                               }
+                               /* fall thru */
+
+                       default:
+                               goto done;
                        }
-                       if ( rc != LDAP_NO_SUCH_OBJECT ) break;
-                       continue;
                }
 
        }
 
-       fprintf( stderr, " PID=%ld - Modify done (%d).\n", (long) pid, rc );
+done:;
+       fprintf( stderr, "  PID=%ld - Modify done (%d).\n", (long) pid, rc );
 
-       ldap_unbind( ld );
+       ldap_unbind_ext( ld, NULL, NULL );
 }