X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmodrdn.c;h=5bb70711828ec0c68ef933606ebaf62be7828c61;hb=3dad7cae7b302f1df2184ca33ff008a0fbf1ebd7;hp=4565883db3181a6a2b8db8d9b592007146ebbfa5;hpb=b92710e3a5f4ca512cb26ed0180c2ace9022183d;p=openldap diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 4565883db3..5bb7071182 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* @@ -29,6 +29,7 @@ */ #include "portable.h" +#include "slapi_common.h" #include @@ -37,6 +38,7 @@ #include "ldap_pvt.h" #include "slap.h" +#include "slapi.h" int do_modrdn( @@ -64,9 +66,10 @@ do_modrdn( const char *text; int manageDSAit; + Slapi_PBlock *pb = op->o_pb; + #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY, - "do_modrdn: begin\n" )); + LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 ); #endif @@ -83,12 +86,11 @@ do_modrdn( * } */ - if ( ber_scanf( op->o_ber, "{oob", &dn, &newrdn, &deloldrdn ) + if ( ber_scanf( op->o_ber, "{mmb", &dn, &newrdn, &deloldrdn ) == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: ber_scanf failed\n" )); + LDAP_LOG( OPERATION, ERR, "do_modrdn: ber_scanf failed\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 ); #endif @@ -106,8 +108,8 @@ do_modrdn( * newSuperior is present: report error. */ #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: (v2) invalid field newSuperior.\n" )); + LDAP_LOG( OPERATION, ERR, + "do_modrdn: (v2) invalid field newSuperior.\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "modrdn(v2): invalid field newSuperior!\n", @@ -120,14 +122,14 @@ do_modrdn( goto cleanup; } - if ( ber_scanf( op->o_ber, "o", &newSuperior ) + if ( ber_scanf( op->o_ber, "m", &newSuperior ) == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: ber_scanf(\"a\") failed\n" )); + LDAP_LOG( OPERATION, ERR, + "do_modrdn: ber_scanf(\"m\") failed\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "ber_scanf(\"a\") failed\n", + Debug( LDAP_DEBUG_ANY, "ber_scanf(\"m\") failed\n", 0, 0, 0 ); #endif @@ -141,10 +143,10 @@ do_modrdn( } #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ARGS, + LDAP_LOG( OPERATION, ARGS, "do_modrdn: dn (%s) newrdn (%s) newsuperior(%s)\n", dn.bv_val, newrdn.bv_val, - newSuperior.bv_len ? newSuperior.bv_val : "" )); + newSuperior.bv_len ? newSuperior.bv_val : "" ); #else Debug( LDAP_DEBUG_ARGS, "do_modrdn: dn (%s) newrdn (%s) newsuperior (%s)\n", @@ -154,8 +156,7 @@ do_modrdn( if ( ber_scanf( op->o_ber, /*{*/ "}") == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: ber_scanf failed\n" )); + LDAP_LOG( OPERATION, ERR, "do_modrdn: ber_scanf failed\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: ber_scanf failed\n", 0, 0, 0 ); #endif @@ -168,8 +169,7 @@ do_modrdn( if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: get_ctrls failed\n" )); + LDAP_LOG( OPERATION, ERR, "do_modrdn: get_ctrls failed\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: get_ctrls failed\n", 0, 0, 0 ); #endif @@ -181,9 +181,9 @@ do_modrdn( rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + LDAP_LOG( OPERATION, INFO, "do_modrdn: conn %d invalid dn (%s)\n", - conn->c_connid, dn.bv_val )); + conn->c_connid, dn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid dn (%s)\n", dn.bv_val, 0, 0 ); @@ -195,8 +195,8 @@ do_modrdn( if( ndn.bv_len == 0 ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: attempt to modify root DSE.\n" )); + LDAP_LOG( OPERATION, ERR, + "do_modrdn: attempt to modify root DSE.\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: root dse!\n", 0, 0, 0 ); #endif @@ -205,19 +205,19 @@ do_modrdn( NULL, "cannot rename the root DSE", NULL, NULL ); goto cleanup; -#ifdef SLAPD_SCHEMA_DN - } else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) { + } else if ( bvmatch( &ndn, &global_schemandn ) ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: attempt to modify subschema subentry\n" )); + LDAP_LOG( OPERATION, ERR, + "do_modrdn: attempt to modify subschema subentry: %s (%ld)\n", + global_schemandn.bv_val, (long) global_schemandn.bv_len, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_modrdn: subschema subentry!\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, "do_modrdn: subschema subentry: %s (%ld)\n", + global_schemandn.bv_val, (long) global_schemandn.bv_len, 0 ); #endif send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, NULL, "cannot rename subschema subentry", NULL, NULL ); goto cleanup; -#endif } /* FIXME: should have/use rdnPretty / rdnNormalize routines */ @@ -225,9 +225,9 @@ do_modrdn( rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + LDAP_LOG( OPERATION, INFO, "do_modrdn: conn %d invalid newrdn (%s)\n", - conn->c_connid, newrdn.bv_val )); + conn->c_connid, newrdn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid newrdn (%s)\n", newrdn.bv_val, 0, 0 ); @@ -239,8 +239,8 @@ do_modrdn( if( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ERR, - "do_modrdn: invalid rdn (%s).\n", pnewrdn.bv_val )); + LDAP_LOG( OPERATION, ERR, + "do_modrdn: invalid rdn (%s).\n", pnewrdn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid rdn (%s)\n", pnewrdn.bv_val, 0, 0 ); @@ -256,9 +256,9 @@ do_modrdn( &nnewSuperior ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + LDAP_LOG( OPERATION, INFO, "do_modrdn: conn %d invalid newSuperior (%s)\n", - conn->c_connid, newSuperior.bv_val )); + conn->c_connid, newSuperior.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "do_modrdn: invalid newSuperior (%s)\n", @@ -270,7 +270,7 @@ do_modrdn( } } - Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MODRDN dn=\"%s\"\n", + Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MODRDN dn=\"%s\"\n", op->o_connid, op->o_opid, pdn.bv_val, 0, 0 ); manageDSAit = get_manageDSAit( op ); @@ -281,13 +281,13 @@ do_modrdn( * if we don't hold it. */ if ( (be = select_backend( &ndn, manageDSAit, 0 )) == NULL ) { - struct berval **ref = referral_rewrite( default_referral, + BerVarray ref = referral_rewrite( default_referral, NULL, &pdn, LDAP_SCOPE_DEFAULT ); send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL, ref ? ref : default_referral, NULL ); - ber_bvecfree( ref ); + ber_bvarray_free( ref ); goto cleanup; } @@ -328,6 +328,36 @@ do_modrdn( /* deref suffix alias if appropriate */ suffix_alias( be, &ndn ); +#if defined( LDAP_SLAPI ) + slapi_x_backend_set_pb( pb, be ); + slapi_x_connection_set_pb( pb, conn ); + slapi_x_operation_set_pb( pb, op ); + slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, + (void *)newSuperior.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) ); + + rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODRDN_FN, pb ); + if ( rc != 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn preoperation plugin " + "failed\n", 0, 0, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin " + "failed.\n", 0, 0, 0); +#endif + if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0) + rc = LDAP_OTHER; + goto cleanup; + } +#endif /* defined( LDAP_SLAPI ) */ + /* * do the add if 1 && (2 || 3) * 1) there is an add function implemented in this backend; @@ -357,15 +387,15 @@ do_modrdn( } #ifndef SLAPD_MULTIMASTER } else { - struct berval **defref = be->be_update_refs + BerVarray defref = be->be_update_refs ? be->be_update_refs : default_referral; - struct berval **ref = referral_rewrite( defref, + BerVarray ref = referral_rewrite( defref, NULL, &pdn, LDAP_SCOPE_DEFAULT ); send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL, ref ? ref : defref, NULL ); - ber_bvecfree( ref ); + ber_bvarray_free( ref ); #endif } } else { @@ -374,18 +404,175 @@ do_modrdn( NULL, NULL ); } +#if defined( LDAP_SLAPI ) + if ( doPluginFNs( be, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn postoperation plugins " + "failed\n", 0, 0, 0 ); +#else + Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn postoperation plugins " + "failed.\n", 0, 0, 0); +#endif + } +#endif /* defined( LDAP_SLAPI ) */ + cleanup: - free( dn.bv_val ); free( pdn.bv_val ); free( ndn.bv_val ); - free( newrdn.bv_val ); free( pnewrdn.bv_val ); free( nnewrdn.bv_val ); - if ( newSuperior.bv_val ) free( newSuperior.bv_val ); if ( pnewSuperior.bv_val ) free( pnewSuperior.bv_val ); if ( nnewSuperior.bv_val ) free( nnewSuperior.bv_val ); return rc; } + +int +slap_modrdn2mods( + Backend *be, + Connection *conn, + Operation *op, + Entry *e, + LDAPRDN *old_rdn, + LDAPRDN *new_rdn, + int deleteoldrdn, + Modifications **pmod ) +{ + int rc = LDAP_SUCCESS; + const char *text; + Modifications *mod = NULL; + int a_cnt, d_cnt; + + assert( new_rdn != NULL ); + assert( !deleteoldrdn || old_rdn != NULL ); + + /* Add new attribute values to the entry */ + for ( a_cnt = 0; new_rdn[ 0 ][ a_cnt ]; a_cnt++ ) { + AttributeDescription *desc = NULL; + Modifications *mod_tmp; + + rc = slap_bv2ad( &new_rdn[ 0 ][ a_cnt ]->la_attr, + &desc, &text ); + + if ( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "slap_modrdn2modlist: %s: %s (new)\n", + text, + new_rdn[ 0 ][ a_cnt ]->la_attr.bv_val, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_modrdn2modlist: %s: %s (new)\n", + text, + new_rdn[ 0 ][ a_cnt ]->la_attr.bv_val, 0 ); +#endif + goto done; + } + + /* ACL check of newly added attrs */ + if ( be && !access_allowed( be, conn, op, e, desc, + &new_rdn[ 0 ][ a_cnt ]->la_value, ACL_WRITE, NULL ) ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "slap_modrdn2modlist: access to attr \"%s\" " + "(new) not allowed\n", + new_rdn[ 0 ][a_cnt]->la_attr.bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_modrdn2modlist: access to attr \"%s\" " + "(new) not allowed\n", + new_rdn[ 0 ][ a_cnt ]->la_attr.bv_val, 0, 0 ); +#endif + rc = LDAP_INSUFFICIENT_ACCESS; + goto done; + } + + /* Apply modification */ + mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) + + 2 * sizeof( struct berval ) ); + mod_tmp->sml_desc = desc; + mod_tmp->sml_bvalues = ( BerVarray )( mod_tmp + 1 ); + mod_tmp->sml_bvalues[ 0 ] = new_rdn[ 0 ][ a_cnt ]->la_value; + mod_tmp->sml_bvalues[ 1 ].bv_val = NULL; + mod_tmp->sml_op = SLAP_MOD_SOFTADD; + mod_tmp->sml_next = mod; + mod = mod_tmp; + } + + /* Remove old rdn value if required */ + if ( deleteoldrdn ) { + for ( d_cnt = 0; old_rdn[ 0 ][ d_cnt ]; d_cnt++ ) { + AttributeDescription *desc = NULL; + Modifications *mod_tmp; + + rc = slap_bv2ad( &old_rdn[ 0 ][ d_cnt ]->la_attr, + &desc, &text ); + + if ( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "slap_modrdn2modlist: %s: %s (old)\n", + text, + old_rdn[ 0 ][ d_cnt ]->la_attr.bv_val, + 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_modrdn2modlist: %s: %s (old)\n", + text, + old_rdn[ 0 ][ d_cnt ]->la_attr.bv_val, + 0 ); +#endif + goto done; + } + + /* ACL check of newly added attrs */ + if ( be && !access_allowed( be, conn, op, e, desc, + &old_rdn[ 0 ][ d_cnt ]->la_value, ACL_WRITE, + NULL ) ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, + "slap_modrdn2modlist: access " + "to attr \"%s\" (old) not allowed\n", + old_rdn[ 0 ][ d_cnt ]->la_attr.bv_val, + 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_modrdn2modlist: access " + "to attr \"%s\" (old) not allowed\n", + old_rdn[ 0 ][ d_cnt ]->la_attr.bv_val, + 0, 0 ); +#endif + rc = LDAP_INSUFFICIENT_ACCESS; + goto done; + } + + /* Apply modification */ + mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) + + 2 * sizeof ( struct berval ) ); + mod_tmp->sml_desc = desc; + mod_tmp->sml_bvalues = ( BerVarray )(mod_tmp+1); + mod_tmp->sml_bvalues[ 0 ] + = old_rdn[ 0 ][ d_cnt ]->la_value; + mod_tmp->sml_bvalues[ 1 ].bv_val = NULL; + mod_tmp->sml_op = LDAP_MOD_DELETE; + mod_tmp->sml_next = mod; + mod = mod_tmp; + } + } + +done: + /* LDAP v2 supporting correct attribute handling. */ + if ( rc != LDAP_SUCCESS && mod != NULL ) { + Modifications *tmp; + for ( ; mod; mod = tmp ) { + tmp = mod->sml_next; + ch_free( mod ); + } + } + + *pmod = mod; + + return rc; +}