2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2014 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
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>.
16 * This work was initially developed by Kurt Spanier for inclusion
17 * in OpenLDAP Software.
24 #include "ac/stdlib.h"
28 #include "ac/socket.h"
29 #include "ac/string.h"
30 #include "ac/unistd.h"
36 #include "slapd-common.h"
42 get_add_entry( char *filename, LDAPMod ***mods );
45 do_addel( char *uri, char *manager, struct berval *passwd,
46 char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay,
47 int friendly, int chaserefs );
54 "-H <uri> | ([-h <host>] -p <port>) "
70 main( int argc, char **argv )
73 char *host = "localhost";
77 struct berval passwd = { 0, NULL };
78 char *filename = NULL;
82 int retries = RETRIES;
86 LDAPMod **attrs = NULL;
88 tester_init( "slapd-addel", TESTER_ADDEL );
90 while ( ( i = getopt( argc, argv, "CD:Ff:H:h:i:L:l:p:r:t:w:" ) ) != EOF )
101 case 'H': /* the server's URI */
102 uri = strdup( optarg );
105 case 'h': /* the servers host */
106 host = strdup( optarg );
110 /* ignored (!) by now */
113 case 'p': /* the servers port */
114 if ( lutil_atoi( &port, optarg ) != 0 ) {
119 case 'D': /* the servers manager */
120 manager = strdup( optarg );
123 case 'w': /* the server managers password */
124 passwd.bv_val = strdup( optarg );
125 passwd.bv_len = strlen( optarg );
126 memset( optarg, '*', passwd.bv_len );
129 case 'f': /* file with entry search request */
130 filename = strdup( optarg );
133 case 'l': /* the number of loops */
134 if ( lutil_atoi( &loops, optarg ) != 0 ) {
139 case 'L': /* the number of outerloops */
140 if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
145 case 'r': /* number of retries */
146 if ( lutil_atoi( &retries, optarg ) != 0 ) {
151 case 't': /* delay in seconds */
152 if ( lutil_atoi( &delay, optarg ) != 0 ) {
163 if (( filename == NULL ) || ( port == -1 && uri == NULL ) ||
164 ( manager == NULL ) || ( passwd.bv_val == NULL ))
167 entry = get_add_entry( filename, &attrs );
168 if (( entry == NULL ) || ( *entry == '\0' )) {
170 fprintf( stderr, "%s: invalid entry DN in file \"%s\".\n",
172 exit( EXIT_FAILURE );
176 if (( attrs == NULL ) || ( *attrs == '\0' )) {
178 fprintf( stderr, "%s: invalid attrs in file \"%s\".\n",
180 exit( EXIT_FAILURE );
184 uri = tester_uri( uri, host, port );
186 for ( i = 0; i < outerloops; i++ ) {
187 do_addel( uri, manager, &passwd, entry, attrs,
188 loops, retries, delay, friendly, chaserefs );
191 exit( EXIT_SUCCESS );
196 addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
203 modop |= LDAP_MOD_BVALUES;
206 if ( pmods != NULL ) {
207 for ( ; pmods[ i ] != NULL; ++i ) {
208 if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
209 pmods[ i ]->mod_op == modop ) {
215 if ( pmods == NULL || pmods[ i ] == NULL ) {
216 if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) *
217 sizeof( LDAPMod * ))) == NULL ) {
218 tester_perror( "realloc", NULL );
219 exit( EXIT_FAILURE );
222 pmods[ i + 1 ] = NULL;
223 if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
225 tester_perror( "calloc", NULL );
226 exit( EXIT_FAILURE );
228 pmods[ i ]->mod_op = modop;
229 if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
230 tester_perror( "strdup", NULL );
231 exit( EXIT_FAILURE );
235 if ( value != NULL ) {
237 if ( pmods[ i ]->mod_bvalues != NULL ) {
238 for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
242 if (( pmods[ i ]->mod_bvalues =
243 (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues,
244 (j + 2) * sizeof( struct berval * ))) == NULL ) {
245 tester_perror( "ber_memrealloc", NULL );
246 exit( EXIT_FAILURE );
248 pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
249 if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval )))
251 tester_perror( "ber_memalloc", NULL );
252 exit( EXIT_FAILURE );
254 pmods[ i ]->mod_bvalues[ j ] = bvp;
257 if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
258 tester_perror( "malloc", NULL );
259 exit( EXIT_FAILURE );
261 AC_MEMCPY( bvp->bv_val, value, vlen );
262 bvp->bv_val[ vlen ] = '\0';
268 get_add_entry( char *filename, LDAPMod ***mods )
273 if ( (fp = fopen( filename, "r" )) != NULL ) {
276 if ( fgets( line, BUFSIZ, fp )) {
279 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
282 if ( !strncasecmp( nl, "dn: ", 4 ))
284 entry = strdup( nl );
288 while ( fgets( line, BUFSIZ, fp )) {
292 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
295 if ( *line == '\0' ) break;
296 if ( !( value = strchr( line, ':' ))) break;
299 while ( *value && isspace( (unsigned char) *value ))
302 addmodifyop( mods, LDAP_MOD_ADD, line, value, strlen( value ));
316 struct berval *passwd,
326 int i = 0, do_retry = maxretries;
327 int rc = LDAP_SUCCESS;
328 int version = LDAP_VERSION3;
331 ldap_initialize( &ld, uri );
333 tester_perror( "ldap_initialize", NULL );
334 exit( EXIT_FAILURE );
337 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
338 (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
339 chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
341 if ( do_retry == maxretries ) {
342 fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
343 (long) pid, maxloop, entry );
346 rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
347 if ( rc != LDAP_SUCCESS ) {
348 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
351 case LDAP_UNAVAILABLE:
352 if ( do_retry > 0 ) {
363 exit( EXIT_FAILURE );
366 for ( ; i < maxloop; i++ ) {
369 rc = ldap_add_ext_s( ld, entry, attrs, NULL, NULL );
370 if ( rc != LDAP_SUCCESS ) {
371 tester_ldap_error( ld, "ldap_add_ext_s", NULL );
373 case LDAP_ALREADY_EXISTS:
374 /* NOTE: this likely means
376 * during the previous round... */
383 case LDAP_UNAVAILABLE:
384 if ( do_retry > 0 ) {
396 /* wait a second for the add to really complete */
397 /* This masks some race conditions though. */
401 /* now delete the entry again */
402 rc = ldap_delete_ext_s( ld, entry, NULL, NULL );
403 if ( rc != LDAP_SUCCESS ) {
404 tester_ldap_error( ld, "ldap_delete_ext_s", NULL );
406 case LDAP_NO_SUCH_OBJECT:
407 /* NOTE: this likely means
409 * during the previous round... */
416 case LDAP_UNAVAILABLE:
417 if ( do_retry > 0 ) {
430 fprintf( stderr, " PID=%ld - Add/Delete done (%d).\n", (long) pid, rc );
432 ldap_unbind_ext( ld, NULL, NULL );