]> git.sur5r.net Git - openldap/blobdiff - tests/progs/slapd-addel.c
Merge remote branch 'origin/mdb.master'
[openldap] / tests / progs / slapd-addel.c
index 3497439af3e4a05dc3f4570979ba92773a9fbc74..9445282e910e322763a75ddf6026651e07263679 100644 (file)
@@ -1,39 +1,67 @@
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1999-2012 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Kurt Spanier for inclusion
+ * in OpenLDAP Software.
+ */
 #include "portable.h"
 
 #include <stdio.h>
 
-#include <ac/stdlib.h>
+#include "ac/stdlib.h"
 
-#include <ac/ctype.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"
 
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
+#include "ldap.h"
+#include "lutil.h"
 
-#include <ldap.h>
+#include "slapd-common.h"
 
 #define LOOPS  100
+#define RETRIES        0
 
 static char *
 get_add_entry( char *filename, LDAPMod ***mods );
 
 static void
-do_addel( char *host, int port, char *manager, char *passwd,
-       char *dn, LDAPMod **attrs, int maxloop );
+do_addel( char *uri, char *manager, struct berval *passwd,
+       char *dn, LDAPMod **attrs, int maxloop, 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> -f <addfile> [-l <loops>]\n",
+        fprintf( stderr,
+               "usage: %s "
+               "-H <uri> | ([-h <host>] -p <port>) "
+               "-D <manager> "
+               "-w <passwd> "
+               "-f <addfile> "
+               "[-i <ignore>] "
+               "[-l <loops>] "
+               "[-L <outerloops>] "
+               "[-r <maxretries>] "
+               "[-t <delay>] "
+               "[-F] "
+               "[-C]\n",
                        name );
        exit( EXIT_FAILURE );
 }
@@ -42,49 +70,98 @@ int
 main( int argc, char **argv )
 {
        int             i;
-       char        *host = "localhost";
-       int                     port = -1;
+       char            *host = "localhost";
+       char            *uri = NULL;
+       int             port = -1;
        char            *manager = NULL;
-       char            *passwd = NULL;
+       struct berval   passwd = { 0, NULL };
        char            *filename = NULL;
        char            *entry = NULL;
-       int                     loops = LOOPS;
-       LDAPMod     **attrs = NULL;
+       int             loops = LOOPS;
+       int             outerloops = 1;
+       int             retries = RETRIES;
+       int             delay = 0;
+       int             friendly = 0;
+       int             chaserefs = 0;
+       LDAPMod         **attrs = NULL;
+
+       tester_init( "slapd-addel", TESTER_ADDEL );
+
+       while ( ( i = getopt( argc, argv, "CD:Ff:H:h:i:L:l:p:r:t:w:" ) ) != EOF )
+       {
+               switch ( i ) {
+               case 'C':
+                       chaserefs++;
+                       break;
 
-       while ( (i = getopt( argc, argv, "h:p:D:w:f:l:" )) != EOF ) {
-               switch( i ) {
-                       case 'h':               /* the servers host */
-                               host = strdup( optarg );
+               case 'F':
+                       friendly++;
+                       break;
+                       
+               case 'H':               /* the server's URI */
+                       uri = strdup( optarg );
                        break;
 
-                       case 'p':               /* the servers port */
-                               port = atoi( optarg );
-                               break;
+               case 'h':               /* the servers host */
+                       host = strdup( optarg );
+                       break;
 
-                       case 'D':               /* the servers manager */
-                               manager = strdup( optarg );
+               case 'i':
+                       /* ignored (!) by now */
                        break;
 
-                       case 'w':               /* the server managers password */
-                               passwd = strdup( optarg );
+               case 'p':               /* the servers port */
+                       if ( lutil_atoi( &port, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
                        break;
 
-                       case 'f':               /* file with entry search request */
-                               filename = strdup( optarg );
-                               break;
+               case 'D':               /* the servers manager */
+                       manager = strdup( optarg );
+                       break;
 
-                       case 'l':               /* the number of loops */
-                               loops = atoi( optarg );
-                               break;
+               case 'w':               /* the server managers password */
+                       passwd.bv_val = strdup( optarg );
+                       passwd.bv_len = strlen( optarg );
+                       memset( optarg, '*', passwd.bv_len );
+                       break;
 
-                       default:
+               case 'f':               /* file with entry search request */
+                       filename = strdup( optarg );
+                       break;
+
+               case 'l':               /* the number of loops */
+                       if ( lutil_atoi( &loops, optarg ) != 0 ) {
                                usage( argv[0] );
-                               break;
+                       }
+                       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 't':               /* delay in seconds */
+                       if ( lutil_atoi( &delay, optarg ) != 0 ) {
+                               usage( argv[0] );
+                       }
+                       break;
+
+               default:
+                       usage( argv[0] );
+                       break;
                }
        }
 
-       if (( filename == NULL ) || ( port == -1 ) ||
-                               ( manager == NULL ) || ( passwd == NULL ))
+       if (( filename == NULL ) || ( port == -1 && uri == NULL ) ||
+                               ( manager == NULL ) || ( passwd.bv_val == NULL ))
                usage( argv[0] );
 
        entry = get_add_entry( filename, &attrs );
@@ -104,7 +181,12 @@ main( int argc, char **argv )
 
        }
 
-       do_addel( host, port, manager, passwd, entry, attrs, loops );
+       uri = tester_uri( uri, host, port );
+
+       for ( i = 0; i < outerloops; i++ ) {
+               do_addel( uri, manager, &passwd, entry, attrs,
+                               loops, retries, delay, friendly, chaserefs );
+       }
 
        exit( EXIT_SUCCESS );
 }
@@ -133,19 +215,19 @@ addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
     if ( pmods == NULL || pmods[ i ] == NULL ) {
                if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) *
                        sizeof( LDAPMod * ))) == NULL ) {
-                       perror( "realloc" );
+                       tester_perror( "realloc", NULL );
                        exit( EXIT_FAILURE );
                }
                *pmodsp = pmods;
                pmods[ i + 1 ] = NULL;
                if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
                        == NULL ) {
-                       perror( "calloc" );
+                       tester_perror( "calloc", NULL );
                        exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_op = modop;
                if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
-               perror( "strdup" );
+               tester_perror( "strdup", NULL );
                exit( EXIT_FAILURE );
                }
     }
@@ -160,23 +242,23 @@ addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
                if (( pmods[ i ]->mod_bvalues =
                        (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues,
                        (j + 2) * sizeof( struct berval * ))) == NULL ) {
-                       perror( "ber_realloc" );
+                       tester_perror( "ber_memrealloc", NULL );
                        exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
                if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval )))
                        == NULL ) {
-                       perror( "malloc" );
+                       tester_perror( "ber_memalloc", NULL );
                        exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_bvalues[ j ] = bvp;
 
            bvp->bv_len = vlen;
            if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
-                       perror( "malloc" );
+                       tester_perror( "malloc", NULL );
                        exit( EXIT_FAILURE );
            }
-           SAFEMEMCPY( bvp->bv_val, value, vlen );
+           AC_MEMCPY( bvp->bv_val, value, vlen );
            bvp->bv_val[ vlen ] = '\0';
     }
 }
@@ -196,7 +278,10 @@ get_add_entry( char *filename, LDAPMod ***mods )
 
                        if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
                                *nl = '\0';
-                       entry = strdup( line );
+                       nl = line;
+                       if ( !strncasecmp( nl, "dn: ", 4 ))
+                               nl += 4;
+                       entry = strdup( nl );
 
                }
 
@@ -226,60 +311,125 @@ get_add_entry( char *filename, LDAPMod ***mods )
 
 static void
 do_addel(
-       char *host,
-       int port,
+       char *uri,
        char *manager,
-       char *passwd,
+       struct berval *passwd,
        char *entry,
        LDAPMod **attrs,
-       int maxloop
-)
+       int maxloop,
+       int maxretries,
+       int delay,
+       int friendly,
+       int chaserefs )
 {
-       LDAP    *ld;
-       int     i;
-       pid_t   pid = getpid();
-
-       if (( ld = ldap_init( host, port )) == NULL ) {
-               perror( "ldap_init" );
+       LDAP    *ld = NULL;
+       int     i = 0, do_retry = maxretries;
+       int     rc = LDAP_SUCCESS;
+       int     version = LDAP_VERSION3;
+
+retry:;
+       ldap_initialize( &ld, uri );
+       if ( ld == NULL ) {
+               tester_perror( "ldap_initialize", NULL );
                exit( EXIT_FAILURE );
        }
 
-       if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE )
-                               != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_bind" );
-                exit( EXIT_FAILURE );
-       }
+       (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 - Add/Delete(%d): entry=\"%s\".\n",
+                       (long) pid, maxloop, entry );
+       }
 
-       fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
-                                       (long) pid, maxloop, entry );
+       rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
+       if ( rc != LDAP_SUCCESS ) {
+               tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
+               switch ( rc ) {
+               case LDAP_BUSY:
+               case LDAP_UNAVAILABLE:
+                       if ( do_retry > 0 ) {
+                               do_retry--;
+                               if ( delay != 0 ) {
+                                   sleep( delay );
+                               }
+                               goto retry;
+                       }
+               /* fallthru */
+               default:
+                       break;
+               }
+               exit( EXIT_FAILURE );
+       }
 
-       for ( i = 0; i < maxloop; i++ ) {
+       for ( ; i < maxloop; i++ ) {
 
                /* add the entry */
-               if ( ldap_add_s( ld, entry, attrs ) != LDAP_SUCCESS ) {
+               rc = ldap_add_ext_s( ld, entry, attrs, NULL, NULL );
+               if ( rc != LDAP_SUCCESS ) {
+                       tester_ldap_error( ld, "ldap_add_ext_s", NULL );
+                       switch ( rc ) {
+                       case LDAP_ALREADY_EXISTS:
+                               /* NOTE: this likely means
+                                * the delete failed
+                                * during the previous round... */
+                               if ( !friendly ) {
+                                       goto done;
+                               }
+                               break;
 
-                       ldap_perror( ld, "ldap_add" );
-                       break;
+                       case LDAP_BUSY:
+                       case LDAP_UNAVAILABLE:
+                               if ( do_retry > 0 ) {
+                                       do_retry--;
+                                       goto retry;
+                               }
+                               /* fall thru */
 
+                       default:
+                               goto done;
+                       }
                }
 
+#if 0
                /* wait a second for the add to really complete */
+               /* This masks some race conditions though. */
                sleep( 1 );
+#endif
 
                /* now delete the entry again */
-               if ( ldap_delete_s( ld, entry ) != LDAP_SUCCESS ) {
+               rc = ldap_delete_ext_s( ld, entry, NULL, NULL );
+               if ( rc != LDAP_SUCCESS ) {
+                       tester_ldap_error( ld, "ldap_delete_ext_s", NULL );
+                       switch ( rc ) {
+                       case LDAP_NO_SUCH_OBJECT:
+                               /* NOTE: this likely means
+                                * the add failed
+                                * during the previous round... */
+                               if ( !friendly ) {
+                                       goto done;
+                               }
+                               break;
 
-                       ldap_perror( ld, "ldap_delete" );
-                       break;
+                       case LDAP_BUSY:
+                       case LDAP_UNAVAILABLE:
+                               if ( do_retry > 0 ) {
+                                       do_retry--;
+                                       goto retry;
+                               }
+                               /* fall thru */
 
+                       default:
+                               goto done;
+                       }
                }
-
        }
 
-       fprintf( stderr, " PID=%ld - Add/Delete done.\n", (long) pid );
+done:;
+       fprintf( stderr, "  PID=%ld - Add/Delete done (%d).\n", (long) pid, rc );
 
-       ldap_unbind( ld );
+       ldap_unbind_ext( ld, NULL, NULL );
 }