]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
ITS#7588 fix double-free for sorted paged search
[openldap] / servers / slapd / syncrepl.c
index 76ba66ebb7796515f078a4dea206dcb88de5b251..4ffb3621af8573e11516e33c078e32c105aa6984 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003-2012 The OpenLDAP Foundation.
+ * Copyright 2003-2013 The OpenLDAP Foundation.
  * Portions Copyright 2003 by IBM Corporation.
  * Portions Copyright 2003-2008 by Howard Chu, Symas Corporation.
  * All rights reserved.
@@ -112,6 +112,7 @@ typedef struct syncinfo_s {
        int                     si_logstate;
        int                     si_got;
        int                     si_strict_refresh;      /* stop listening during fallback refresh */
+       int                     si_too_old;
        ber_int_t       si_msgid;
        Avlnode                 *si_presentlist;
        LDAP                    *si_ld;
@@ -666,11 +667,11 @@ do_syncrep1(
 
                        LDAP_STAILQ_REMOVE( &slap_sync_cookie, sc, sync_cookie, sc_next );
 
-                       /* ctxcsn wasn't parsed yet, do it now */
-                       slap_parse_sync_cookie( sc, NULL );
                        slap_sync_cookie_free( &si->si_syncCookie, 0 );
-                       slap_dup_sync_cookie( &si->si_syncCookie, sc );
-                       slap_sync_cookie_free( sc, 1 );
+                       si->si_syncCookie.octet_str = sc->octet_str;
+                       ch_free( sc );
+                       /* ctxcsn wasn't parsed yet, do it now */
+                       slap_parse_sync_cookie( &si->si_syncCookie, NULL );
                } else {
                        ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
                        if ( !si->si_cookieState->cs_num ) {
@@ -935,8 +936,10 @@ do_syncrep2(
                                                                                si->si_ridtxt, syncCookie.ctxcsn->bv_val, bdn.bv_val );
                                                                        ldap_controls_free( rctrls );
                                                                        rc = 0;
+                                                                       si->si_too_old = 1;
                                                                        goto done;
                                                                }
+                                                               si->si_too_old = 0;
                                                                break;
                                                        }
                                                }
@@ -976,6 +979,13 @@ do_syncrep2(
                                                }
                                                assert( punlock < 0 );
                                                punlock = i;
+                                       } else if (si->si_too_old) {
+                                               bdn.bv_val[bdn.bv_len] = '\0';
+                                               Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN too old, ignoring (%s)\n",
+                                                       si->si_ridtxt, bdn.bv_val, 0 );
+                                               ldap_controls_free( rctrls );
+                                               rc = 0;
+                                               goto done;
                                        }
                                        op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                }
@@ -1334,6 +1344,9 @@ do_syncrep2(
                                ldap_memfree( retoid );
                                ber_bvfree( retdata );
 
+                               if ( rc )
+                                       goto done;
+
                        } else {
                                Debug( LDAP_DEBUG_ANY, "do_syncrep2: %s "
                                        "unknown intermediate response (%d)\n",
@@ -1353,8 +1366,8 @@ do_syncrep2(
                }
                if ( !BER_BVISNULL( &syncCookie.octet_str ) ) {
                        slap_sync_cookie_free( &syncCookie_req, 0 );
-                       slap_dup_sync_cookie( &syncCookie_req, &syncCookie );
-                       slap_sync_cookie_free( &syncCookie, 0 );
+                       syncCookie_req = syncCookie;
+                       memset( &syncCookie, 0, sizeof( syncCookie ));
                }
                ldap_msgfree( msg );
                msg = NULL;
@@ -1426,6 +1439,8 @@ do_syncrepl(
                        ldap_pvt_thread_yield();
        }
 
+       si->si_too_old = 0;
+
        if ( si->si_ctype < 1 ) {
                goto deleted;
        }
@@ -1962,6 +1977,7 @@ drop:
                                }
                        }
                        slap_mods_free( newmods, 1 );
+                       rx->rx_mods = oldmods;
                }
        }
        return LDAP_SUCCESS;