]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldbm/modrdn.c
Import fix for ITS#31: slapd/ldbm/delete initialization bug
[openldap] / servers / slapd / back-ldbm / modrdn.c
index fcd9fcc35a6f6c14ca2444386ed6f2eb48d093fb..d4209177c4ed2af0aabd1af134516321b50ecd15 100644 (file)
@@ -1,14 +1,15 @@
 /* modrdn.c - ldbm backend modrdn routine */
 
+#include "portable.h"
+
 #include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
 #include "slap.h"
 #include "back-ldbm.h"
-
-extern Entry   *dn2entry();
-extern char    *dn_parent();
+#include "proto-back-ldbm.h"
 
 int
 ldbm_back_modrdn(
@@ -24,10 +25,12 @@ ldbm_back_modrdn(
        char            *matched;
        char            *pdn, *newdn, *p;
        char            sep[2];
-       Entry           *e, *e2;
+       Entry           *e;
 
        matched = NULL;
-       if ( (e = dn2entry( be, dn, &matched )) == NULL ) {
+
+       /* get entry with writer lock */
+       if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
                send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, "" );
                if ( matched != NULL ) {
                        free( matched );
@@ -57,21 +60,16 @@ ldbm_back_modrdn(
                        strcat( newdn, pdn );
                }
        } else {
-               newdn = strdup( newrdn );
+               newdn = ch_strdup( newrdn );
        }
        (void) dn_normalize( newdn );
 
-       matched = NULL;
-       if ( (e2 = dn2entry( be, newdn, &matched )) != NULL ) {
+       /* get entry with writer lock */
+       if ( (dn2id ( be, newdn ) ) != NOID ) {
                free( newdn );
                free( pdn );
                send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, NULL, NULL );
-               cache_return_entry( &li->li_cache, e2 );
-               cache_return_entry( &li->li_cache, e );
-               return( -1 );
-       }
-       if ( matched != NULL ) {
-               free( matched );
+               goto error_return;
        }
 
        /* check for abandon */
@@ -80,9 +78,7 @@ ldbm_back_modrdn(
                pthread_mutex_unlock( &op->o_abandonmutex );
                free( newdn );
                free( pdn );
-               cache_return_entry( &li->li_cache, e2 );
-               cache_return_entry( &li->li_cache, e );
-               return( -1 );
+               goto error_return;
        }
        pthread_mutex_unlock( &op->o_abandonmutex );
 
@@ -91,8 +87,7 @@ ldbm_back_modrdn(
                free( newdn );
                free( pdn );
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL );
-               cache_return_entry( &li->li_cache, e );
-               return( -1 );
+               goto error_return;
        }
 
        /* delete old one */
@@ -100,8 +95,7 @@ ldbm_back_modrdn(
                free( newdn );
                free( pdn );
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL );
-               cache_return_entry( &li->li_cache, e );
-               return( -1 );
+               goto error_return;
        }
 
        (void) cache_delete_entry( &li->li_cache, e );
@@ -120,13 +114,19 @@ ldbm_back_modrdn(
        /* id2entry index */
        if ( id2entry_add( be, e ) != 0 ) {
                entry_free( e );
-
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, "", "" );
-               return( -1 );
+               goto error_return;
        }
        free( pdn );
-       cache_return_entry( &li->li_cache, e );
+
+       /* free entry and writer lock */
+       cache_return_entry_w( &li->li_cache, e );
        send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
 
        return( 0 );
+
+error_return:
+       /* free entry and writer lock */
+       cache_return_entry_w( &li->li_cache, e );
+       return( -1 );
 }