From 9ebe788370f61af0dca7e9fd540350027155dd2d Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Mon, 11 Feb 2008 17:29:55 +0000 Subject: [PATCH] ITS#5344: modrdn check for affectsMultipleDSAs and for new DN above/below self --- servers/slapd/modrdn.c | 35 +++++++++++++++--------- tests/data/slapd-2db.conf | 52 ++++++++++++++++++++++++++++++++++++ tests/scripts/defines.sh | 1 + tests/scripts/test005-modrdn | 32 +++++++++++++++++----- 4 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 tests/data/slapd-2db.conf diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index e6cb031811..ef124ec311 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -214,9 +214,9 @@ cleanup: int fe_op_modrdn( Operation *op, SlapReply *rs ) { - Backend *newSuperior_be = NULL; - struct berval pdn = BER_BVNULL; + struct berval dest_ndn = BER_BVNULL, dest_pndn, pdn = BER_BVNULL; BackendDB *op_be, *bd = op->o_bd; + ber_slen_t diff; if( op->o_req_ndn.bv_len == 0 ) { Debug( LDAP_DEBUG_ANY, "%s do_modrdn: root dse!\n", @@ -234,6 +234,23 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) goto cleanup; } + if( op->orr_nnewSup ) { + dest_pndn = *op->orr_nnewSup; + } else { + dnParent( &op->o_req_ndn, &dest_pndn ); + } + build_new_dn( &dest_ndn, &dest_pndn, &op->orr_nnewrdn, op->o_tmpmemctx ); + + diff = (ber_slen_t) dest_ndn.bv_len - (ber_slen_t) op->o_req_ndn.bv_len; + if ( diff > 0 ? dnIsSuffix( &dest_ndn, &op->o_req_ndn ) + : diff < 0 && dnIsSuffix( &op->o_req_ndn, &dest_ndn ) ) + { + send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, + diff > 0 ? "cannot place an entry below itself" + : "cannot place an entry above itself" ); + goto cleanup; + } + /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" @@ -275,19 +292,11 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) goto cleanup; } - /* Make sure that the entry being changed and the newSuperior are in - * the same backend, otherwise we return an error. - */ - if( op->orr_newSup ) { - newSuperior_be = select_backend( op->orr_nnewSup, 0 ); - - if ( newSuperior_be != op->o_bd ) { - /* newSuperior is in different backend */ + /* check that destination DN is in the same backend as source DN */ + if ( select_backend( &dest_ndn, 0 ) != op->o_bd ) { send_ldap_error( op, rs, LDAP_AFFECTS_MULTIPLE_DSAS, "cannot rename between DSAs" ); - goto cleanup; - } } /* @@ -367,6 +376,8 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) } cleanup:; + if ( dest_ndn.bv_val != NULL ) + ber_memfree_x( dest_ndn.bv_val, op->o_tmpmemctx ); op->o_bd = bd; return rs->sr_err; } diff --git a/tests/data/slapd-2db.conf b/tests/data/slapd-2db.conf new file mode 100644 index 0000000000..92a5fbebd9 --- /dev/null +++ b/tests/data/slapd-2db.conf @@ -0,0 +1,52 @@ +# stand-alone slapd config -- for testing (with indexing) +# $OpenLDAP$ +## This work is part of OpenLDAP Software . +## +## Copyright 1998-2008 The OpenLDAP Foundation. +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted only as authorized by the OpenLDAP +## Public License. +## +## A copy of this license is available in the file LICENSE in the +## top-level directory of the distribution or, alternatively, at +## . + +include @SCHEMADIR@/core.schema +include @SCHEMADIR@/cosine.schema +include @SCHEMADIR@/inetorgperson.schema +include @SCHEMADIR@/openldap.schema +# +pidfile @TESTDIR@/slapd.1.pid +argsfile @TESTDIR@/slapd.1.args + +#mod#modulepath ../servers/slapd/back-@BACKEND@/ +#mod#moduleload back_@BACKEND@.la +#monitormod#modulepath ../servers/slapd/back-monitor/ +#monitormod#moduleload back_monitor.la + +####################################################################### +# database definitions +####################################################################### + +database @BACKEND@ +suffix "cn=Everyone,ou=Groups,dc=example,dc=com" +directory @TESTDIR@/db.1.a +subordinate +#bdb#index objectClass eq +#bdb#index cn,sn,uid pres,eq,sub +#hdb#index objectClass eq +#hdb#index cn,sn,uid pres,eq,sub + +database @BACKEND@ +suffix "dc=example,dc=com" +directory @TESTDIR@/db.1.b +rootdn "cn=Manager,dc=example,dc=com" +rootpw secret +#bdb#index objectClass eq +#bdb#index cn,sn,uid pres,eq,sub +#hdb#index objectClass eq +#hdb#index cn,sn,uid pres,eq,sub + +#monitor#database monitor diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh index 6c56f02440..b39ae28c0e 100755 --- a/tests/scripts/defines.sh +++ b/tests/scripts/defines.sh @@ -77,6 +77,7 @@ CLIENTDIR=../clients/tools # conf CONF=$DATADIR/slapd.conf CONFTWO=$DATADIR/slapd2.conf +CONF2DB=$DATADIR/slapd-2db.conf MCONF=$DATADIR/slapd-master.conf COMPCONF=$DATADIR/slapd-component.conf PWCONF=$DATADIR/slapd-pw.conf diff --git a/tests/scripts/test005-modrdn b/tests/scripts/test005-modrdn index e30c8431a0..b334ad0bba 100755 --- a/tests/scripts/test005-modrdn +++ b/tests/scripts/test005-modrdn @@ -16,11 +16,11 @@ echo "running defines.sh" . $SRCDIR/scripts/defines.sh -mkdir -p $TESTDIR $DBDIR1 +mkdir -p $TESTDIR $DBDIR1A $DBDIR1B echo "Running slapadd to build slapd database..." -. $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1 -$SLAPADD -f $CONF1 -l $LDIFORDERED +. $CONFFILTER $BACKEND $MONITORDB < $CONF2DB > $CONF1 +$SLAPADD -f $CONF1 -b "$BASEDN" -l $LDIFORDERED RC=$? if test $RC != 0 ; then echo "slapadd failed ($RC)!" @@ -221,9 +221,28 @@ if test $? != 0 ; then exit -1 fi -echo "Testing modrdn with newSuperior as child of target " +echo "Testing modrdn to another database (should fail with affectsMultipleDSAs)" $LDAPMODRDN -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ - $TESTOUT 2>&1 -s 'cn=Sub1, ou=FooBar, cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' \ + $TESTOUT 2>&1 'cn=All Staff,ou=Groups,dc=example,dc=com' 'cn=Everyone' +RC=$? +case $RC in +0) + echo "ldapmodrdn succeeded, should have failed!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit -1 + ;; +71) + ;; +*) + echo "ldapmodrdn failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC + ;; +esac + +echo "Testing modrdn with newSuperior = target (should fail with unwillingToPerform)" +$LDAPMODRDN -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ + $TESTOUT 2>&1 -s 'cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' \ 'cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example, dc=com' 'cn=James A Jones 1' RC=$? @@ -233,8 +252,7 @@ case $RC in test $KILLSERVERS != no && kill -HUP $KILLPIDS exit -1 ;; -32) - echo "ldapmodrdn failed (noSuchObject)" +53) ;; *) echo "ldapmodrdn failed ($RC)!" -- 2.39.5