/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2014 The OpenLDAP Foundation.
+ * Copyright 1998-2018 The OpenLDAP Foundation.
* Portions Copyright 1998-2003 Kurt D. Zeilenga.
* Portions Copyright 2003 IBM Corporation.
* All rights reserved.
#include "slapcommon.h"
+extern int slap_DN_strict; /* dn.c */
+
static char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
int
lmax = 0;
nextline = 0;
- /* enforce schema checking unless not disabled */
+ /* enforce schema checking unless not disabled and allow unknown
+ * attributes otherwise */
if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
SLAP_DBFLAGS(be) &= ~(SLAP_DBFLAG_NO_SCHEMA_CHECK);
+ } else {
+ slap_DN_strict = 0;
}
if( !dryrun && be->be_entry_open( be, 1 ) != 0 ) {
lineno=nextline+1 )
{
BackendDB *bd;
- Entry *e;
+ Entry *e_orig = NULL, *e = NULL;
struct berval rbuf;
LDIFRecord lr;
- struct berval ndn;
+ struct berval ndn = BER_BVNULL;
int n;
int is_oc = 0;
int local_rc;
request = "delete";
break;
}
- /* backend does not support delete, fallthrough */
+ /* backend does not support delete, fallthru */
case LDAP_REQ_MODRDN:
fprintf( stderr, "%s: request 0x%lx not supported (line=%lu)\n",
progname, (unsigned long)lr.lr_op, lineno );
rc = EXIT_FAILURE;
- if( continuemode ) continue;
- goto done;
+ goto cleanup;
default:
/* record skipped e.g. version: or comment or something we don't handle yet */
- continue;
+ goto cleanup;
}
local_rc = dnNormalize( 0, NULL, NULL, &lr.lr_dn, &ndn, NULL );
fprintf( stderr, "%s: DN=\"%s\" normalization failed (line=%lu)\n",
progname, lr.lr_dn.bv_val, lineno );
rc = EXIT_FAILURE;
- if( continuemode ) continue;
- break;
+ goto cleanup;
}
/* make sure the DN is not empty */
}
fprintf( stderr, "\n" );
rc = EXIT_FAILURE;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- if( continuemode ) continue;
- break;
+ goto cleanup;
}
/* check backend */
}
fprintf( stderr, "\n" );
rc = EXIT_FAILURE;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- if( continuemode ) continue;
- break;
+ goto cleanup;
}
- /* get entry */
- id = be->be_dn2id_get( be, &ndn );
- e = be->be_entry_get( be, id );
- if ( e != NULL ) {
- Entry *e_tmp = entry_dup( e );
- /* FIXME: release? */
- e = e_tmp;
+ /* get id and/or entry */
+ switch ( lr.lr_op ) {
+ case LDAP_REQ_ADD:
+ e = entry_alloc();
+ ber_dupbv( &e->e_name, &lr.lr_dn );
+ ber_dupbv( &e->e_nname, &ndn );
+ break;
+
+ //case LDAP_REQ_MODRDN:
+ case LDAP_REQ_DELETE:
+ case LDAP_REQ_MODIFY:
+ id = be->be_dn2id_get( be, &ndn );
+ rc = (id == NOID);
+ if ( rc == LDAP_SUCCESS && lr.lr_op != LDAP_REQ_DELETE ) {
+ e_orig = be->be_entry_get( be, id );
+ if ( e_orig )
+ e = entry_dup( e_orig );
+ rc = (e == NULL);
+ }
+ break;
}
- for ( n = 0; lr.lrop_mods[ n ] != NULL; n++ ) {
- LDAPMod *mod = lr.lrop_mods[ n ];
- Modification mods = { 0 };
- unsigned i = 0;
- int bin = (mod->mod_op & LDAP_MOD_BVALUES);
- int pretty = 0;
- int normalize = 0;
-
- local_rc = slap_str2ad( mod->mod_type, &mods.sm_desc, &text );
- if ( local_rc != LDAP_SUCCESS ) {
- fprintf( stderr, "%s: slap_str2ad(\"%s\") failed for entry \"%s\" (%d: %s, lineno=%lu)\n",
- progname, mod->mod_type, lr.lr_dn.bv_val, local_rc, text, lineno );
- rc = EXIT_FAILURE;
- mod_err = 1;
- if( continuemode ) continue;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- entry_free( e );
- goto done;
- }
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s: no such entry \"%s\" in database (lineno=%lu)\n",
+ progname, ndn.bv_val, lineno );
+ rc = EXIT_FAILURE;
+ goto cleanup;
+ }
- mods.sm_type = mods.sm_desc->ad_cname;
+ if ( lr.lrop_mods ) {
+ for ( n = 0; lr.lrop_mods && lr.lrop_mods[ n ] != NULL; n++ ) {
+ LDAPMod *mod = lr.lrop_mods[ n ];
+ Modification mods = { 0 };
+ unsigned i = 0;
+ int bin = (mod->mod_op & LDAP_MOD_BVALUES);
+ int pretty = 0;
+ int normalize = 0;
- if ( mods.sm_desc->ad_type->sat_syntax->ssyn_pretty ) {
- pretty = 1;
+ local_rc = slap_str2ad( mod->mod_type, &mods.sm_desc, &text );
+ if ( local_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s: slap_str2ad(\"%s\") failed for entry \"%s\" (%d: %s, lineno=%lu)\n",
+ progname, mod->mod_type, lr.lr_dn.bv_val, local_rc, text, lineno );
+ rc = EXIT_FAILURE;
+ goto cleanup;
+ }
- } else {
- assert( mods.sm_desc->ad_type->sat_syntax->ssyn_validate != NULL );
- }
+ mods.sm_type = mods.sm_desc->ad_cname;
- if ( mods.sm_desc->ad_type->sat_equality &&
- mods.sm_desc->ad_type->sat_equality->smr_normalize )
- {
- normalize = 1;
- }
+ if ( mods.sm_desc->ad_type->sat_syntax->ssyn_pretty ) {
+ pretty = 1;
- if ( bin && mod->mod_bvalues ) {
- for ( i = 0; mod->mod_bvalues[ i ] != NULL; i++ )
- ;
+ } else {
+ assert( mods.sm_desc->ad_type->sat_syntax->ssyn_validate != NULL );
+ }
- } else if ( !bin && mod->mod_values ) {
- for ( i = 0; mod->mod_values[ i ] != NULL; i++ )
- ;
- }
+ if ( mods.sm_desc->ad_type->sat_equality &&
+ mods.sm_desc->ad_type->sat_equality->smr_normalize )
+ {
+ normalize = 1;
+ }
- mods.sm_values = SLAP_CALLOC( sizeof( struct berval ), i + 1 );
- if ( normalize ) {
- mods.sm_nvalues = SLAP_CALLOC( sizeof( struct berval ), i + 1 );
- } else {
- mods.sm_nvalues = NULL;
- }
- mods.sm_numvals = i;
+ if ( bin && mod->mod_bvalues ) {
+ for ( i = 0; mod->mod_bvalues[ i ] != NULL; i++ )
+ ;
- for ( i = 0; i < mods.sm_numvals; i++ ) {
- struct berval bv;
+ } else if ( !bin && mod->mod_values ) {
+ for ( i = 0; mod->mod_values[ i ] != NULL; i++ )
+ ;
+ }
- if ( bin ) {
- bv = *mod->mod_bvalues[ i ];
- } else {
- ber_str2bv( mod->mod_values[ i ], 0, 0, &bv );
+ if ( i != 0 )
+ {
+ mods.sm_values = SLAP_CALLOC( sizeof( struct berval ), i + 1 );
+ if ( normalize ) {
+ mods.sm_nvalues = SLAP_CALLOC( sizeof( struct berval ), i + 1 );
+ } else {
+ mods.sm_nvalues = NULL;
+ }
}
+ mods.sm_numvals = i;
- if ( pretty ) {
- local_rc = ordered_value_pretty( mods.sm_desc,
- &bv, &mods.sm_values[i], NULL );
+ for ( i = 0; i < mods.sm_numvals; i++ ) {
+ struct berval bv;
- } else {
- local_rc = ordered_value_validate( mods.sm_desc,
- &bv, 0 );
- }
+ if ( bin ) {
+ bv = *mod->mod_bvalues[ i ];
+ } else {
+ ber_str2bv( mod->mod_values[ i ], 0, 0, &bv );
+ }
- if ( local_rc != LDAP_SUCCESS ) {
- fprintf( stderr, "%s: DN=\"%s\": unable to %s attr=%s value #%d\n",
- progname, e->e_dn, pretty ? "prettify" : "validate",
- mods.sm_desc->ad_cname.bv_val, i );
- /* handle error */
- mod_err = 1;
- rc = EXIT_FAILURE;
- ber_bvarray_free( mods.sm_values );
- ber_bvarray_free( mods.sm_nvalues );
- if( continuemode ) continue;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- entry_free( e );
- goto done;
- }
+ if ( pretty ) {
+ local_rc = ordered_value_pretty( mods.sm_desc,
+ &bv, &mods.sm_values[i], NULL );
- if ( !pretty ) {
- ber_dupbv( &mods.sm_values[i], &bv );
- }
+ } else {
+ local_rc = ordered_value_validate( mods.sm_desc,
+ &bv, 0 );
+ }
- if ( normalize ) {
- local_rc = ordered_value_normalize(
- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
- mods.sm_desc,
- mods.sm_desc->ad_type->sat_equality,
- &mods.sm_values[i], &mods.sm_nvalues[i],
- NULL );
if ( local_rc != LDAP_SUCCESS ) {
- fprintf( stderr, "%s: DN=\"%s\": unable to normalize attr=%s value #%d\n",
- progname, e->e_dn, mods.sm_desc->ad_cname.bv_val, i );
+ fprintf( stderr, "%s: DN=\"%s\": unable to %s attr=%s value #%d\n",
+ progname, e->e_dn, pretty ? "prettify" : "validate",
+ mods.sm_desc->ad_cname.bv_val, i );
/* handle error */
- mod_err = 1;
rc = EXIT_FAILURE;
ber_bvarray_free( mods.sm_values );
ber_bvarray_free( mods.sm_nvalues );
- if( continuemode ) continue;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- entry_free( e );
- goto done;
+ goto cleanup;
}
- }
- }
-
- mods.sm_op = (mod->mod_op & ~LDAP_MOD_BVALUES);
- mods.sm_flags = 0;
- if ( mods.sm_desc == slap_schema.si_ad_objectClass ) {
- is_oc = 1;
- }
+ if ( !pretty ) {
+ ber_dupbv( &mods.sm_values[i], &bv );
+ }
- switch ( mods.sm_op ) {
- case LDAP_MOD_ADD:
- local_rc = modify_add_values( e, &mods,
- 0, &text, textbuf, textlen );
- break;
+ if ( normalize ) {
+ local_rc = ordered_value_normalize(
+ SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+ mods.sm_desc,
+ mods.sm_desc->ad_type->sat_equality,
+ &mods.sm_values[i], &mods.sm_nvalues[i],
+ NULL );
+ if ( local_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s: DN=\"%s\": unable to normalize attr=%s value #%d\n",
+ progname, e->e_dn, mods.sm_desc->ad_cname.bv_val, i );
+ /* handle error */
+ rc = EXIT_FAILURE;
+ ber_bvarray_free( mods.sm_values );
+ ber_bvarray_free( mods.sm_nvalues );
+ goto cleanup;
+ }
+ }
+ }
- case LDAP_MOD_DELETE:
- local_rc = modify_delete_values( e, &mods,
- 0, &text, textbuf, textlen );
- break;
+ mods.sm_op = (mod->mod_op & ~LDAP_MOD_BVALUES);
+ mods.sm_flags = 0;
- case LDAP_MOD_REPLACE:
- local_rc = modify_replace_values( e, &mods,
- 0, &text, textbuf, textlen );
- break;
+ if ( mods.sm_desc == slap_schema.si_ad_objectClass ) {
+ is_oc = 1;
+ }
- case LDAP_MOD_INCREMENT:
- local_rc = modify_increment_values( e, &mods,
- 0, &text, textbuf, textlen );
- break;
- }
+ switch ( mods.sm_op ) {
+ case LDAP_MOD_ADD:
+ local_rc = modify_add_values( e, &mods,
+ 0, &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_DELETE:
+ local_rc = modify_delete_values( e, &mods,
+ 0, &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_REPLACE:
+ local_rc = modify_replace_values( e, &mods,
+ 0, &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_INCREMENT:
+ local_rc = modify_increment_values( e, &mods,
+ 0, &text, textbuf, textlen );
+ break;
+ }
- if ( local_rc != LDAP_SUCCESS ) {
- fprintf( stderr, "%s: DN=\"%s\": unable to modify attr=%s\n",
- progname, e->e_dn, mods.sm_desc->ad_cname.bv_val );
- rc = EXIT_FAILURE;
ber_bvarray_free( mods.sm_values );
ber_bvarray_free( mods.sm_nvalues );
- if( continuemode ) continue;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- entry_free( e );
- goto done;
+
+ if ( local_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s: DN=\"%s\": unable to modify attr=%s\n",
+ progname, e->e_dn, mods.sm_desc->ad_cname.bv_val );
+ rc = EXIT_FAILURE;
+ goto cleanup;
+ }
}
- }
- rc = slap_tool_entry_check( progname, op, e, lineno, &text, textbuf, textlen );
- if ( rc != LDAP_SUCCESS ) {
- rc = EXIT_FAILURE;
- SLAP_FREE( ndn.bv_val );
- ldap_ldif_record_done( &lr );
- if( continuemode ) continue;
- entry_free( e );
- break;
+ rc = slap_tool_entry_check( progname, op, e, lineno, &text, textbuf, textlen );
+ if ( rc != LDAP_SUCCESS ) {
+ rc = EXIT_FAILURE;
+ goto cleanup;
+ }
}
- if ( SLAP_LASTMOD(be) ) {
+ if ( SLAP_LASTMOD(be) && e != NULL ) {
time_t now = slap_get_time();
char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
struct berval vals[ 2 ];
a = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );
if ( a != NULL ) {
- vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
- vals[0].bv_val = uuidbuf;
if ( a->a_vals != a->a_nvals ) {
SLAP_FREE( a->a_nvals[0].bv_val );
SLAP_FREE( a->a_nvals );
a->a_nvals = NULL;
a->a_numvals = 0;
}
+ vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
+ vals[0].bv_val = uuidbuf;
attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, vals, NULL );
a = attr_find( e->e_attrs, slap_schema.si_ad_creatorsName );
}
}
- if ( mod_err ) break;
-
/* check schema, objectClass etc */
if ( !dryrun ) {
break;
case LDAP_REQ_DELETE:
- rc = be->be_entry_delete( be, id, &bvtext );
+ rc = be->be_entry_delete( be, &ndn, &bvtext );
break;
}
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: could not %s entry dn=\"%s\" "
- "(line=%lu): %s\n", progname, request, e->e_dn,
+ "(line=%lu): %s\n", progname, request, ndn.bv_val,
lineno, bvtext.bv_val );
rc = EXIT_FAILURE;
- entry_free( e );
- if( continuemode ) continue;
- break;
+ goto cleanup;
}
sid = slap_tool_update_ctxcsn_check( progname, e );
if ( verbose )
fprintf( stderr, "%s: \"%s\" (%08lx)\n",
- request, e->e_dn, (long) id );
+ request, ndn.bv_val, (long) id );
} else {
if ( verbose )
fprintf( stderr, "%s: \"%s\"\n",
- request, e->e_dn );
+ request, ndn.bv_val );
}
- entry_free( e );
+cleanup:;
+ ldap_ldif_record_done( &lr );
+ SLAP_FREE( ndn.bv_val );
+ if ( e ) entry_free( e );
+ if ( e_orig ) be_entry_release_w( op, e_orig );
+ if ( rc != LDAP_SUCCESS && !continuemode ) break;
}
-done:;
if ( ldifrc < 0 )
rc = EXIT_FAILURE;