]> git.sur5r.net Git - openldap/commitdiff
1. Session history support
authorJong Hyuk Choi <jongchoi@openldap.org>
Mon, 10 Nov 2003 02:44:25 +0000 (02:44 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Mon, 10 Nov 2003 02:44:25 +0000 (02:44 +0000)
- memory based session history to minimize sync traffic
- when client is covered by a session history, then
      [add+delete] mode is used
- when client cookie is not covered by the history because
      the cookie is too outdated and/or the history is truncated,
  [add+present] mode is used
2. Sync cookie syntax : comma separated name=value pairs
- csn=yyyymmddhh:mm:ssZ#0xSSSS#r#ssssr,sid=nnn

28 files changed:
servers/slapd/Makefile.in
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/ctxcsn.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c
servers/slapd/config.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/ctxcsn.c
servers/slapd/globals.c
servers/slapd/ldapsync.c [new file with mode: 0644]
servers/slapd/main.c
servers/slapd/mods.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/schema_prep.c
servers/slapd/search.c
servers/slapd/sessionlog.c [new file with mode: 0644]
servers/slapd/slap.h
servers/slapd/syncrepl.c
servers/slapd/tools/Makefile.in
tests/data/slapd-syncrepl-master.conf
tests/data/slapd-syncrepl-slave-refresh1.conf

index b5b76a2ef173b045bb46bf4a700330c0ec27e2f6..2ece47608f9e08569ff874fce624d168525e0c87 100644 (file)
@@ -23,7 +23,7 @@ SRCS  = main.c globals.c config.c daemon.c \
                oidm.c starttls.c index.c sets.c referral.c root_dse.c \
                sasl.c module.c mra.c mods.c sl_malloc.c limits.c \
                backglue.c operational.c matchedValues.c cancel.c syncrepl.c \
-               backover.c ctxcsn.c $(@PLAT@_SRCS)
+               backover.c ctxcsn.c ldapsync.c sessionlog.c $(@PLAT@_SRCS)
 
 OBJS   = main.o globals.o config.o daemon.o \
                connection.o search.o filter.o add.o cr.o \
@@ -37,7 +37,7 @@ OBJS  = main.o globals.o config.o daemon.o \
                oidm.o starttls.o index.o sets.o referral.o root_dse.o \
                sasl.o module.o mra.o mods.o sl_malloc.o limits.o \
                backglue.o operational.o matchedValues.o cancel.o syncrepl.o \
-               backover.o ctxcsn.o $(@PLAT@_OBJS)
+               backover.o ctxcsn.o ldapsync.o sessionlog.o $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir)/slapi
 LDAP_LIBDIR= ../../libraries
index c393cdf968aa7bd3e0aa0db12da78a9940942c3f..bb6e2aeb2e1b4240a3f97ba65c3be40f8551ec38 100644 (file)
@@ -528,7 +528,7 @@ retry:      /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !noop ) {
+       if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch( op, rs, ps_list, op->oq_add.rs_e, LDAP_PSEARCH_BY_ADD );
                }
index 1a249f41e68f1030d2130bf00072d67447176a3c..76e130fb8863d69c2fa2ac3adca55835d78cc31f 100644 (file)
@@ -162,6 +162,8 @@ struct bdb_info {
        ID                      bi_lastid;
        ldap_pvt_thread_mutex_t bi_lastid_mutex;
        LDAP_LIST_HEAD(pl, slap_op) bi_psearch_list;
+       ldap_pvt_thread_mutex_t bi_pslist_mutex;
+       LDAP_LIST_HEAD(se, slap_session_entry) bi_session_list;
 #ifdef SLAP_IDL_CACHE
        int             bi_idl_cache_max_size;
        int             bi_idl_cache_size;
index d1bd93cd757d64a7d4427a2bf0b6b02effe54623..7fa83327ac9fa2fac9b34b1f2e9269c047aed93b 100644 (file)
@@ -127,31 +127,31 @@ bdb_db_config(
                if( rc != LDAP_SUCCESS ) return 1;
 
        /* unique key for shared memory regions */
-        } else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) {
-                 if ( argc < 2 ) {
-                         fprintf( stderr,
-                 "%s: line %d: missing key in \"shm_key <key>\" line\n",
-                             fname, lineno );
-                         return( 1 );
-                 }
-                 bdb->bi_shm_key = atoi( argv[1] );
+       } else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) {
+               if ( argc < 2 ) {
+                       fprintf( stderr,
+                               "%s: line %d: missing key in \"shm_key <key>\" line\n",
+                               fname, lineno );
+                       return( 1 );
+               }
+               bdb->bi_shm_key = atoi( argv[1] );
 
        /* size of the cache in entries */
-        } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
-                 if ( argc < 2 ) {
-                         fprintf( stderr,
-                 "%s: line %d: missing size in \"cachesize <size>\" line\n",
-                             fname, lineno );
-                         return( 1 );
-                 }
-                 bdb->bi_cache.c_maxsize = atoi( argv[1] );
+       } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
+               if ( argc < 2 ) {
+                       fprintf( stderr,
+                               "%s: line %d: missing size in \"cachesize <size>\" line\n",
+                               fname, lineno );
+                       return( 1 );
+               }
+               bdb->bi_cache.c_maxsize = atoi( argv[1] );
 
        /* depth of search stack cache in units of (IDL)s */
-        } else if ( strcasecmp( argv[0], "searchstack" ) == 0 ) {
+       } else if ( strcasecmp( argv[0], "searchstack" ) == 0 ) {
                if ( argc < 2 ) {
                        fprintf( stderr,
-               "%s: line %d: missing depth in \"searchstack <depth>\" line\n",
-                       fname, lineno );
+                               "%s: line %d: missing depth in \"searchstack <depth>\" line\n",
+                               fname, lineno );
                        return( 1 );
                }
                bdb->bi_search_stack_depth = atoi( argv[1] );
@@ -165,17 +165,82 @@ bdb_db_config(
 
 #ifdef SLAP_IDL_CACHE
        /* size of the IDL cache in entries */
-        } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) {
-                 if ( argc < 2 ) {
-                         fprintf( stderr,
-                 "%s: line %d: missing size in \"idlcachesize <size>\" line\n",
-                             fname, lineno );
-                         return( 1 );
-                 }
-                if ( !( slapMode & SLAP_TOOL_MODE ) )
-                        bdb->bi_idl_cache_max_size = atoi( argv[1] );
+       } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) {
+               if ( argc < 2 ) {
+                       fprintf( stderr,
+                               "%s: line %d: missing size in \"idlcachesize <size>\" line\n",
+                               fname, lineno );
+                       return( 1 );
+               }
+               if ( !( slapMode & SLAP_TOOL_MODE ) )
+                       bdb->bi_idl_cache_max_size = atoi( argv[1] );
 #endif
 
+       } else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) {
+               int se_id = 0, se_size = 0;
+               struct slap_session_entry *sent;
+               if ( argc < 3 ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT,
+                               "%s: line %d: missing arguments in \"sessionlog <id> <size>\""
+                               " line.\n", fname, lineno , 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s: line %d: missing arguments in \"sessionlog <id> <size>\""
+                               " line\n", fname, lineno, 0 );
+#endif
+                       return( 1 );
+               }
+
+               se_id = atoi( argv[1] );
+               se_size = atoi( argv[2] );
+
+               if ( se_id < 0 || se_id > 999 ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT,
+                               "%s: line %d: session log id %d is out of range [0..999]\n",
+                               fname, lineno , se_id );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s: line %d: session log id %d is out of range [0..999]\n",
+                               fname, lineno , se_id );
+#endif
+                       return( 1 );
+               }
+
+               if ( se_size < 0 || se_size > 999 ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT,
+                               "%s: line %d: session log size %d is negative\n",
+                               fname, lineno , se_size );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s: line %d: session log size %d is negative\n",
+                               fname, lineno , se_size );
+#endif
+                       return( 1 );
+               }
+
+               LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) {
+                       if ( sent->se_id == se_id ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                       "%s: line %d: session %d already exists\n",
+                                       fname, lineno , se_id );
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: line %d: session %d already exists\n",
+                                       fname, lineno , se_id );
+#endif
+                               return( 1 );
+                       }
+               }
+               sent = (struct slap_session_entry *) ch_calloc( 1,
+                                               sizeof( struct slap_session_entry ));
+               sent->se_id = se_id;
+               sent->se_size = se_size;
+               LDAP_LIST_INSERT_HEAD( &bdb->bi_session_list, sent, se_link );
+
        /* anything else */
        } else {
                fprintf( stderr, "%s: line %d: "
index a2cbadfd77a4ba414a318add02786d05a306dd6e..6d9af8c80b686ee4a791159babfb88b7839ccf6e 100644 (file)
@@ -262,6 +262,7 @@ bdb_get_commit_csn(
        int                     num_retries = 0;
        int                     ctxcsn_added = 0;
        int                     rc;
+       struct sync_cookie syncCookie = { NULL, -1, NULL};
 
        if ( op->o_sync_mode != SLAP_SYNC_NONE ) {
                if ( op->o_bd->be_syncinfo ) {
@@ -271,7 +272,8 @@ bdb_get_commit_csn(
                        ber_str2bv( substr, 0, 0, &bv );
                        build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &bv, NULL );
                } else {
-                       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], (struct berval *)&slap_ldapsync_cn_bv, NULL );
+                       build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0],
+                                               (struct berval *)&slap_ldapsync_cn_bv, NULL );
                }
 
 ctxcsn_retry :
@@ -330,7 +332,8 @@ txn_retry:
                                        return rs->sr_err;
                                }
 
-                               bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker );
+                               bdb_cache_add( bdb, suffix_ei, ctxcsn_e,
+                                               (struct berval *)&slap_ldapsync_cn_bv, locker );
 
                                rs->sr_err = TXN_COMMIT( ltid, 0 );
                                if ( rs->sr_err != 0 ) {
@@ -361,14 +364,24 @@ txn_retry:
                        if ( op->o_bd->be_syncinfo ) {
                                csn_a = attr_find( ctxcsn_e->e_attrs,
                                        slap_schema.si_ad_syncreplCookie );
+                               if ( csn_a ) {
+                                       struct berval cookie;
+                                       ber_dupbv( &cookie, &csn_a->a_vals[0] );
+                                       ber_bvarray_add( &syncCookie.octet_str, &cookie );
+                                       slap_parse_sync_cookie( &syncCookie );
+                                       *search_context_csn = ber_dupbv( NULL, syncCookie.ctxcsn );
+                                       slap_sync_cookie_free( &syncCookie, 0 );
+                               } else {
+                                       *search_context_csn = NULL;
+                               }
                        } else {
                                csn_a = attr_find( ctxcsn_e->e_attrs,
                                        slap_schema.si_ad_contextCSN );
-                       }
-                       if ( csn_a ) {
-                               *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] );
-                       } else {
-                               *search_context_csn = NULL;
+                               if ( csn_a ) {
+                                       *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] );
+                               } else {
+                                       *search_context_csn = NULL;
+                               }
                        }
                } else {
                        *search_context_csn = NULL;
index 5872be64eca1563f7c76f5aa95dfd239103835bf..fa25873ac7b1f5918c3f63b5a858a995edd7f90f 100644 (file)
@@ -540,7 +540,7 @@ retry:      /* transaction retry */
 return_results:
        send_ldap_result( op, rs );
 
-       if ( rs->sr_err == LDAP_SUCCESS && !noop ) {
+       if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) {
                LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE );
                }
index 79455549d5cf3e67c2963c174e03ba5f35fd439d..ba219deaa57b24151e9f368c37c1045f4eb3051e 100644 (file)
@@ -467,7 +467,7 @@ retry:      /* transaction retry */
                goto return_results;
        }
 
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch(op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
index b85d50a0af6f92d62b8800ddfc26a38f37310be4..18f14807aa7d7e2de4c1dad3a7220e0bbcf07327 100644 (file)
@@ -864,7 +864,7 @@ retry:      /* transaction retry */
                goto return_results;
        }
 
-       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
+       if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
                        bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
index f9e14ee5604ea8ac435ee4bafeefa42681e57feb..8fb4a1169867b019b74c0c1d5f56737abfe763d1 100644 (file)
@@ -548,30 +548,8 @@ int bdb_do_search(
 );
 #define        bdb_psearch(op, rs, sop, e, ps_type)    bdb_do_search(op, rs, sop, e, ps_type)
 
-#define bdb_build_sync_state_ctrl      BDB_SYMBOL(build_sync_state_ctrl)
-#define bdb_build_sync_done_ctrl       BDB_SYMBOL(build_sync_done_ctrl)
 #define bdb_send_ldap_intermediate     BDB_SYMBOL(send_ldap_intermediate)
 
-int
-bdb_build_sync_state_ctrl(
-       Operation       *op,
-       SlapReply               *rs,
-       Entry           *e,
-       int             entry_sync_state,
-       LDAPControl     **ctrls,
-       int             num_ctrls,
-       int             send_cookie,
-       struct berval   *csn     );
-
-int
-bdb_build_sync_done_ctrl(
-       Operation       *op,
-       SlapReply       *rs,
-       LDAPControl     **ctrls,
-       int             num_ctrls,
-       int             send_cookie,
-       struct berval   *latest_entrycsn_bv     );
-
 int
 bdb_send_ldap_intermediate(
        Operation   *op,
index e3cf6b03d8ac4c11ee45c4c1530a3b02290ee083..0cf8f48dcaccb34424f670f4ab585a15f59b7f53 100644 (file)
@@ -378,7 +378,6 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        AttributeName   *attrs;
 
        Filter          contextcsnand, contextcsnle, cookief, csnfnot, csnfeq, csnfand, csnfge;
-       Filter          omitcsnf, omitcsnfle;
        AttributeAssertion aa_ge, aa_eq, aa_le;
        int             entry_count = 0;
        struct berval *search_context_csn = NULL;
@@ -396,19 +395,86 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        u_int32_t       locker = 0;
        DB_LOCK         lock;
 
+       Operation       *ps_list;
+       int                     sync_send_present_mode = 1;
+       int                     match;
+       MatchingRule *mr;
+       const char *text;
+       int                     slog_found = 0;
+
 #ifdef NEW_LOGGING
-       LDAP_LOG( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
+       LDAP_LOG( OPERATION, ENTRY, "bdb_search\n", 0, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n",
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_search\n",
                0, 0, 0);
 #endif
        attrs = sop->oq_search.rs_attrs;
 
+       if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
+               struct slap_session_entry *sent;
+               if ( sop->o_sync_state.sid >= 0 ) {
+                       LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) {
+                               if ( sent->se_id == sop->o_sync_state.sid ) {
+                                       sop->o_sync_slog_size = sent->se_size;
+                                       break;
+                               }
+                       }
+               }
+       }
+
        /* psearch needs to be registered before refresh begins */
        /* psearch and refresh transmission is serialized in send_ldap_ber() */
        if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
+               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
                LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link );
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+       } else if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST
+                               && sop->o_sync_slog_size >= 0 ) {
+               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+               LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                       if ( ps_list->o_sync_slog_size >= 0 ) {
+                               if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) {
+                                       slog_found = 1;
+                                       break;
+                               }
+                       }
+               }
+
+               if ( slog_found ) {
+                       if ( ps_list->o_sync_slog_omitcsn.bv_len != 0 ) {
+                               mr = slap_schema.si_ad_entryCSN->ad_type->sat_ordering;
+                               if ( sop->o_sync_state.ctxcsn && sop->o_sync_state.ctxcsn->bv_val != NULL ) {
+                                        value_match( &match, slap_schema.si_ad_entryCSN, mr,
+                                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                                               sop->o_sync_state.ctxcsn, &ps_list->o_sync_slog_omitcsn,
+                                                               &text );
+                               } else {
+                                       match = -1;
+                               }
+                               if ( match >= 0 ) {
+                                       rs->sr_err = LDAP_SUCCESS;
+                                       rs->sr_rspoid = LDAP_SYNC_INFO;
+                                       rs->sr_ctrls = NULL;
+                                       bdb_send_ldap_intermediate( sop, rs,
+                                                       LDAP_SYNC_STATE_MODE_DONE, NULL );
+                                       sync_send_present_mode = 0;
+                               }
+                       } else {
+                               rs->sr_err = LDAP_SUCCESS;
+                               rs->sr_rspoid = LDAP_SYNC_INFO;
+                               rs->sr_ctrls = NULL;
+                               bdb_send_ldap_intermediate( sop, rs,
+                                               LDAP_SYNC_STATE_MODE_DONE, NULL );
+                               sync_send_present_mode = 0;
+                       }
+               } else if ( sop->o_sync_slog_size >= 0 ) {
+                       LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link );
+               } else {
+                       sop->o_sync_state.sid = -1;
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
        }
+
        null_attr.an_desc = NULL;
        null_attr.an_oc = NULL;
        null_attr.an_name.bv_len = 0;
@@ -670,8 +736,9 @@ dn2entry_retry:
                goto done;
        }
 
-       if ( sop->o_sync_state.bv_val && ber_bvcmp( &sop->o_sync_state, 
-               search_context_csn ) == 0 )
+       if ( sop->o_sync_mode != SLAP_SYNC_NONE && sop->o_sync_state.ctxcsn &&
+                sop->o_sync_state.ctxcsn->bv_val &&
+                ber_bvcmp( &sop->o_sync_state.ctxcsn[0], search_context_csn ) == 0 )
        {
                bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock );
                goto nochange;
@@ -777,8 +844,6 @@ dn2entry_retry:
 
        if ( (sop->o_sync_mode & SLAP_SYNC_REFRESH) || IS_PSEARCH )
        {
-               MatchingRule    *mr;
-               const char              *text;
                int                             match;
 
                cookief.f_choice = LDAP_FILTER_AND;
@@ -792,7 +857,11 @@ dn2entry_retry:
                csnfeq.f_choice = LDAP_FILTER_EQUALITY;
                csnfeq.f_ava = &aa_eq;
                csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
-               csnfeq.f_av_value = sop->o_sync_state;
+               if ( sop->o_sync_state.ctxcsn != NULL ) {
+                       csnfeq.f_av_value = *sop->o_sync_state.ctxcsn;
+               } else {
+                       csnfeq.f_av_value = slap_empty_bv;
+               }
 
                csnfand.f_choice = LDAP_FILTER_AND;
                csnfand.f_and = &csnfge;
@@ -801,7 +870,11 @@ dn2entry_retry:
                csnfge.f_choice = LDAP_FILTER_GE;
                csnfge.f_ava = &aa_ge;
                csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
-               csnfge.f_av_value = sop->o_sync_state;
+               if ( sop->o_sync_state.ctxcsn != NULL ) {
+                       csnfge.f_av_value = *sop->o_sync_state.ctxcsn;
+               } else {
+                       csnfge.f_av_value = slap_empty_bv;
+               }
 
                if ( search_context_csn && !IS_PSEARCH ) {
                        csnfge.f_next = &contextcsnand;
@@ -817,21 +890,23 @@ dn2entry_retry:
                        contextcsnle.f_next = sop->oq_search.rs_filter;
 
                        mr = slap_schema.si_ad_entryCSN->ad_type->sat_ordering;
-                       if ( sop->o_sync_state.bv_len != 0 ) {
+                       if ( sop->o_sync_state.ctxcsn &&
+                                sop->o_sync_state.ctxcsn->bv_val != NULL ) {
                                value_match( &match, slap_schema.si_ad_entryCSN, mr,
-                                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                                       &sop->o_sync_state, search_context_csn, &text );
+                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                               &sop->o_sync_state.ctxcsn[0], search_context_csn,
+                                               &text );
                        } else {
                                match = -1;
                        }
-                       no_sync_state_change = !match;
+                       no_sync_state_change = ( match >= 0 );
                } else {
                        csnfge.f_next = sop->oq_search.rs_filter;
                }
        }
 
        for ( id = bdb_idl_first( candidates, &cursor );
-               id != NOID;
+               id != NOID && !no_sync_state_change;
                id = bdb_idl_next( candidates, &cursor ) )
        {
                int             scopeok = 0;
@@ -1060,8 +1135,7 @@ id2entry_retry:
                } else {
                        if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
                                rc_sync = test_filter( sop, rs->sr_entry, &cookief );
-                               rs->sr_err = test_filter( sop,
-                                       rs->sr_entry, &contextcsnand );
+                               rs->sr_err = test_filter( sop, rs->sr_entry, &contextcsnand );
                                if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
                                        if ( rc_sync == LDAP_COMPARE_TRUE ) {
                                                if ( no_sync_state_change ) {
@@ -1091,7 +1165,8 @@ id2entry_retry:
 
                if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
                        /* check size limit */
-                       if ( --sop->oq_search.rs_slimit == -1 ) {
+            if ( --sop->oq_search.rs_slimit == -1 &&
+                 sop->o_sync_slog_size == -1 ) {
                                if (!IS_PSEARCH) {
                                        bdb_cache_return_entry_r( bdb->bi_dbenv,
                                                &bdb->bi_cache, e, &lock );
@@ -1157,49 +1232,82 @@ id2entry_retry:
                                                        } else {
                                                                entry_sync_state = LDAP_SYNC_ADD;
                                                        }
-                                               } else if ( ps_type == LDAP_PSEARCH_BY_SCOPEOUT )
+                                               } else if ( ps_type == LDAP_PSEARCH_BY_SCOPEOUT ) {
                                                        entry_sync_state = LDAP_SYNC_DELETE;
-                                               else {
+                                               else {
                                                        rs->sr_err = LDAP_OTHER;
                                                        goto done;
                                                }
-                                               rs->sr_err = bdb_build_sync_state_ctrl( sop,
-                                                       rs, e, entry_sync_state, ctrls,
-                                                       num_ctrls++, 1, search_context_csn );
-                                               if ( rs->sr_err != LDAP_SUCCESS ) goto done;
-                                               rs->sr_attrs = attrs;
-                                               rs->sr_ctrls = ctrls;
-                                               result = send_search_entry( sop, rs );
-                                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
-                                               ch_free( ctrls[--num_ctrls] );
-                                               ctrls[num_ctrls] = NULL;
-                                               rs->sr_ctrls = NULL;
-
+                                               if ( sop->o_sync_slog_size != -1 ) {
+                                                       if ( entry_sync_state == LDAP_SYNC_DELETE ) {
+                                                               result = slap_add_session_log( op, sop, e );
+                                                       } else {
+                                                               result = 1;
+                                                       }
+                                               } else {
+                                                       struct berval cookie;
+                                                       slap_compose_sync_cookie( sop, &cookie,
+                                                                               search_context_csn,
+                                                                               sop->o_sync_state.sid );
+                                                       rs->sr_err = slap_build_sync_state_ctrl( sop,
+                                                               rs, e, entry_sync_state, ctrls,
+                                                               num_ctrls++, 1, &cookie );
+                                                       if ( rs->sr_err != LDAP_SUCCESS ) goto done;
+                                                       rs->sr_attrs = attrs;
+                                                       rs->sr_ctrls = ctrls;
+                                                       result = send_search_entry( sop, rs );
+                                                       if ( cookie.bv_val )
+                                                               ch_free( cookie.bv_val );       
+                                                       ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                                                       ch_free( ctrls[--num_ctrls] );
+                                                       ctrls[num_ctrls] = NULL;
+                                                       rs->sr_ctrls = NULL;
+                                               }
                                        } else if ( ps_type == LDAP_PSEARCH_BY_PREMODIFY ) {
                                                struct psid_entry* psid_e;
-                                               psid_e = (struct psid_entry *) calloc (1,
+                                               psid_e = (struct psid_entry *) ch_calloc (1,
                                                        sizeof(struct psid_entry));
                                                psid_e->ps_op = sop;
                                                LDAP_LIST_INSERT_HEAD( &op->o_pm_list,
                                                        psid_e, ps_link );
 
                                        } else {
-                                               printf("Error !\n");
+#ifdef NEW_LOGGING
+                                               LDAP_LOG ( OPERATION, RESULTS,
+                                                       "bdb_search: invalid ps_type (%d) \n",
+                                                       ps_type, 0, 0);
+#else
+                                               Debug( LDAP_DEBUG_TRACE,
+                                                       "bdb_search: invalid ps_type (%d) \n",
+                                                       ps_type, 0, 0);
+#endif
                                        }
                                } else {
                                        if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
-                                               rs->sr_err = bdb_build_sync_state_ctrl( sop,
+                                               struct berval cookie;
+                                               slap_compose_sync_cookie( sop, &cookie,
+                                                                       search_context_csn,
+                                                                       sop->o_sync_state.sid );
+                                               rs->sr_err = slap_build_sync_state_ctrl( sop,
                                                        rs, e, entry_sync_state, ctrls,
-                                                       num_ctrls++, 0, search_context_csn );
+                                                       num_ctrls++, 0, &cookie );
                                                if ( rs->sr_err != LDAP_SUCCESS ) goto done;
 
                                                rs->sr_ctrls = ctrls;
                                                if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
                                                        rs->sr_attrs = sop->oq_search.rs_attrs;
+                                                       result = send_search_entry( sop, rs );
                                                } else { /* PRESENT */
-                                                       rs->sr_attrs = &null_attr;
+                                                       if ( sync_send_present_mode ) {
+                                                               rs->sr_attrs = &null_attr;
+                                                               result = send_search_entry( sop, rs );
+                                                       } else {
+                                                               result = 1;
+                                                       }
                                                }
-                                               result = send_search_entry( sop, rs );
+
+                                               if ( cookie.bv_val )
+                                                       ch_free( cookie.bv_val );       
                                                ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
                                                ch_free( ctrls[--num_ctrls] );
                                                ctrls[num_ctrls] = NULL;
@@ -1260,19 +1368,54 @@ nochange:
                        rs->sr_err = LDAP_SUCCESS;
                        rs->sr_rspoid = LDAP_SYNC_INFO;
                        rs->sr_ctrls = NULL;
-                       bdb_send_ldap_intermediate( sop, rs,
-                               LDAP_SYNC_STATE_MODE_DONE, search_context_csn );
+                       if ( sync_send_present_mode ) {
+                               struct berval cookie;
+                               slap_compose_sync_cookie( sop, &cookie,
+                                                                                 search_context_csn,
+                                                                                 sop->o_sync_state.sid );
+                               bdb_send_ldap_intermediate( sop, rs,
+                                       LDAP_SYNC_STATE_MODE_DONE, &cookie );
+                               if ( cookie.bv_val )
+                                       ch_free( cookie.bv_val );
+                       }
+
+                       if ( !sync_send_present_mode && !no_sync_state_change ) {
+                               int slog_found = 0;
+                               ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex );
+                               LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
+                                       if ( ps_list->o_sync_slog_size > 0 ) {
+                                               if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) {
+                                                       slog_found = 1;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               if ( slog_found ) {
+                                       slap_send_session_log( op, ps_list, rs );
+                               }
+                               ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex );
+                       }
 
-                       /* If changelog is supported, this is where to process it */
-       
                        if ( sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
                                /* refreshAndPersist mode */
+                               struct berval cookie;
+                               slap_compose_sync_cookie( sop, &cookie,
+                                                                                 search_context_csn,
+                                                                                 sop->o_sync_state.sid );
                                bdb_send_ldap_intermediate( sop, rs,
-                                       LDAP_SYNC_LOG_MODE_DONE, search_context_csn );
+                                       LDAP_SYNC_LOG_MODE_DONE, &cookie );
+                               if ( cookie.bv_val ) {
+                                       ch_free( cookie.bv_val );
+                               }
                        } else {
                                /* refreshOnly mode */
-                               bdb_build_sync_done_ctrl( sop, rs, ctrls,
-                                       num_ctrls++, 1, search_context_csn );
+                               struct berval cookie;
+                               slap_compose_sync_cookie( sop, &cookie,
+                                                                                 search_context_csn,
+                                                                                 sop->o_sync_state.sid );
+                               slap_build_sync_done_ctrl( sop, rs, ctrls,
+                                       num_ctrls++, 1, &cookie );
                                rs->sr_ctrls = ctrls;
                                rs->sr_ref = rs->sr_v2ref;
                                rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL;
@@ -1282,6 +1425,8 @@ nochange:
                                }
                                ch_free( ctrls[--num_ctrls] );
                                ctrls[num_ctrls] = NULL;
+                               if ( cookie.bv_val )
+                                       ch_free( cookie.bv_val );       
                        }
                } else {
                        rs->sr_ctrls = NULL;
@@ -1588,118 +1733,6 @@ done:
 }                      
 #endif
 
-int
-bdb_build_sync_state_ctrl(
-       Operation       *op,
-       SlapReply       *rs,
-       Entry           *e,
-       int                     entry_sync_state,
-       LDAPControl     **ctrls,
-       int                     num_ctrls,
-       int                     send_cookie,
-       struct berval   *csn)
-{
-       Attribute* a;
-       int ret;
-       int res;
-       const char *text = NULL;
-
-       BerElementBuffer berbuf;
-       BerElement *ber = (BerElement *)&berbuf;
-
-       struct berval entryuuid_bv      = { 0, NULL };
-
-       ber_init2( ber, 0, LBER_USE_DER );
-
-       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-               AttributeDescription *desc = a->a_desc;
-               if ( desc == slap_schema.si_ad_entryUUID ) {
-                       ber_dupbv( &entryuuid_bv, &a->a_vals[0] );
-               }
-       }
-
-       if ( send_cookie && csn ) {
-               ber_printf( ber, "{eOON}",
-                       entry_sync_state, &entryuuid_bv, csn );
-       } else {
-               ber_printf( ber, "{eON}",
-                       entry_sync_state, &entryuuid_bv );
-       }
-
-       ch_free( entryuuid_bv.bv_val );
-       entryuuid_bv.bv_val = NULL;
-
-       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
-       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
-       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-       ber_free_buf( ber );
-
-       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "bdb_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#endif
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return ret;
-       }
-
-       return LDAP_SUCCESS;
-}
-
-int
-bdb_build_sync_done_ctrl(
-       Operation       *op,
-       SlapReply       *rs,
-       LDAPControl     **ctrls,
-       int             num_ctrls,
-       int             send_cookie,
-       struct berval   *csn )
-{
-       int ret;
-       BerElementBuffer berbuf;
-       BerElement *ber = (BerElement *)&berbuf;
-
-       ber_init2( ber, NULL, LBER_USE_DER );
-
-       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-       if ( send_cookie && csn ) {
-               ber_printf( ber, "{ON}", csn );
-       } else {
-               ber_printf( ber, "{N}" );
-       }
-
-       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
-       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
-       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-       ber_free_buf( ber );
-
-       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "bdb_build_sync_done_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_build_sync_done_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#endif
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return ret;
-       }
-
-       return LDAP_SUCCESS;
-}
-
 int
 bdb_send_ldap_intermediate(
        Operation   *op,
index 347f3239b0c063b8d15c1d364ad2aab324d2c2e2..ea3d1a65f47a4c9d40b3b5666a8a3df6e084860b 100644 (file)
@@ -2797,8 +2797,9 @@ add_syncrepl(
        si->si_attrs[0] = NULL;
        si->si_type = LDAP_SYNC_REFRESH_ONLY;
        si->si_interval = 86400;
-       si->si_syncCookie.bv_val = NULL;
-       si->si_syncCookie.bv_len = 0;
+       si->si_syncCookie.ctxcsn = NULL;
+       si->si_syncCookie.octet_str = NULL;
+       si->si_syncCookie.sid = -1;
        si->si_manageDSAit = 0;
        si->si_tlimit = -1;
        si->si_slimit = -1;
@@ -2864,7 +2865,6 @@ add_syncrepl(
 #define ATTRSONLYSTR   "attrsonly"
 #define TYPESTR                        "type"
 #define INTERVALSTR            "interval"
-#define COOKIESTR              "cookie"
 #define LASTMODSTR             "lastmod"
 #define LMREQSTR               "req"
 #define LMGENSTR               "gen"
@@ -3104,15 +3104,10 @@ parse_syncrepl_line(
                                        (long) si->si_interval);
                                return 1;
                        }
-               } else if ( !strncasecmp( cargv[ i ],
-                       COOKIESTR, sizeof( COOKIESTR ) - 1 ) )
-               {
-                       val = cargv[ i ] + sizeof( COOKIESTR );
-                       ber_str2bv( val, 0, 1, &si->si_syncCookie );
                } else if ( !strncasecmp( cargv[ i ],
                        MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
                {
-                       val = cargv[ i ] + sizeof( COOKIESTR );
+                       val = cargv[ i ] + sizeof( MANAGEDSAITSTR );
                        si->si_manageDSAit = atoi( val );
                } else if ( !strncasecmp( cargv[ i ],
                        SLIMITSTR, sizeof( SLIMITSTR ) - 1 ) )
index c8d9814ab94aa72b74c51f997ddbaf6c2895d460..1044cf4bf1a532b3d9686c4077fc627a87d90e35 100644 (file)
@@ -928,6 +928,7 @@ connection_operation( void *ctx, void *arg_v )
 #endif /* SLAPD_MONITOR */
        Connection *conn = op->o_conn;
        void *memctx = NULL;
+       void *memctx_null = NULL;
        ber_len_t memsiz;
 
        ldap_pvt_thread_mutex_lock( &num_ops_mutex );
@@ -1098,20 +1099,25 @@ operations_error:
 
        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-       if ( op->o_cancel != SLAP_CANCEL_ACK && ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) {
+       ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
+
+       if ( op->o_cancel != SLAP_CANCEL_ACK &&
+                               ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) {
+               sl_mem_detach( ctx, memctx );
+       } else if (( op->o_sync_slog_size != -1 )) {
                sl_mem_detach( ctx, memctx );
-               goto no_co_op_free;
+               LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
+               LDAP_STAILQ_NEXT(op, o_next) = NULL;
+               conn->c_n_ops_executing--;
+               conn->c_n_ops_completed++;
+       } else {
+               LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
+               LDAP_STAILQ_NEXT(op, o_next) = NULL;
+               slap_op_free( op );
+               conn->c_n_ops_executing--;
+               conn->c_n_ops_completed++;
        }
 
-       LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
-       LDAP_STAILQ_NEXT(op, o_next) = NULL;
-
-       conn->c_n_ops_executing--;
-       conn->c_n_ops_completed++;
-       memctx = NULL;
-       ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx );
-       slap_op_free( op );
-
 no_co_op_free:
 
        switch( tag ) {
index 8bdecdeef3236edca1ca7b830055cc15402c276a..47916031656c9f1a62b7e37cc028ab59165d76e3 100644 (file)
@@ -1206,7 +1206,7 @@ static int parseLDAPsync (
        BerElement *ber;
        ber_int_t mode;
        ber_len_t len;
-       struct berval cookie = { 0, NULL };
+       struct slap_session_entry *se;
 
        if ( op->o_sync != SLAP_NO_CONTROL ) {
                rs->sr_text = "LDAP Sync control specified multiple times";
@@ -1256,22 +1256,20 @@ static int parseLDAPsync (
        tag = ber_peek_tag( ber, &len );
 
        if ( tag == LDAP_SYNC_TAG_COOKIE ) {
-               if (( ber_scanf( ber, /*{*/ "m}",
-                                       &cookie )) == LBER_ERROR ) {
+               struct berval tmp_bv;   
+               if (( ber_scanf( ber, /*{*/ "o}", &tmp_bv )) == LBER_ERROR ) {
                        rs->sr_text = "LDAP Sync control : cookie decoding error";
                        return LDAP_PROTOCOL_ERROR;
                }
+               ber_bvarray_add( &op->o_sync_state.octet_str, &tmp_bv );
+               slap_parse_sync_cookie( &op->o_sync_state );
        } else {
                if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
                        rs->sr_text = "LDAP Sync control : decoding error";
                        return LDAP_PROTOCOL_ERROR;
                }
-               cookie.bv_len = 0;
-               cookie.bv_val = NULL;
        }
 
-       ber_dupbv( &op->o_sync_state, &cookie );
-
        (void) ber_free( ber, 1 );
 
        op->o_sync_mode = (char) mode;
index 8b0b3e8917fc77ca1eb658e1de71ee3dddd0a8f8..71c7188bd3c9f2fd79a5863914ac57df545617b5 100644 (file)
@@ -193,6 +193,7 @@ slap_get_csn(
        if ( manage_ctxcsn ) {
                pending = (struct slap_csn_entry *) ch_calloc( 1, sizeof( struct slap_csn_entry ));
                ldap_pvt_thread_mutex_lock( &op->o_bd->be_pcl_mutex );
+               ber_dupbv( &op->o_sync_csn, csn );
                pending->csn = ber_dupbv( NULL, csn );
                pending->connid = op->o_connid;
                pending->opid = op->o_opid;
index fdc4c823a2a86df9d5393169368e6c80f6ecfd0e..1869805805b6daf01aeb11bc761d7ac5ab547f66 100644 (file)
@@ -25,3 +25,5 @@ const struct berval slap_unknown_bv = BER_BVC("unknown");
 /* normalized boolean values */
 const struct berval slap_true_bv = BER_BVC("TRUE");
 const struct berval slap_false_bv = BER_BVC("FALSE");
+
+struct sync_cookie *slap_sync_cookie = NULL;
diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c
new file mode 100644 (file)
index 0000000..a93d8e6
--- /dev/null
@@ -0,0 +1,377 @@
+/* $OpenLDAP$ */
+/*
+ * LDAP Content Sync Routines
+ */
+/*
+ * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Copyright (c) 2003 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "ldap_pvt.h"
+#include "lutil.h"
+#include "slap.h"
+#include "lutil_ldap.h"
+
+int
+slap_build_sync_state_ctrl(
+       Operation       *op,
+       SlapReply       *rs,
+       Entry           *e,
+       int                     entry_sync_state,
+       LDAPControl     **ctrls,
+       int                     num_ctrls,
+       int                     send_cookie,
+       struct berval   *csn)
+{
+       Attribute* a;
+       int ret;
+       int res;
+       const char *text = NULL;
+
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+
+       struct berval entryuuid_bv      = { 0, NULL };
+
+       ber_init2( ber, 0, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+               AttributeDescription *desc = a->a_desc;
+               if ( desc == slap_schema.si_ad_entryUUID ) {
+                       ber_dupbv( &entryuuid_bv, &a->a_vals[0] );
+               }
+       }
+
+       if ( send_cookie && csn ) {
+               ber_printf( ber, "{eOON}",
+                       entry_sync_state, &entryuuid_bv, csn );
+       } else {
+               ber_printf( ber, "{eON}",
+                       entry_sync_state, &entryuuid_bv );
+       }
+
+       ch_free( entryuuid_bv.bv_val );
+       entryuuid_bv.bv_val = NULL;
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+slap_build_sync_done_ctrl(
+       Operation       *op,
+       SlapReply       *rs,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       int             send_cookie,
+       struct berval   *csn )
+{
+       int ret;
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       if ( send_cookie && csn ) {
+               ber_printf( ber, "{ON}", csn );
+       } else {
+               ber_printf( ber, "{N}" );
+       }
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+
+int
+slap_build_sync_state_ctrl_from_slog(
+       Operation       *op,
+       SlapReply       *rs,
+       struct slog_entry *slog_e,
+       int                     entry_sync_state,
+       LDAPControl     **ctrls,
+       int                     num_ctrls,
+       int                     send_cookie,
+       struct berval   *csn)
+{
+       Attribute* a;
+       int ret;
+       int res;
+       const char *text = NULL;
+
+       BerElementBuffer berbuf;
+       BerElement *ber = (BerElement *)&berbuf;
+
+       struct berval entryuuid_bv      = { 0, NULL };
+
+       ber_init2( ber, 0, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid );
+
+       if ( send_cookie && csn ) {
+               ber_printf( ber, "{eOON}",
+                       entry_sync_state, &entryuuid_bv, csn );
+       } else {
+               ber_printf( ber, "{eON}",
+                       entry_sync_state, &entryuuid_bv );
+       }
+
+       ch_free( entryuuid_bv.bv_val );
+       entryuuid_bv.bv_val = NULL;
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+void
+slap_compose_sync_cookie(
+       Operation *op,
+       struct berval *cookie,
+       struct berval *csn,
+       int sid )
+{
+       char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 10 ];
+
+       if ( csn->bv_val == NULL ) {
+               if ( sid == -1 ) {
+                       cookiestr[0] = '\0';
+               } else {
+                       snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
+                                               "sid=%03d", sid );
+               }
+       } else if ( sid == -1 ) {
+               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
+                                               "csn=%s", csn->bv_val );
+       } else {
+               snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
+                                               "csn=%s,sid=%03d", csn->bv_val, sid );
+       }
+       ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie );
+}
+
+void
+slap_sync_cookie_free(
+       struct sync_cookie *cookie,
+       int free_cookie
+)
+{
+       if ( cookie == NULL )
+               return;
+
+       if ( cookie->ctxcsn ) {
+               ber_bvarray_free( cookie->ctxcsn );
+               cookie->ctxcsn = NULL;
+       }
+
+       if ( cookie->octet_str ) {
+               ber_bvarray_free( cookie->octet_str );
+               cookie->octet_str = NULL;
+       }
+
+       if ( free_cookie ) {
+               ch_free( cookie );
+       }
+
+       return;
+}
+
+int
+slap_parse_sync_cookie(
+       struct sync_cookie *cookie
+)
+{
+       char *csn_ptr;
+       char *csn_str;
+       char *sid_ptr;
+       char *sid_str;
+       char *cval;
+       struct berval *ctxcsn;
+
+       if ( cookie == NULL )
+               return -1;
+
+       if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) {
+               csn_str = (char *) strndup( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE );
+               if ( cval = strchr( csn_str, ',' )) {
+                       *cval = '\0';
+               }
+               ctxcsn = ber_str2bv( csn_str + 4, strlen(csn_str) - 4, 1, NULL );
+               ch_free( csn_str );
+               ber_bvarray_add( &cookie->ctxcsn, ctxcsn );
+               ch_free( ctxcsn );
+       } else {
+               cookie->ctxcsn = NULL;
+       }
+
+       if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) {
+               sid_str = (char *) strndup( sid_ptr, 7 );
+               if ( cval = strchr( sid_str, ',' )) {
+                       *cval = '\0';
+               }
+               cookie->sid = atoi( sid_str+4 );
+               ch_free( sid_str );
+       } else {
+               cookie->sid = -1;
+       }
+}
+
+int
+slap_init_sync_cookie_ctxcsn(
+       struct sync_cookie *cookie
+)
+{
+       char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ];
+       struct berval octet_str = { 0, NULL };
+       struct berval ctxcsn = { 0, NULL };
+       struct berval ctxcsn_dup = { 0, NULL };
+       struct berval slap_syncCookie;
+
+       if ( cookie == NULL )
+               return -1;
+
+       octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4,
+                                       "csn=%4d%02d%02d%02d:%02d:%02dZ#0x%04x#%d#%04x",
+                                       1900, 1, 1, 0, 0, 0, 0, 0, 0 );
+       octet_str.bv_val = csnbuf;
+       build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL );
+       ber_bvarray_free( cookie->octet_str );
+       cookie->octet_str = NULL;
+       ber_bvarray_add( &cookie->octet_str, &slap_syncCookie );
+
+       ber_dupbv( &ctxcsn, &octet_str );
+       ctxcsn.bv_val += 4;
+       ctxcsn.bv_len -= 4;
+       ber_dupbv( &ctxcsn_dup, &ctxcsn );
+       ch_free( ctxcsn.bv_val );
+       ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup );
+
+       return 0;
+}
+
+struct sync_cookie *
+slap_dup_sync_cookie(
+       struct sync_cookie *dst,
+       struct sync_cookie *src
+)
+{
+       int i;
+       struct sync_cookie *new;
+       struct berval tmp_bv;
+
+       if ( src == NULL )
+               return NULL;
+
+       if ( dst ) {
+               ber_bvarray_free( dst->ctxcsn );
+               ber_bvarray_free( dst->octet_str );
+               new = dst;
+       } else {
+               new = ( struct sync_cookie * )
+                               ch_calloc( 1, sizeof( struct sync_cookie ));
+       }
+
+       new->sid = src->sid;
+
+       if ( src->ctxcsn ) {
+               for ( i=0; src->ctxcsn[i].bv_val; i++ ) {
+                       ber_dupbv( &tmp_bv, &src->ctxcsn[i] );
+                       ber_bvarray_add( &new->ctxcsn, &tmp_bv );
+               }
+       }
+
+       if ( src->octet_str ) {
+               for ( i=0; src->octet_str[i].bv_val; i++ ) {
+                       ber_dupbv( &tmp_bv, &src->octet_str[i] );
+                       ber_bvarray_add( &new->octet_str, &tmp_bv );
+               }
+       }
+
+       return new;
+}
index 61dc82e12186bb0210fdedbaf51460e4b5c37de8..c15dee8c1dae1c8ae0bf296ba77a8cb26dadc2f8 100644 (file)
@@ -92,6 +92,7 @@ usage( char *name )
        fprintf( stderr,
                "\t-4\t\tIPv4 only\n"
                "\t-6\t\tIPv6 only\n"
+               "\t-c cookie\tSync cookie of consumer\n"
                "\t-d level\tDebug level" "\n"
                "\t-f filename\tConfiguration file\n"
 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
@@ -144,6 +145,8 @@ int main( int argc, char **argv )
        char        *serverName = NULL;
        int         serverMode = SLAP_SERVER_MODE;
 
+       struct berval cookie = { 0, NULL };
+
 #ifdef CSRIMALLOC
        FILE *leakfile;
        if( ( leakfile = fopen( "slapd.leak", "w" )) == NULL ) {
@@ -214,7 +217,7 @@ int main( int argc, char **argv )
 #endif
 
        while ( (i = getopt( argc, argv,
-                            "d:f:h:s:n:t"
+                            "c:d:f:h:s:n:t"
 #if LDAP_PF_INET6
                                "46"
 #endif
@@ -243,6 +246,16 @@ int main( int argc, char **argv )
                        urls = ch_strdup( optarg );
            break;
 
+               case 'c':       /* provide sync cookie, override if exist in replica */
+                       if ( slap_sync_cookie ) {
+                               slap_sync_cookie_free( slap_sync_cookie, 1 );
+                       }
+                       slap_sync_cookie = (struct sync_cookie *) ch_calloc( 1,
+                                                               sizeof( struct sync_cookie ));
+                       ber_str2bv( optarg, strlen( optarg ), 1, &cookie );
+                       ber_bvarray_add( &slap_sync_cookie->octet_str, &cookie );
+                       break;
+
                case 'd':       /* set debug level and 'do not detach' flag */
                        no_detach = 1;
 #ifdef LDAP_DEBUG
index 02d4bcb207883a7fe5daddb40b5731d1fc092447..1d2d9a800cc615514961f7b8b2f359d459989b60 100644 (file)
@@ -216,6 +216,7 @@ modify_delete_values(
        Attribute       *a;
        MatchingRule    *mr = mod->sm_desc->ad_type->sat_equality;
        char            dummy = '\0';
+       int                     match = 0;
 
        /*
         * If permissive is set, then the non-existence of an 
@@ -264,7 +265,6 @@ modify_delete_values(
        for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) {
                int     found = 0;
                for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
-                       int match;
 
                        if( mod->sm_nvalues ) {
                                assert( a->a_nvals );
index c144c19cfcc4b0a95b2fb2122c4236de73b6b882..ff6fbf3cc6203cdba7700cf58daa85f2219e4558 100644 (file)
@@ -42,6 +42,8 @@ void slap_op_destroy(void)
 void
 slap_op_free( Operation *op )
 {
+       struct berval slap_empty_bv_dup;
+
        assert( LDAP_STAILQ_NEXT(op, o_next) == NULL );
 
        if ( op->o_ber != NULL ) {
@@ -65,9 +67,8 @@ slap_op_free( Operation *op )
                ber_free( op->o_res_ber, 1 );
        }
 #endif
-       if ( op->o_sync_state.bv_val != NULL ) {
-               free( op->o_sync_state.bv_val );
-       }
+
+       slap_sync_cookie_free( &op->o_sync_state, 0 );
 
        {
                GroupAssertion *g, *n;
@@ -85,7 +86,14 @@ slap_op_free( Operation *op )
        }
 #endif /* defined( LDAP_SLAPI ) */
 
+       if ( op->o_sync_csn.bv_val != NULL ) {
+               ch_free( op->o_sync_csn.bv_val );
+       }
+
        memset( op, 0, sizeof(Operation) );
+
+       op->o_sync_state.sid = -1;
+       op->o_sync_slog_size = -1;
        ldap_pvt_thread_mutex_lock( &slap_op_mutex );
        LDAP_STAILQ_INSERT_HEAD( &slap_free_ops, op, o_next );
        ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
@@ -100,6 +108,7 @@ slap_op_alloc(
 )
 {
        Operation       *op;
+       struct berval slap_empty_bv_dup;
 
        ldap_pvt_thread_mutex_lock( &slap_op_mutex );
        if ((op = LDAP_STAILQ_FIRST( &slap_free_ops ))) {
@@ -107,8 +116,9 @@ slap_op_alloc(
        }
        ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
 
-       if (!op)
+       if (!op) {
                op = (Operation *) ch_calloc( 1, sizeof(Operation) );
+       }
 
        op->o_ber = ber;
        op->o_msgid = msgid;
@@ -118,6 +128,11 @@ slap_op_alloc(
        op->o_opid = id;
        op->o_res_ber = NULL;
 
+       op->o_sync_state.sid = -1;
+       op->o_sync_slog_size = -1;
+       LDAP_STAILQ_FIRST( &op->o_sync_slog_list ) = NULL;
+       op->o_sync_slog_list.stqh_last = &LDAP_STAILQ_FIRST( &op->o_sync_slog_list );
+
 #if defined( LDAP_SLAPI )
        if ( slapi_plugins_used ) {
                op->o_pb = slapi_pblock_new();
index 9ccc36220d398f18ba4cef496910b55eef0c07d5..3f88cf474620a03a08d26978044afd2a35262f6c 100644 (file)
@@ -551,6 +551,7 @@ LDAP_SLAPD_V( const struct berval ) slap_empty_bv;
 LDAP_SLAPD_V( const struct berval ) slap_unknown_bv;
 LDAP_SLAPD_V( const struct berval ) slap_true_bv;
 LDAP_SLAPD_V( const struct berval ) slap_false_bv;
+LDAP_SLAPD_V( struct sync_cookie * ) slap_sync_cookie;
 
 /*
  * index.c
@@ -575,6 +576,29 @@ LDAP_SLAPD_V (char *)      ldap_srvtab;
 LDAP_SLAPD_V (int)     krbv4_ldap_auth();
 #endif
 
+/*
+ * ldapsync.c
+ */
+LDAP_SLAPD_F (int) slap_build_sync_state_ctrl LDAP_P((
+                               Operation *, SlapReply *, Entry *, int, LDAPControl **,
+                               int, int, struct berval * ));
+LDAP_SLAPD_F (int) slap_build_sync_done_ctrl LDAP_P((
+                               Operation *, SlapReply *, LDAPControl **,
+                               int, int, struct berval * ));
+LDAP_SLAPD_F (int) slap_build_sync_state_ctrl_from_slog LDAP_P((
+                               Operation *, SlapReply *, struct slog_entry *, int,
+                               LDAPControl **, int, int, struct berval * ));
+LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P((
+                               Operation *, struct berval *, struct berval *, int ));
+LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P((
+                               struct sync_cookie *, int free_cookie ));
+LDAP_SLAPD_F (int) slap_parse_sync_cookie LDAP_P((
+                               struct sync_cookie * ));
+LDAP_SLAPD_F (int) slap_init_sync_cookie_ctxcsn LDAP_P((
+                               struct sync_cookie * ));
+LDAP_SLAPD_F (struct sync_cookie *) slap_dup_sync_cookie LDAP_P((
+                               struct sync_cookie *, struct sync_cookie * ));
+
 /*
  * limits.c
  */
@@ -1004,6 +1028,14 @@ LDAP_SLAPD_F (char *) scherr2str LDAP_P((int code)) LDAP_GCCATTR((const));
 LDAP_SLAPD_F (int) dscompare LDAP_P(( const char *s1, const char *s2del,
        char delim ));
 
+/*
+ * sessionlog.c
+ */
+LDAP_SLAPD_F (int) slap_send_session_log LDAP_P((
+                                       Operation *, Operation *, SlapReply *));
+LDAP_SLAPD_F (int) slap_add_session_log LDAP_P((
+                                       Operation *, Operation *, Entry * ));
+
 /*
  * sl_malloc.c
  */
@@ -1031,6 +1063,30 @@ LDAP_SLAPD_F (SLAP_EXTOP_MAIN_FN) starttls_extop;
 LDAP_SLAPD_F (Filter *) str2filter LDAP_P(( const char *str ));
 LDAP_SLAPD_F (Filter *) str2filter_x LDAP_P(( Operation *op, const char *str ));
 
+/*
+ * syncrepl.c
+ */
+
+LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq;
+
+LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *));
+LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *));
+LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P((
+                                       syncinfo_t *, Operation *, LDAPMessage *,
+                                       Modifications **, int ));
+LDAP_SLAPD_F (int) syncrepl_entry LDAP_P((
+                                       syncinfo_t *, Operation*, Entry*,
+                                       Modifications*,int, struct berval*,
+                                       struct sync_cookie *, int ));
+LDAP_SLAPD_F (void) syncrepl_updateCookie LDAP_P((
+                                       syncinfo_t *, Operation *, struct berval *,
+                                       struct sync_cookie * ));
+LDAP_SLAPD_F (void)  syncrepl_add_glue LDAP_P(( 
+                                       Operation*, Entry* ));
+LDAP_SLAPD_F (Entry*) slap_create_syncrepl_entry LDAP_P((
+                                       Backend *, struct berval *,
+                                       struct berval *, struct berval * ));
+
 /* syntax.c */
 LDAP_SLAPD_F (Syntax *) syn_find LDAP_P((
        const char *synname ));
@@ -1183,29 +1239,6 @@ LDAP_SLAPD_F (int) do_search LDAP_P((Operation *op, SlapReply *rs));
 LDAP_SLAPD_F (int) do_unbind LDAP_P((Operation *op, SlapReply *rs));
 LDAP_SLAPD_F (int) do_extended LDAP_P((Operation *op, SlapReply *rs));
 
-/*
- * syncrepl.c
- */
-
-LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq;
-
-LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *));
-LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *));
-LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P((
-                                       syncinfo_t *, Operation *, LDAPMessage *,
-                                       Modifications **, int ));
-LDAP_SLAPD_F (int) syncrepl_entry LDAP_P((
-                                       syncinfo_t *, Operation*, Entry*,
-                                       Modifications*,int, struct berval*, int ));
-LDAP_SLAPD_F (void) syncrepl_updateCookie LDAP_P((
-                                       syncinfo_t *, Operation *, struct berval *,
-                                       struct berval * ));
-LDAP_SLAPD_F (void)  syncrepl_add_glue LDAP_P(( 
-                                       Operation*, Entry* ));
-LDAP_SLAPD_F (Entry*) slap_create_syncrepl_entry LDAP_P((
-                                       Backend *, struct berval *,
-                                       struct berval *, struct berval * ));
-
 LDAP_END_DECL
 
 #endif /* PROTO_SLAP_H */
index 306015eea6179eb8cdb444ecb0514c93cd184ba9..d46cefa7090c0432a1c861a926bd080142fb034c 100644 (file)
@@ -423,7 +423,7 @@ static struct slap_schema_ad_map {
                        "DESC 'syncrepl Cookie for shadow copy' "
                        "EQUALITY octetStringMatch "
                        "ORDERING octetStringOrderingMatch "
-                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
                NULL, SLAP_AT_HIDE,
                NULL, NULL,
@@ -435,7 +435,7 @@ static struct slap_schema_ad_map {
                        "DESC 'the largest committed CSN of a context' "
                        "EQUALITY octetStringMatch "
                        "ORDERING octetStringOrderingMatch "
-                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
                        "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",
                NULL, SLAP_AT_HIDE,
                NULL, NULL,
index 39ca34f4b17eae260057f353906d94d74c88d9f4..2fdd461653bda58d3212c87bfc48deb1d3b3c5a8 100644 (file)
@@ -401,6 +401,9 @@ return_results:;
        if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
                return rs->sr_err;
 
+       if ( ( op->o_sync_slog_size != -1 ) )
+               return rs->sr_err;
+
        if( op->o_req_dn.bv_val != NULL) sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
        if( op->o_req_ndn.bv_val != NULL) sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 
diff --git a/servers/slapd/sessionlog.c b/servers/slapd/sessionlog.c
new file mode 100644 (file)
index 0000000..cb759ee
--- /dev/null
@@ -0,0 +1,140 @@
+/* $OpenLDAP$ */
+/*
+ * Session History Management Routines
+ */
+/*
+ * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Copyright (c) 2003 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "ldap_pvt.h"
+#include "lutil.h"
+#include "slap.h"
+#include "lutil_ldap.h"
+
+int
+slap_send_session_log(
+       Operation *op,
+       Operation *sop,
+       SlapReply *rs
+)
+{
+       Entry e;
+       AttributeName   uuid_attr[2];
+       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+       int             num_ctrls = 0;
+       struct slog_entry *slog_e;
+       int             result;
+       int             match;
+       const   char    *text;
+
+       uuid_attr[0].an_desc = NULL;
+       uuid_attr[0].an_oc = NULL;
+       uuid_attr[0].an_name.bv_len = 0;
+       uuid_attr[0].an_name.bv_val = NULL;
+       e.e_attrs = NULL;
+       e.e_id = 0;
+       e.e_name.bv_val = NULL;
+       e.e_name.bv_len = 0;
+       e.e_nname.bv_val = NULL;
+       e.e_nname.bv_len = 0;
+
+       for( num_ctrls = 0;
+                num_ctrls < SLAP_MAX_RESPONSE_CONTROLS;
+                num_ctrls++ ) {
+               ctrls[num_ctrls] = NULL;
+       }
+       num_ctrls = 0;
+
+       LDAP_STAILQ_FOREACH( slog_e, &sop->o_sync_slog_list, sl_link ) {
+
+               if ( op->o_sync_state.ctxcsn->bv_val == NULL ) {
+                       match = 1;
+               } else {
+                       value_match( &match, slap_schema.si_ad_entryCSN,
+                                               slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
+                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                               op->o_sync_state.ctxcsn, &slog_e->sl_csn, &text );
+               }
+
+               if ( match < 0 ) {
+                       rs->sr_err = slap_build_sync_state_ctrl_from_slog( op, rs, slog_e,
+                                                       LDAP_SYNC_DELETE, ctrls, num_ctrls++, 0, NULL );
+
+                       if ( rs->sr_err != LDAP_SUCCESS )
+                               return rs->sr_err;
+
+                       if ( e.e_name.bv_val )
+                               ch_free( e.e_name.bv_val );
+                       ber_dupbv( &e.e_name, &slog_e->sl_name );
+
+                       rs->sr_entry = &e;
+                       rs->sr_attrs = uuid_attr;
+                       rs->sr_ctrls = ctrls;
+                       result = send_search_entry( op, rs );
+                       ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                       ch_free( ctrls[--num_ctrls] );
+                       ctrls[num_ctrls] = NULL;
+                       rs->sr_ctrls = NULL;
+               }
+       }
+}
+
+int
+slap_add_session_log(
+       Operation *op,
+       Operation *sop,
+       Entry *e
+)
+{
+       struct slog_entry* slog_e;
+       Attribute *a;
+
+       slog_e = (struct slog_entry *) ch_calloc (1, sizeof( struct slog_entry ));
+       a = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );
+       ber_dupbv( &slog_e->sl_uuid, &a->a_vals[0] );
+       ber_dupbv( &slog_e->sl_name, &e->e_name );
+       ber_dupbv( &slog_e->sl_csn,  &op->o_sync_csn );
+       LDAP_STAILQ_INSERT_TAIL( &sop->o_sync_slog_list, slog_e, sl_link );
+       sop->o_sync_slog_len++;
+
+       while ( sop->o_sync_slog_len > sop->o_sync_slog_size ) {
+               slog_e = LDAP_STAILQ_FIRST( &sop->o_sync_slog_list );
+               if ( sop->o_sync_slog_omitcsn.bv_val ) {
+                       ch_free( sop->o_sync_slog_omitcsn.bv_val );
+               }
+               ber_dupbv( &sop->o_sync_slog_omitcsn, &slog_e->sl_csn );
+               LDAP_STAILQ_REMOVE_HEAD( &sop->o_sync_slog_list, sl_link );
+               ch_free( slog_e->sl_uuid.bv_val );
+               ch_free( slog_e->sl_name.bv_val );
+               ch_free( slog_e->sl_csn.bv_val );
+               ch_free( slog_e );
+               sop->o_sync_slog_len--;
+       }
+
+       return LDAP_SUCCESS;
+}
index 4be38925d1c99a53c9818327f4a93f557ceeb639..0b11e6e4f14de1067c88a06f7c041d680f120e9f 100644 (file)
@@ -1293,45 +1293,57 @@ struct nonpresent_entry {
        LDAP_LIST_ENTRY(nonpresent_entry) npe_link;
 };
 
+struct sync_cookie {
+       struct berval *ctxcsn;
+       long sid;
+       struct berval *octet_str;
+};
+
 /*
  * syncinfo structure for syncrepl
  */
 typedef struct syncinfo_s {
-       struct slap_backend_db *si_be;
-       unsigned int    si_id;
-       char                    *si_provideruri;
-       BerVarray               si_provideruri_bv;
-#define        SYNCINFO_TLS_OFF                0
-#define        SYNCINFO_TLS_ON                 1
-#define        SYNCINFO_TLS_CRITICAL   2
-       int                             si_tls;
-       struct  berval  si_updatedn;    
-       int                             si_bindmethod;
-       char                    *si_binddn;
-       char                    *si_passwd;
-       char                    *si_saslmech;
-       char                    *si_secprops;
-       char                    *si_realm;
-       char                    *si_authcId;
-       char                    *si_authzId;
-       int                             si_schemachecking;
-       Filter                  *si_filter;
-       struct berval   si_filterstr;
-       struct berval   si_base;
-       int                             si_scope;
-       int                             si_attrsonly;
-       char                    **si_attrs;
-       int                             si_type;
-       time_t                  si_interval;
-       struct berval   si_syncCookie;
-       int                             si_manageDSAit;
-       int                             si_slimit;
-       int                             si_tlimit;
-       struct berval   si_syncUUID_ndn;
-       Avlnode                 *si_presentlist;
-       int                             si_sync_mode;
-       LDAP                    *si_ld;
-       LDAP_LIST_HEAD(np,      nonpresent_entry) si_nonpresentlist;
+//        struct slap_conn *si_conn;
+        struct slap_backend_db *si_be;
+//        struct slap_entry *si_e;
+//        void                         *si_ctx;
+        unsigned int           si_id;
+        char                           *si_provideruri;
+        BerVarray                      si_provideruri_bv;
+#define SYNCINFO_TLS_OFF               0
+#define SYNCINFO_TLS_ON                        1
+#define SYNCINFO_TLS_CRITICAL  2
+        int                                    si_tls;
+               struct berval           si_updatedn;    
+        int                                    si_bindmethod;
+        char                           *si_binddn;
+        char                           *si_passwd;
+        char                           *si_saslmech;
+        char                           *si_secprops;
+        char                           *si_realm;
+        char                           *si_authcId;
+        char                           *si_authzId;
+               int                                     si_schemachecking;
+        Filter                         *si_filter;
+        struct berval          si_filterstr;
+        struct berval          si_base;
+        int                                    si_scope;
+        int                                    si_attrsonly;
+        char                           **si_attrs;
+        int                                    si_type;
+        time_t                         si_interval;
+//             struct sync_cookie      *si_syncCookie;
+               struct sync_cookie      si_syncCookie;
+        int                                    si_manageDSAit;
+        int                                    si_slimit;
+               int                                     si_tlimit;
+//        struct berval                *si_syncUUID;
+//             struct berval           *si_syncUUID_ndn;
+               struct berval           si_syncUUID_ndn;
+        Avlnode                                *si_presentlist;
+               int                                     si_sync_mode;
+               LDAP                            *si_ld;
+               LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist;
 } syncinfo_t;
 
 struct slap_backend_db {
@@ -1812,6 +1824,21 @@ struct psid_entry {
        LDAP_LIST_ENTRY(psid_entry) ps_link;
 };
 
+struct slog_entry {
+       struct berval sl_uuid;
+       struct berval sl_name;
+       struct berval sl_csn;
+       LDAP_STAILQ_ENTRY(slog_entry) sl_link;
+};
+
+/* session lists */
+struct slap_session_entry {
+       int se_id;
+       int se_size;
+       struct berval se_spec;
+       LDAP_LIST_ENTRY( slap_session_entry ) se_link;
+};
+
 struct slap_csn_entry {
        struct berval *csn;
        unsigned long opid;
@@ -1966,13 +1993,20 @@ typedef struct slap_op {
 
        char o_sync;
        char o_sync_mode;
-#define SLAP_SYNC_NONE                         (0x0)
-#define SLAP_SYNC_REFRESH                      (0x1)
-#define SLAP_SYNC_PERSIST                      (0x2)
-#define SLAP_SYNC_REFRESH_AND_PERSIST          (0x3)
-       struct berval o_sync_state;
+#define SLAP_SYNC_NONE                                 (0x0)
+#define SLAP_SYNC_REFRESH                              (0x1)
+#define SLAP_SYNC_PERSIST                              (0x2)
+#define SLAP_SYNC_REFRESH_AND_PERSIST  (0x3)
+       struct sync_cookie      o_sync_state;
+       struct berval           o_sync_cid;
+       int                                     o_sync_slog_size;
+       struct berval           o_sync_csn;
+       struct berval           o_sync_slog_omitcsn;
+       int                                     o_sync_slog_len;
+       LDAP_STAILQ_HEAD(sl, slog_entry) o_sync_slog_list;
 
        int o_ps_entries;
+       int     o_no_psearch;
        LDAP_LIST_ENTRY(slap_op) o_ps_link;
        LDAP_LIST_HEAD(pe, psid_entry) o_pm_list;
 
index b17754d420638a7169c11f2698b820c3edc1c35f..b4acf565ce55494525938bf7a95e6eff061a6b85 100644 (file)
@@ -125,8 +125,8 @@ init_syncrepl(syncinfo_t *si)
 static int
 ldap_sync_search(
        syncinfo_t *si,
-       void *ctx,
-       struct berval *syncCookie )
+       void *ctx
+)
 {
        BerElementBuffer berbuf;
        BerElement *ber = (BerElement *)&berbuf;
@@ -139,8 +139,10 @@ ldap_sync_search(
        ber_init2( ber, NULL, LBER_USE_DER );
        ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx );
 
-       if ( syncCookie ) {
-               ber_printf( ber, "{eO}", abs(si->si_type), syncCookie );
+       if ( si->si_syncCookie.octet_str &&
+                si->si_syncCookie.octet_str[0].bv_val ) {
+               ber_printf( ber, "{eO}", abs(si->si_type),
+                                       &si->si_syncCookie.octet_str[0] );
        } else {
                ber_printf( ber, "{e}", abs(si->si_type) );
        }
@@ -187,7 +189,7 @@ do_syncrep1(
 
        char syncrepl_cbuf[sizeof(CN_STR SYNCREPL_STR)];
        struct berval syncrepl_cn_bv;
-       BerVarray syncCookie;
+       struct sync_cookie      syncCookie = { NULL, -1, NULL };
 
        si->si_sync_mode = LDAP_SYNC_STATE_MODE;
 
@@ -197,11 +199,11 @@ do_syncrep1(
        if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR,
-                       "do_syncrepl: ldap_initialize failed (%s)\n",
+                       "do_syncrep1: ldap_initialize failed (%s)\n",
                        si->si_provideruri, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "do_syncrepl: ldap_initialize failed (%s)\n",
+                       "do_syncrep1: ldap_initialize failed (%s)\n",
                        si->si_provideruri, 0, 0 );
 #endif
                return rc;
@@ -216,7 +218,7 @@ do_syncrep1(
                rc = ldap_start_tls_s( si->si_ld, NULL, NULL );
                if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, ERR, "do_syncrepl: "
+                       LDAP_LOG ( OPERATION, ERR, "do_syncrep1: "
                                "%s: ldap_start_tls failed (%d)\n",
                                si->si_tls == SYNCINFO_TLS_CRITICAL ? "Error" : "Warning",
                                rc, 0 );
@@ -272,11 +274,11 @@ do_syncrep1(
                 */
                if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, ERR, "do_syncrepl: "
+                       LDAP_LOG ( OPERATION, ERR, "do_syncrep1: "
                                "ldap_sasl_interactive_bind_s failed (%d)\n",
                                rc, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY, "do_syncrepl: "
+                       Debug( LDAP_DEBUG_ANY, "do_syncrep1: "
                                "ldap_sasl_interactive_bind_s failed (%d)\n",
                                rc, 0, 0 );
 #endif
@@ -292,10 +294,10 @@ do_syncrep1(
                rc = ldap_bind_s( si->si_ld, si->si_binddn, si->si_passwd, si->si_bindmethod );
                if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, ERR, "do_syncrepl: "
+                       LDAP_LOG ( OPERATION, ERR, "do_syncrep1: "
                                "ldap_bind_s failed (%d)\n", rc, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY, "do_syncrepl: "
+                       Debug( LDAP_DEBUG_ANY, "do_syncrep1: "
                                "ldap_bind_s failed (%d)\n", rc, 0, 0 );
 #endif
                        goto done;
@@ -312,24 +314,43 @@ do_syncrep1(
                op->o_tmpmemctx );
        op->o_req_dn = op->o_req_ndn;
 
-       syncCookie = NULL;
-       backend_attribute( op, NULL, &op->o_req_ndn,
-               slap_schema.si_ad_syncreplCookie, &syncCookie );
+       if ( slap_sync_cookie != NULL ) {
+               slap_sync_cookie_free( &si->si_syncCookie, 0 );
+               slap_parse_sync_cookie( slap_sync_cookie );
+               if ( slap_sync_cookie->ctxcsn == NULL ||
+                        slap_sync_cookie->ctxcsn->bv_val == NULL ) {
+                       slap_init_sync_cookie_ctxcsn( slap_sync_cookie );
+               }
+               slap_dup_sync_cookie( &si->si_syncCookie, slap_sync_cookie );
+               slap_sync_cookie_free( slap_sync_cookie, 1 );
+               slap_sync_cookie = NULL;
+       }
+
+       /* use in-memory version if it exists */
+       if ( si->si_syncCookie.octet_str == NULL ) {
+               BerVarray cookie = NULL;
+               struct berval cookie_bv;
+               backend_attribute( op, NULL, &op->o_req_ndn,
+                       slap_schema.si_ad_syncreplCookie, &cookie );
+               if ( cookie ) {
+                       ber_dupbv( &cookie_bv, &cookie[0] );
+                       ber_bvarray_add( &si->si_syncCookie.octet_str, &cookie_bv );
+                       slap_parse_sync_cookie( &si->si_syncCookie );
+                       ber_bvarray_free_x( cookie, op->o_tmpmemctx );
+               }
+       }
+
+       rc = ldap_sync_search( si, op->o_tmpmemctx );
 
-       rc = ldap_sync_search( si, op->o_tmpmemctx, syncCookie );
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, ERR, "do_syncrepl: "
+               LDAP_LOG ( OPERATION, ERR, "do_syncrep1: "
                        "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 );
 #else
-               Debug( LDAP_DEBUG_ANY, "do_syncrepl: "
+               Debug( LDAP_DEBUG_ANY, "do_syncrep1: "
                        "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 );
 #endif
        }
-       if ( syncCookie ) {
-               ber_dupbv( &si->si_syncCookie, syncCookie );
-               ber_bvarray_free_x( syncCookie, op->o_tmpmemctx );
-       }
 
 done:
        if ( rc ) {
@@ -364,8 +385,9 @@ do_syncrep2(
 
        int             syncstate;
        struct berval   syncUUID = { 0, NULL };
-       struct berval   syncCookie = { 0, NULL };
-       struct berval   syncCookie_req;
+       struct sync_cookie      syncCookie = { NULL, -1, NULL };
+       struct sync_cookie      syncCookie_req = { NULL, -1, NULL };
+       struct berval           cookie = { 0, NULL };
 
        int     rc;
        int     err;
@@ -400,7 +422,7 @@ do_syncrep2(
 
        psub = &si->si_be->be_nsuffix[0];
 
-       syncCookie_req = si->si_syncCookie;
+       slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie );
 
        if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ){
                tout_p = &tout;
@@ -419,7 +441,6 @@ do_syncrep2(
                  msg != NULL;
                  msg = ldap_next_message( si->si_ld, msg ) )
                {
-                       syncCookie.bv_len = 0; syncCookie.bv_val = NULL;
                        switch( ldap_msgtype( msg ) ) {
                        case LDAP_RES_SEARCH_ENTRY:
                                ldap_get_entry_controls( si->si_ld, msg, &rctrls );
@@ -432,13 +453,21 @@ do_syncrep2(
                                ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER );
                                ber_scanf( ber, "{em", &syncstate, &syncUUID );
                                if ( ber_peek_tag( ber, &len ) == LDAP_SYNC_TAG_COOKIE ) {
-                                       ber_scanf( ber, "m}", &syncCookie );
+                                       ber_scanf( ber, "m}", &cookie );
+                                       if ( cookie.bv_val ) {
+                                               struct berval tmp_bv;
+                                               ber_dupbv( &tmp_bv, &cookie );
+                                               ber_bvarray_add( &syncCookie.octet_str, &tmp_bv );
+                                       }
+                                       if ( syncCookie.octet_str &&
+                                                       syncCookie.octet_str[0].bv_val )
+                                               slap_parse_sync_cookie( &syncCookie );
                                }
                                entry = syncrepl_message_to_entry( si, op, msg,
                                        &modlist, syncstate );
-                               rc_efree = syncrepl_entry( si, op, entry, modlist,
-                                               syncstate, &syncUUID, !syncinfo_arrived );
-                               if ( syncCookie.bv_len ) {
+                               rc_efree = syncrepl_entry( si, op, entry, modlist, syncstate,
+                                                       &syncUUID, &syncCookie_req, !syncinfo_arrived );
+                               if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) {
                                        syncrepl_updateCookie( si, op, psub, &syncCookie );
                                }
                                ldap_controls_free( rctrls );
@@ -453,10 +482,10 @@ do_syncrep2(
                        case LDAP_RES_SEARCH_REFERENCE:
 #ifdef NEW_LOGGING
                                LDAP_LOG( OPERATION, ERR,
-                                       "do_syncrepl : reference received\n", 0, 0, 0 );
+                                       "do_syncrep2 : reference received\n", 0, 0, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
-                                       "do_syncrepl : reference received\n", 0, 0, 0 );
+                                       "do_syncrep2 : reference received\n", 0, 0, 0 );
 #endif
                                break;
 
@@ -470,16 +499,30 @@ do_syncrep2(
                                        ber_scanf( ber, "{" /*"}"*/);
                                        if ( ber_peek_tag( ber, &len ) == LDAP_SYNC_TAG_COOKIE )
                                        {
-                                               ber_scanf( ber, "m", &syncCookie );
+                                               ber_scanf( ber, "m", &cookie );
+                                               if ( cookie.bv_val ) {
+                                                       struct berval tmp_bv;
+                                                       ber_dupbv( &tmp_bv, &cookie );
+                                                       ber_bvarray_add( &syncCookie.octet_str, &tmp_bv);
+                                               }
+                                               if ( syncCookie.octet_str &&
+                                                                syncCookie.octet_str[0].bv_val )
+                                                       slap_parse_sync_cookie( &syncCookie );
                                        }
                                }
-                               value_match( &match, slap_schema.si_ad_entryCSN,
-                                       slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
-                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                       &syncCookie_req, &syncCookie, &text );
-                               if ( syncCookie.bv_len && match < 0) {
-                                       syncrepl_updateCookie( si, op,
-                                               psub, &syncCookie );
+                               if ( syncCookie_req.ctxcsn == NULL ) {
+                                       match = -1;
+                               } else if ( syncCookie.ctxcsn == NULL ) {
+                                       match = 1;
+                               } else {
+                                       value_match( &match, slap_schema.si_ad_entryCSN,
+                                               slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
+                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                               &syncCookie_req.ctxcsn[0], &syncCookie.ctxcsn[0], &text );
+                               }
+                               if ( syncCookie.octet_str && syncCookie.octet_str->bv_val
+                                        && match < 0 ) {
+                                       syncrepl_updateCookie( si, op, psub, &syncCookie );
                                }
                                if ( rctrls ) {
                                        ldap_controls_free( rctrls );
@@ -509,25 +552,31 @@ do_syncrep2(
 
                                        if ( ber_peek_tag( ber, &len )
                                                                == LDAP_SYNC_TAG_COOKIE ) {
-                                               ber_scanf( ber, /*"{"*/ "m}", &syncCookie );
-                                       } else {
-                                               if ( syncstate == LDAP_SYNC_NEW_COOKIE ) {
-#ifdef NEW_LOGGING
-                                                       LDAP_LOG( OPERATION, ERR,
-                                                               "do_syncrepl : cookie required\n", 0, 0, 0 );
-#else
-                                                       Debug( LDAP_DEBUG_ANY,
-                                                               "do_syncrepl : cookie required\n", 0, 0, 0 );
-#endif
+                                               ber_scanf( ber, /*"{"*/ "m}", &cookie );
+                                               if ( cookie.bv_val ) {
+                                                       struct berval tmp_bv;
+                                                       ber_dupbv( &tmp_bv, &cookie );
+                                                       ber_bvarray_add( &syncCookie.octet_str, &tmp_bv);
                                                }
+                                               if ( syncCookie.octet_str &&
+                                                                syncCookie.octet_str[0].bv_val )
+                                                       slap_parse_sync_cookie( &syncCookie );
                                        }
 
-                                       value_match( &match, slap_schema.si_ad_entryCSN,
-                                               slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
-                                               SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
-                                               &syncCookie_req, &syncCookie, &text );
+                                       if ( syncCookie_req.ctxcsn == NULL ) {
+                                               match = -1;
+                                       } else if ( syncCookie.ctxcsn == NULL ) {
+                                               match = 1;
+                                       } else {
+                                               value_match( &match, slap_schema.si_ad_entryCSN,
+                                                       slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
+                                                       SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+                                                       &syncCookie_req.ctxcsn[0],
+                                                       &syncCookie.ctxcsn[0], &text );
+                                       }
 
-                                       if ( syncCookie.bv_len && match < 0 ) {
+                                       if ( syncCookie.ctxcsn && syncCookie.ctxcsn[0].bv_val
+                                                && match < 0 ) {
                                                syncrepl_updateCookie( si, op, psub, &syncCookie);
                                        }
 
@@ -545,10 +594,10 @@ do_syncrep2(
                                        {
 #ifdef NEW_LOGGING
                                                LDAP_LOG( OPERATION, ERR,
-                                                       "do_syncrepl : unknown sync info\n", 0, 0, 0 );
+                                                       "do_syncrep2 : unknown sync info\n", 0, 0, 0 );
 #else
                                                Debug( LDAP_DEBUG_ANY,
-                                                       "do_syncrepl : unknown sync info\n", 0, 0, 0 );
+                                                       "do_syncrep2 : unknown sync info\n", 0, 0, 0 );
 #endif
                                        }
 
@@ -557,11 +606,11 @@ do_syncrep2(
                                        break;
                                } else {
 #ifdef NEW_LOGGING
-                                       LDAP_LOG( OPERATION, ERR,"do_syncrepl :"
+                                       LDAP_LOG( OPERATION, ERR,"do_syncrep2 :"
                                                " unknown intermediate "
                                                "response\n", 0, 0, 0 );
 #else
-                                       Debug( LDAP_DEBUG_ANY, "do_syncrepl : "
+                                       Debug( LDAP_DEBUG_ANY, "do_syncrep2 : "
                                                "unknown intermediate response (%d)\n",
                                                rc, 0, 0 );
 #endif
@@ -572,15 +621,20 @@ do_syncrep2(
                                break;
                        default:
 #ifdef NEW_LOGGING
-                               LDAP_LOG( OPERATION, ERR, "do_syncrepl : "
+                               LDAP_LOG( OPERATION, ERR, "do_syncrep2 : "
                                        "unknown message\n", 0, 0, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY, "do_syncrepl : "
+                               Debug( LDAP_DEBUG_ANY, "do_syncrep2 : "
                                        "unknown message\n", 0, 0, 0 );
 #endif
                                break;
 
                        }
+                       if ( syncCookie.octet_str ) {
+                               slap_sync_cookie_free( &syncCookie_req, 0 );
+                               slap_dup_sync_cookie( &syncCookie_req, &syncCookie );
+                               slap_sync_cookie_free( &syncCookie, 0 );
+                       }
                }
                ldap_msgfree( res );
                res = NULL;
@@ -594,14 +648,17 @@ do_syncrep2(
                
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR,
-                       "do_syncrepl : %s\n", errstr, 0, 0 );
+                       "do_syncrep2 : %s\n", errstr, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "do_syncrepl : %s\n", errstr, 0, 0 );
+                       "do_syncrep2 : %s\n", errstr, 0, 0 );
 #endif
        }
 
 done:
+       slap_sync_cookie_free( &syncCookie, 0 );
+       slap_sync_cookie_free( &syncCookie_req, 0 );
+
        if ( res ) ldap_msgfree( res );
 
        if ( rc && si->si_ld ) {
@@ -672,6 +729,13 @@ do_syncrepl(
        op.o_conn = &conn;
        op.o_connid = op.o_conn->c_connid;
 
+       op.o_sync_state.ctxcsn = NULL;
+       op.o_sync_state.sid = -1;
+       op.o_sync_state.octet_str = NULL;
+       op.o_sync_slog_size = -1;
+       LDAP_STAILQ_FIRST( &op.o_sync_slog_list ) = NULL;
+       op.o_sync_slog_list.stqh_last = &LDAP_STAILQ_FIRST(&op.o_sync_slog_list);
+
        /* Establish session, do search */
        if ( !si->si_ld ) {
                first = 1;
@@ -699,10 +763,6 @@ do_syncrepl(
                                dostop = 1;
                        }
                } else {
-                       ch_free( si->si_syncCookie.bv_val );
-                       si->si_syncCookie.bv_val = NULL;
-                       si->si_syncCookie.bv_len = 0;
-                       /* Session closed due to receipt of search result */
                        if ( rc == -2 ) rc = 0;
                }
        }
@@ -884,6 +944,7 @@ syncrepl_entry(
        Modifications* modlist,
        int syncstate,
        struct berval* syncUUID,
+       struct sync_cookie* syncCookie_req,
        int refresh
 )
 {
@@ -898,7 +959,7 @@ syncrepl_entry(
        int ret = LDAP_SUCCESS;
        const char *text;
 
-       if ( refresh &&
+       if ( refresh && si->si_sync_mode == LDAP_SYNC_STATE_MODE &&
                ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD ))
        {
                syncuuid_bv = ber_dupbv( NULL, syncUUID );
@@ -951,13 +1012,24 @@ syncrepl_entry(
        cb.sc_response = null_callback;
        cb.sc_private = si;
 
-       if ( rc == LDAP_SUCCESS && si->si_syncUUID_ndn.bv_val &&
-               si->si_sync_mode != LDAP_SYNC_LOG_MODE )
+       if ( rc == LDAP_SUCCESS && si->si_syncUUID_ndn.bv_val )
        {
+               char *subseq_ptr;
+
+               if ( syncstate != LDAP_SYNC_DELETE ) {
+                       op->o_no_psearch = 1;
+               }
+
+               ber_dupbv( &op->o_sync_csn, syncCookie_req->ctxcsn );
+               subseq_ptr = strstr( op->o_sync_csn.bv_val, "#0000" );
+               subseq_ptr += 4;
+               *subseq_ptr = '1';
+               
                op->o_req_dn = si->si_syncUUID_ndn;
                op->o_req_ndn = si->si_syncUUID_ndn;
                op->o_tag = LDAP_REQ_DELETE;
                rc = be->be_delete( op, &rs );
+               op->o_no_psearch = 0;
        }
 
        switch ( syncstate ) {
@@ -1032,15 +1104,7 @@ syncrepl_entry(
                }
 
        case LDAP_SYNC_DELETE :
-               if ( si->si_sync_mode == LDAP_SYNC_LOG_MODE ) {
-                       if ( si->si_syncUUID_ndn.bv_val ) {
-                               op->o_req_dn = si->si_syncUUID_ndn;
-                               op->o_req_ndn = si->si_syncUUID_ndn;
-                               op->o_tag = LDAP_REQ_DELETE;
-                               rc = be->be_delete( op, &rs );
-                       }
-               }
-               /* Already deleted otherwise */
+               /* Already deleted */
                ret = 1;
                goto done;
 
@@ -1289,7 +1353,7 @@ syncrepl_updateCookie(
        syncinfo_t *si,
        Operation *op,
        struct berval *pdn,
-       struct berval *syncCookie
+       struct sync_cookie *syncCookie
 )
 {
        Backend *be = op->o_bd;
@@ -1313,6 +1377,9 @@ syncrepl_updateCookie(
        slap_callback cb;
        SlapReply       rs = {REP_RESULT};
 
+       slap_sync_cookie_free( &si->si_syncCookie, 0 );
+       slap_dup_sync_cookie( &si->si_syncCookie, syncCookie );
+
        mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
        mod->sml_op = LDAP_MOD_REPLACE;
        mod->sml_desc = slap_schema.si_ad_objectClass;
@@ -1335,7 +1402,7 @@ syncrepl_updateCookie(
        modtail = &mod->sml_next;
 
        if ( scbva[0].bv_val ) ch_free( scbva[0].bv_val );
-       ber_dupbv( &scbva[0], syncCookie );
+       ber_dupbv( &scbva[0], &si->si_syncCookie.octet_str[0] );
        mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
        mod->sml_op = LDAP_MOD_REPLACE;
        mod->sml_desc = slap_schema.si_ad_syncreplCookie;
index 8934eac54cbfa05fd8e738e1fd8079e47f4a74f4..8f71829cff5b86c25beb914973a33cea305ec29c 100644 (file)
@@ -46,7 +46,8 @@ SLAPD_OBJS = ../globals.o ../config.o ../ch_malloc.o ../cr.o ../backend.o \
                ../init.o ../controls.o ../kerberos.o ../passwd.o \
                ../index.o ../extended.o ../starttls.o ../sets.o ../mra.o \
                ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o \
-               ../cancel.o ../sl_malloc.o ../backover.o ../ctxcsn.o ../syncrepl.o
+               ../cancel.o ../sl_malloc.o ../backover.o ../ctxcsn.o ../syncrepl.o \
+               ../ldapsync.o ../sessionlog.o
 
 SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
 
index bb51cdd1dd1181edf1853184b0086d829145239c..7e2fa3406e5e9d81514ab02d7e42ead8da9968c3 100644 (file)
@@ -28,3 +28,5 @@ rootpw                secret
 #ldbm#index            cn,sn,uid       pres,eq,sub
 #bdb#index             objectClass     eq
 #bdb#index             cn,sn,uid       pres,eq,sub
+
+sessionlog 1 100
index d1aa086f600f28ac0b80edde2f69106b0562c4bd..15543497ab9fa91c01e3ee4c2f245f909b7ffb09 100644 (file)
@@ -29,6 +29,8 @@ rootpw                secret
 #bdb#index             objectClass     eq
 #bdb#index             cn,sn,uid       pres,eq,sub
 
+sessionlog 1 100
+
 # Don't change syncrepl spec yet
 syncrepl id=1
                 provider=ldap://localhost:9011