X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fmodrdn.c;h=84f08f464af43ff48c55013c42faae311fc0d2af;hb=b94d5e17e22b58b990dac4d4af5319be915366a6;hp=0b6fa4d5f5df3d3b01fdb8c15733eac78199b41e;hpb=7087a8f58d4e6239b88d1dc5e56bf06e77572351;p=openldap diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 0b6fa4d5f5..84f08f464a 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -1,31 +1,34 @@ /* $OpenLDAP$ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ -/* - * Copyright (c) 1995 Regents of the University of Michigan. +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2004 The OpenLDAP Foundation. * All rights reserved. * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is given - * to the University of Michigan at Ann Arbor. The name of the University - * may not be used to endorse or promote products derived from this - * software without specific prior written permission. This software - * is provided ``as is'' without express or implied warranty. - */ - -/* - * LDAP v3 newSuperior support. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. * - * Copyright 1999, Juan C. Gomez, All rights reserved. + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright 1999, Juan C. Gomez, All rights reserved. * This software is not subject to any license of Silicon Graphics * Inc. or Purdue University. * * Redistribution and use in source and binary forms are permitted * without restriction or fee of any kind as long as this notice * is preserved. + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" @@ -38,7 +41,7 @@ #include "ldap_pvt.h" #include "slap.h" #ifdef LDAP_SLAPI -#include "slapi.h" +#include "slapi/slapi.h" #endif int @@ -47,22 +50,25 @@ do_modrdn( SlapReply *rs ) { - struct berval dn = { 0, NULL }; - struct berval newrdn = { 0, NULL }; - struct berval newSuperior = { 0, NULL }; + struct berval dn = BER_BVNULL; + struct berval newrdn = BER_BVNULL; + struct berval newSuperior = BER_BVNULL; ber_int_t deloldrdn; - struct berval pnewSuperior = { 0, NULL }; + struct berval pnewSuperior = BER_BVNULL; - struct berval nnewSuperior = { 0, NULL }; + struct berval nnewSuperior = BER_BVNULL; Backend *newSuperior_be = NULL; ber_len_t length; int manageDSAit; -#ifdef LDAP_SLAPI - Slapi_PBlock *pb = op->o_pb; -#endif + struct berval pdn = BER_BVNULL; + struct berval org_req_dn = BER_BVNULL; + struct berval org_req_ndn = BER_BVNULL; + struct berval org_dn = BER_BVNULL; + struct berval org_ndn = BER_BVNULL; + int org_managedsait; #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 ); @@ -230,7 +236,7 @@ do_modrdn( goto cleanup; } - if( rdnValidate( &op->orr_newrdn ) != LDAP_SUCCESS ) { + if( rdn_validate( &op->orr_newrdn ) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "do_modrdn: invalid rdn (%s).\n", op->orr_newrdn.bv_val, 0, 0 ); @@ -271,7 +277,8 @@ do_modrdn( * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ - if ( (op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 )) == NULL ) { + op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 ); + if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); if (!rs->sr_ref) rs->sr_ref = default_referral; @@ -283,7 +290,7 @@ do_modrdn( if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref ); } else { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + "no global superior knowledge" ); } goto cleanup; } @@ -315,32 +322,35 @@ do_modrdn( } #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( 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 *)manageDSAit ); - - rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_MODRDN_FN, pb ); - if ( rs->sr_err < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ +#define pb op->o_pb + if ( pb ) { + slapi_int_pblock_set_operation( 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 *)manageDSAit ); + + rs->sr_err = slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_PRE_MODRDN_FN, pb ); + if ( rs->sr_err < 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 ); + 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); + Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin " + "failed.\n", 0, 0, 0); #endif - if ( ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = LDAP_OTHER; + if ( ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || + rs->sr_err == LDAP_SUCCESS ) { + rs->sr_err = LDAP_OTHER; + } + goto cleanup; } - goto cleanup; } #endif /* defined( LDAP_SLAPI ) */ @@ -352,36 +362,60 @@ do_modrdn( */ if ( op->o_bd->be_modrdn ) { /* do the update here */ - int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); -#if defined(LDAP_SYNCREPL) && !defined(SLAPD_MULTIMASTER) - if ( !op->o_bd->syncinfo && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) -#elif defined(LDAP_SYNCREPL) && defined(SLAPD_MULTIMASTER) - if ( !op->o_bd->syncinfo ) /* LDAP_SYNCREPL overrides MM */ -#elif !defined(LDAP_SYNCREPL) && !defined(SLAPD_MULTIMASTER) - if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) + int repl_user = be_isupdate( op ); +#ifndef SLAPD_MULTIMASTER + if ( !SLAP_SHADOW(op->o_bd) || repl_user ) #endif { + slap_callback cb = { NULL, slap_replog_cb, NULL, NULL }; op->orr_deleteoldrdn = deloldrdn; - if ( (op->o_bd->be_modrdn)( op, rs ) == 0 #ifdef SLAPD_MULTIMASTER - && ( !op->o_bd->be_update_ndn.bv_len || !repl_user ) -#endif - ) { - replog( op ); - } -#if defined(LDAP_SYNCREPL) || !defined(SLAPD_MULTIMASTER) - } else { - BerVarray defref = NULL; -#ifdef LDAP_SYNCREPL - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->masteruri_bv; - } else + if ( !op->o_bd->be_update_ndn.bv_len || !repl_user ) #endif { - defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; + cb.sc_next = op->o_callback; + op->o_callback = &cb; + } + op->o_bd->be_modrdn( op, rs ); + + if ( op->o_bd->be_delete ) { + org_req_dn = op->o_req_dn; + org_req_ndn = op->o_req_ndn; + org_dn = op->o_dn; + org_ndn = op->o_ndn; + org_managedsait = get_manageDSAit( op ); + op->o_dn = op->o_bd->be_rootdn; + op->o_ndn = op->o_bd->be_rootndn; + op->o_managedsait = 1; + + while ( rs->sr_err == LDAP_SUCCESS && + op->o_delete_glue_parent ) { + op->o_delete_glue_parent = 0; + if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) { + slap_callback cb = { NULL }; + cb.sc_response = slap_null_cb; + dnParent( &op->o_req_ndn, &pdn ); + op->o_req_dn = pdn; + op->o_req_ndn = pdn; + op->o_callback = &cb; + op->o_bd->be_delete( op, rs ); + } else { + break; + } + } + op->o_managedsait = org_managedsait; + op->o_dn = org_dn; + op->o_ndn = org_ndn; + op->o_req_dn = org_req_dn; + op->o_req_ndn = org_req_ndn; + op->o_delete_glue_parent = 0; } + +#ifndef SLAPD_MULTIMASTER + } else { + BerVarray defref = op->o_bd->be_update_refs + ? op->o_bd->be_update_refs : default_referral; + if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); @@ -392,9 +426,8 @@ do_modrdn( if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref ); } else { - send_ldap_error( op, rs, - LDAP_UNWILLING_TO_PERFORM, - "referral missing" ); + send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, + "shadow context; no update referral" ); } #endif } @@ -404,7 +437,7 @@ do_modrdn( } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) < 0 ) { + if ( pb != NULL && slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn postoperation plugins " "failed\n", 0, 0, 0 ); @@ -416,6 +449,9 @@ do_modrdn( #endif /* defined( LDAP_SLAPI ) */ cleanup: + + slap_graduate_commit_csn( op ); + op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); @@ -438,11 +474,15 @@ slap_modrdn2mods( Modifications **pmod ) { Modifications *mod = NULL; + Modifications **modtail = &mod; int a_cnt, d_cnt; + int repl_user; assert( new_rdn != NULL ); assert( !op->orr_deleteoldrdn || old_rdn != NULL ); + repl_user = be_isupdate( op ); + /* Add new attribute values to the entry */ for ( a_cnt = 0; new_rdn[a_cnt]; a_cnt++ ) { AttributeDescription *desc = NULL; @@ -493,7 +533,7 @@ slap_modrdn2mods( if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = &mod_tmp->sml_values[2]; (void) (*desc->ad_type->sat_equality->smr_normalize)( - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], @@ -562,7 +602,7 @@ slap_modrdn2mods( if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = &mod_tmp->sml_values[2]; (void) (*desc->ad_type->sat_equality->smr_normalize)( - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], @@ -578,6 +618,21 @@ slap_modrdn2mods( } done: + + if ( !repl_user ) { + char textbuf[ SLAP_TEXT_BUFLEN ]; + size_t textlen = sizeof textbuf; + + for( modtail = &mod; + *modtail != NULL; + modtail = &(*modtail)->sml_next ) + { + /* empty */ + } + + rs->sr_err = slap_mods_opattrs( op, mod, modtail, &rs->sr_text, textbuf, textlen ); + } + /* LDAP v2 supporting correct attribute handling. */ if ( rs->sr_err != LDAP_SUCCESS && mod != NULL ) { Modifications *tmp;