X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fslapmodify.c;h=fd578a68f2837c149ec6a2ea2585880a39993a62;hb=59e9ff6243465640956b58ad1756a3ede53eca7c;hp=878188eb1a92835333411ad3be1a7a86d14ed2d1;hpb=f6eacdbbc56be65dc1080ae2527b96399c24418d;p=openldap diff --git a/servers/slapd/slapmodify.c b/servers/slapd/slapmodify.c index 878188eb1a..fd578a68f2 100644 --- a/servers/slapd/slapmodify.c +++ b/servers/slapd/slapmodify.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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. @@ -38,6 +38,8 @@ #include "slapcommon.h" +extern int slap_DN_strict; /* dn.c */ + static char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ]; int @@ -74,6 +76,7 @@ slapmodify( int argc, char **argv ) memset( &opbuf, 0, sizeof(opbuf) ); op = &opbuf.ob_op; op->o_hdr = &opbuf.ob_hdr; + op->o_bd = be; if ( !be->be_entry_open || !be->be_entry_close || @@ -97,9 +100,12 @@ slapmodify( int argc, char **argv ) 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 ) { @@ -131,10 +137,10 @@ slapmodify( int argc, char **argv ) 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; @@ -178,20 +184,23 @@ slapmodify( int argc, char **argv ) request = "modify"; break; - case LDAP_REQ_MODRDN: case LDAP_REQ_DELETE: + if ( be->be_entry_delete ) + { + request = "delete"; + break; + } + /* 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: - fprintf( stderr, "%s: unknown request 0x%lx (line=%lu)\n", - progname, (unsigned long)lr.lr_op, lineno ); - rc = EXIT_FAILURE; - if( continuemode ) continue; - goto done; + /* record skipped e.g. version: or comment or something we don't handle yet */ + goto cleanup; } local_rc = dnNormalize( 0, NULL, NULL, &lr.lr_dn, &ndn, NULL ); @@ -199,8 +208,7 @@ slapmodify( int argc, char **argv ) 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 */ @@ -228,10 +236,7 @@ slapmodify( int argc, char **argv ) } fprintf( stderr, "\n" ); rc = EXIT_FAILURE; - SLAP_FREE( ndn.bv_val ); - ldap_ldif_record_done( &lr ); - if( continuemode ) continue; - break; + goto cleanup; } /* check backend */ @@ -262,190 +267,190 @@ slapmodify( int argc, char **argv ) } 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 ]; @@ -482,8 +487,6 @@ slapmodify( int argc, char **argv ) 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 ); @@ -494,6 +497,8 @@ slapmodify( int argc, char **argv ) 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 ); @@ -546,47 +551,53 @@ slapmodify( int argc, char **argv ) } } - if ( mod_err ) break; - /* check schema, objectClass etc */ if ( !dryrun ) { switch ( lr.lr_op ) { case LDAP_REQ_ADD: id = be->be_entry_put( be, e, &bvtext ); + rc = (id == NOID); break; case LDAP_REQ_MODIFY: id = be->be_entry_modify( be, e, &bvtext ); + rc = (id == NOID); + break; + + case LDAP_REQ_DELETE: + rc = be->be_entry_delete( be, &ndn, &bvtext ); break; } - if( id == NOID ) { + 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;