Diff for /servers/slapd/overlays/syncprov.c between versions 1.56.2.6 and 1.65

version 1.56.2.6, 2005/04/29 21:29:10 version 1.65, 2005/01/13 20:14:52
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.56.2.5 2005/03/14 22:25:02 kurt Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.64 2005/01/13 18:51:01 hyc Exp $ */
 /* syncprov.c - syncrepl provider */  /* syncprov.c - syncrepl provider */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
Line 250  syncprov_done_ctrl( Line 250  syncprov_done_ctrl(
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
 }  }
   
   #if 0
   /* Generate state based on session log - not implemented yet */
   static int
   syncprov_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   *cookie)
   {
           Attribute* a;
           int ret;
           int res;
           const char *text = NULL;
   
           BerElementBuffer berbuf;
           BerElement *ber = (BerElement *)&berbuf;
   
           struct berval entryuuid_bv      = BER_BVNULL;
   
           ber_init2( ber, NULL, LBER_USE_DER );
           ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
   
           ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
   
           entryuuid_bv = slog_e->sl_uuid;
   
           if ( send_cookie && cookie ) {
                   ber_printf( ber, "{eOON}",
                           entry_sync_state, &entryuuid_bv, cookie );
           } else {
                   ber_printf( ber, "{eON}",
                           entry_sync_state, &entryuuid_bv );
           }
   
           ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
           ctrls[num_ctrls]->ldctl_iscritical = (op->o_sync == SLAP_CONTROL_CRITICAL);
           ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
   
           ber_free_buf( ber );
   
           if ( ret < 0 ) {
                   Debug( LDAP_DEBUG_TRACE,
                           "slap_build_sync_ctrl: ber_flatten2 failed\n",
                           0, 0, 0 );
                   send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
                   return ret;
           }
   
           return LDAP_SUCCESS;
   }
   #endif
   
 static int  static int
 syncprov_sendinfo(  syncprov_sendinfo(
         Operation       *op,          Operation       *op,
Line 414  syncprov_findbase( Operation *op, fbase_ Line 470  syncprov_findbase( Operation *op, fbase_
         cb.sc_private = fc;          cb.sc_private = fc;
   
         fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync mode */          fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync mode */
         fop.o_managedsait = SLAP_CONTROL_CRITICAL;  
         fop.o_callback = &cb;          fop.o_callback = &cb;
         fop.o_tag = LDAP_REQ_SEARCH;          fop.o_tag = LDAP_REQ_SEARCH;
         fop.ors_scope = LDAP_SCOPE_BASE;          fop.ors_scope = LDAP_SCOPE_BASE;
Line 549  syncprov_findcsn( Operation *op, int mod Line 604  syncprov_findcsn( Operation *op, int mod
         char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];          char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
         struct berval fbuf, maxcsn;          struct berval fbuf, maxcsn;
         Filter cf, af;          Filter cf, af;
 #ifdef LDAP_COMP_MATCH          AttributeAssertion eq;
         AttributeAssertion eq = { NULL, BER_BVNULL, NULL };  
 #else  
         AttributeAssertion eq = { NULL, BER_BVNULL };  
 #endif  
         int i, rc = LDAP_SUCCESS;          int i, rc = LDAP_SUCCESS;
         fpres_cookie pcookie;          fpres_cookie pcookie;
         sync_control *srs = NULL;          sync_control *srs;
   
         if ( mode != FIND_MAXCSN ) {          if ( mode != FIND_MAXCSN ) {
                 srs = op->o_controls[slap_cids.sc_LDAPsync];                  srs = op->o_controls[slap_cids.sc_LDAPsync];
   
                 if ( srs->sr_state.ctxcsn.bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {                  if ( srs->sr_state.ctxcsn->bv_len >= LDAP_LUTIL_CSNSTR_BUFSIZE ) {
                         return LDAP_OTHER;                          return LDAP_OTHER;
                 }                  }
         }          }
   
         fop = *op;          fop = *op;
         fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync_mode */          fop.o_sync_mode &= SLAP_CONTROL_MASK;   /* turn off sync_mode */
         /* We want pure entries, not referrals */  
         fop.o_managedsait = SLAP_CONTROL_CRITICAL;  
   
         fbuf.bv_val = buf;          fbuf.bv_val = buf;
         cf.f_ava = &eq;          cf.f_ava = &eq;
Line 599  syncprov_findcsn( Operation *op, int mod Line 648  syncprov_findcsn( Operation *op, int mod
                 break;                  break;
         case FIND_CSN:          case FIND_CSN:
                 cf.f_choice = LDAP_FILTER_LE;                  cf.f_choice = LDAP_FILTER_LE;
                 cf.f_av_value = srs->sr_state.ctxcsn;                  cf.f_av_value = *srs->sr_state.ctxcsn;
                 fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",                  fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
                         cf.f_av_value.bv_val );                          cf.f_av_value.bv_val );
                 fop.ors_attrsonly = 1;                  fop.ors_attrsonly = 1;
Line 613  syncprov_findcsn( Operation *op, int mod Line 662  syncprov_findcsn( Operation *op, int mod
                 af.f_next = NULL;                  af.f_next = NULL;
                 af.f_and = &cf;                  af.f_and = &cf;
                 cf.f_choice = LDAP_FILTER_LE;                  cf.f_choice = LDAP_FILTER_LE;
                 cf.f_av_value = srs->sr_state.ctxcsn;                  cf.f_av_value = *srs->sr_state.ctxcsn;
                 cf.f_next = op->ors_filter;                  cf.f_next = op->ors_filter;
                 fop.ors_filter = &af;                  fop.ors_filter = &af;
                 filter2bv_x( &fop, fop.ors_filter, &fop.ors_filterstr );                  filter2bv_x( &fop, fop.ors_filter, &fop.ors_filterstr );
                 fop.ors_attrsonly = 0;                  fop.ors_attrsonly = 0;
                 fop.ors_attrs = uuid_anlist;                  fop.ors_attrs = uuid_anlist;
                 fop.ors_slimit = SLAP_NO_LIMIT;                  fop.ors_slimit = SLAP_NO_LIMIT;
                   /* We want pure entries, not referrals */
                   fop.o_managedsait = SLAP_CONTROL_CRITICAL;
                 cb.sc_private = &pcookie;                  cb.sc_private = &pcookie;
                 cb.sc_response = findpres_cb;                  cb.sc_response = findpres_cb;
                 pcookie.num = 0;                  pcookie.num = 0;
Line 660  syncprov_findcsn( Operation *op, int mod Line 711  syncprov_findcsn( Operation *op, int mod
         return rc;          return rc;
 }  }
   
 /* Queue a persistent search response */  /* Queue a persistent search response if still in Refresh stage */
 static int  static int
 syncprov_qresp( opcookie *opc, syncops *so, int mode )  syncprov_qresp( opcookie *opc, syncops *so, int mode )
 {  {
Line 670  syncprov_qresp( opcookie *opc, syncops * Line 721  syncprov_qresp( opcookie *opc, syncops *
                 opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1 + opc->sctxcsn.bv_len + 1 );                  opc->sdn.bv_len + 1 + opc->sndn.bv_len + 1 + opc->sctxcsn.bv_len + 1 );
         sr->s_next = NULL;          sr->s_next = NULL;
         sr->s_dn.bv_val = (char *)(sr + 1);          sr->s_dn.bv_val = (char *)(sr + 1);
         sr->s_dn.bv_len = opc->sdn.bv_len;  
         sr->s_mode = mode;          sr->s_mode = mode;
         sr->s_isreference = opc->sreference;          sr->s_isreference = opc->sreference;
         sr->s_ndn.bv_val = lutil_strcopy( sr->s_dn.bv_val, opc->sdn.bv_val );          sr->s_ndn.bv_val = lutil_strcopy( sr->s_dn.bv_val, opc->sdn.bv_val );
         sr->s_ndn.bv_len = opc->sndn.bv_len;  
         *(sr->s_ndn.bv_val++) = '\0';          *(sr->s_ndn.bv_val++) = '\0';
         sr->s_uuid.bv_val = lutil_strcopy( sr->s_ndn.bv_val, opc->sndn.bv_val );          sr->s_uuid.bv_val = lutil_strcopy( sr->s_ndn.bv_val, opc->sndn.bv_val );
         sr->s_uuid.bv_len = opc->suuid.bv_len;  
         *(sr->s_uuid.bv_val++) = '\0';          *(sr->s_uuid.bv_val++) = '\0';
         sr->s_csn.bv_val = lutil_strcopy( sr->s_uuid.bv_val, opc->suuid.bv_val );          sr->s_csn.bv_val = lutil_strcopy( sr->s_uuid.bv_val, opc->suuid.bv_val );
         sr->s_csn.bv_len = opc->sctxcsn.bv_len;  
         strcpy( sr->s_csn.bv_val, opc->sctxcsn.bv_val );  
   
         if ( !so->s_res ) {          if ( !so->s_res ) {
                 so->s_res = sr;                  so->s_res = sr;
Line 693  syncprov_qresp( opcookie *opc, syncops * Line 739  syncprov_qresp( opcookie *opc, syncops *
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
 }  }
   
 /* Play back queued responses */  
 static int  
 syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mode, int queue );  
   
 static int  
 syncprov_qplay( Operation *op, slap_overinst *on, syncops *so )  
 {  
         syncres *sr, *srnext;  
         Entry *e;  
         opcookie opc;  
         int rc;  
   
         opc.son = on;  
         op->o_bd->bd_info = (BackendInfo *)on->on_info;  
         for (sr = so->s_res; sr; sr=srnext) {  
                 srnext = sr->s_next;  
                 opc.sdn = sr->s_dn;  
                 opc.sndn = sr->s_ndn;  
                 opc.suuid = sr->s_uuid;  
                 opc.sctxcsn = sr->s_csn;  
                 opc.sreference = sr->s_isreference;  
                 e = NULL;  
   
                 if ( sr->s_mode != LDAP_SYNC_DELETE ) {  
                         rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e );  
                         if ( rc ) {  
                                 ch_free( sr );  
                                 so->s_res = srnext;  
                                 continue;  
                         }  
                 }  
                 rc = syncprov_sendresp( op, &opc, so, &e, sr->s_mode, 0 );  
   
                 if ( e ) {  
                         be_entry_release_rw( op, e, 0 );  
                 }  
                 if ( rc )  
                         break;  
   
                 ch_free( sr );  
                 so->s_res = srnext;  
         }  
         op->o_bd->bd_info = (BackendInfo *)on;  
         if ( !so->s_res )  
                 so->s_restail = NULL;  
         return rc;  
 }  
   
 /* Send a persistent search response */  /* Send a persistent search response */
 static int  static int
 syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry **e, int mode, int queue )  syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, Entry *e, int mode, int queue )
 {  {
         slap_overinst *on = opc->son;          slap_overinst *on = opc->son;
         syncprov_info_t *si = on->on_bi.bi_private;          syncprov_info_t *si = on->on_bi.bi_private;
Line 756  syncprov_sendresp( Operation *op, opcook Line 754  syncprov_sendresp( Operation *op, opcook
         Operation sop = *so->s_op;          Operation sop = *so->s_op;
         Opheader ohdr;          Opheader ohdr;
   
         if ( so->s_op->o_abandon )  
                 return SLAPD_ABANDON;  
   
         ohdr = *sop.o_hdr;          ohdr = *sop.o_hdr;
         sop.o_hdr = &ohdr;          sop.o_hdr = &ohdr;
         sop.o_tmpmemctx = op->o_tmpmemctx;          sop.o_tmpmemctx = op->o_tmpmemctx;
         sop.o_bd = op->o_bd;          sop.o_bd = op->o_bd;
         sop.o_controls = op->o_controls;          sop.o_controls = op->o_controls;
         sop.o_private = op->o_private;  
   
         /* If queueing is allowed */          if ( queue && (so->s_flags & PS_IS_REFRESHING) ) {
         if ( queue ) {  
                 ldap_pvt_thread_mutex_lock( &so->s_mutex );                  ldap_pvt_thread_mutex_lock( &so->s_mutex );
                 /* If we're still in refresh mode, must queue */                  if ( so->s_flags & PS_IS_REFRESHING )
                 if (so->s_flags & PS_IS_REFRESHING) {  
                         return syncprov_qresp( opc, so, mode );  
                 }  
                 /* If connection is free but queue is non-empty,  
                  * try to flush the queue.  
                  */  
                 if ( so->s_res ) {  
                         rs.sr_err = syncprov_qplay( &sop, on, so );  
                 }  
                 /* If the connection is busy, must queue */  
                 if ( sop.o_conn->c_writewaiter || rs.sr_err == LDAP_BUSY ) {  
                         return syncprov_qresp( opc, so, mode );                          return syncprov_qresp( opc, so, mode );
                 }  
                 ldap_pvt_thread_mutex_unlock( &so->s_mutex );                  ldap_pvt_thread_mutex_unlock( &so->s_mutex );
   
                 /* If syncprov_qplay returned any other error, bail out. */  
                 if ( rs.sr_err ) {  
                         return rs.sr_err;  
                 }  
         } else {  
                 /* Queueing not allowed and conn is busy, give up */  
                 if ( sop.o_conn->c_writewaiter )  
                         return LDAP_BUSY;  
         }          }
   
         ctrls[1] = NULL;          ctrls[1] = NULL;
Line 804  syncprov_sendresp( Operation *op, opcook Line 776  syncprov_sendresp( Operation *op, opcook
         rs.sr_err = syncprov_state_ctrl( &sop, &rs, &e_uuid,          rs.sr_err = syncprov_state_ctrl( &sop, &rs, &e_uuid,
                 mode, ctrls, 0, 1, &cookie );                  mode, ctrls, 0, 1, &cookie );
   
           rs.sr_entry = e;
         rs.sr_ctrls = ctrls;          rs.sr_ctrls = ctrls;
         op->o_bd->bd_info = (BackendInfo *)on->on_info;  
         switch( mode ) {          switch( mode ) {
         case LDAP_SYNC_ADD:          case LDAP_SYNC_ADD:
                 rs.sr_entry = *e;  
                 if ( rs.sr_entry->e_private )  
                         rs.sr_flags = REP_ENTRY_MUSTRELEASE;  
                 if ( opc->sreference ) {                  if ( opc->sreference ) {
                         rs.sr_ref = get_entry_referrals( &sop, rs.sr_entry );                          rs.sr_ref = get_entry_referrals( &sop, e );
                         send_search_reference( &sop, &rs );                          send_search_reference( &sop, &rs );
                         ber_bvarray_free( rs.sr_ref );                          ber_bvarray_free( rs.sr_ref );
                         if ( !rs.sr_entry )  
                                 *e = NULL;  
                         break;                          break;
                 }                  }
                 /* fallthru */                  /* fallthru */
         case LDAP_SYNC_MODIFY:          case LDAP_SYNC_MODIFY:
                 rs.sr_entry = *e;  
                 if ( rs.sr_entry->e_private )  
                         rs.sr_flags = REP_ENTRY_MUSTRELEASE;  
                 rs.sr_attrs = sop.ors_attrs;                  rs.sr_attrs = sop.ors_attrs;
                 send_search_entry( &sop, &rs );                  send_search_entry( &sop, &rs );
                 if ( !rs.sr_entry )  
                         *e = NULL;  
                 break;                  break;
         case LDAP_SYNC_DELETE:          case LDAP_SYNC_DELETE:
                 e_uuid.e_attrs = NULL;                  e_uuid.e_attrs = NULL;
Line 846  syncprov_sendresp( Operation *op, opcook Line 808  syncprov_sendresp( Operation *op, opcook
                 assert(0);                  assert(0);
         }          }
         op->o_tmpfree( rs.sr_ctrls[0], op->o_tmpmemctx );          op->o_tmpfree( rs.sr_ctrls[0], op->o_tmpmemctx );
         op->o_private = sop.o_private;  
         rs.sr_ctrls = NULL;          rs.sr_ctrls = NULL;
         /* Check queue again here; if we were hanging in a send and eventually  
          * recovered, there may be more to send now. But don't check if the  
          * original psearch has been abandoned.  
          */  
         if ( so->s_op->o_abandon )  
                 return SLAPD_ABANDON;  
   
         if ( rs.sr_err == LDAP_SUCCESS && queue && so->s_res ) {  
                 ldap_pvt_thread_mutex_lock( &so->s_mutex );  
                 rs.sr_err = syncprov_qplay( &sop, on, so );  
                 ldap_pvt_thread_mutex_unlock( &so->s_mutex );  
         }  
         return rs.sr_err;          return rs.sr_err;
 }  }
   
Line 907  syncprov_drop_psearch( syncops *so, int Line 856  syncprov_drop_psearch( syncops *so, int
                         ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );                          ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
         }          }
         syncprov_free_syncop( so );          syncprov_free_syncop( so );
   
         return 0;  
 }  
   
 static int  
 syncprov_ab_cleanup( Operation *op, SlapReply *rs )  
 {  
         slap_callback *sc = op->o_callback;  
         op->o_callback = sc->sc_next;  
         syncprov_drop_psearch( op->o_callback->sc_private, 0 );  
         op->o_tmpfree( sc, op->o_tmpmemctx );  
         return 0;  
 }  }
   
 static int  static int
Line 942  syncprov_op_abandon( Operation *op, Slap Line 879  syncprov_op_abandon( Operation *op, Slap
         if ( so ) {          if ( so ) {
                 /* Is this really a Cancel exop? */                  /* Is this really a Cancel exop? */
                 if ( op->o_tag != LDAP_REQ_ABANDON ) {                  if ( op->o_tag != LDAP_REQ_ABANDON ) {
                         so->s_op->o_cancel = SLAP_CANCEL_ACK;  
                         rs->sr_err = LDAP_CANCELLED;                          rs->sr_err = LDAP_CANCELLED;
                         send_ldap_result( so->s_op, rs );                          send_ldap_result( so->s_op, rs );
                         if ( so->s_flags & PS_IS_DETACHED ) {  
                                 slap_callback *cb;  
                                 cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );  
                                 cb->sc_cleanup = syncprov_ab_cleanup;  
                                 cb->sc_next = op->o_callback;  
                                 cb->sc_private = so;  
                                 return SLAP_CB_CONTINUE;  
                         }  
                 }                  }
                 syncprov_drop_psearch( so, 0 );                  syncprov_drop_psearch( so, 0 );
         }          }
Line 987  syncprov_matchops( Operation *op, opcook Line 915  syncprov_matchops( Operation *op, opcook
         if ( op->o_tag != LDAP_REQ_ADD ) {          if ( op->o_tag != LDAP_REQ_ADD ) {
                 op->o_bd->bd_info = (BackendInfo *)on->on_info;                  op->o_bd->bd_info = (BackendInfo *)on->on_info;
                 rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );                  rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
                 /* If we're sending responses now, make a copy and unlock the DB */  
                 if ( e && !saveit ) {  
                         Entry *e2 = entry_dup( e );  
                         be_entry_release_rw( op, e, 0 );  
                         e = e2;  
                 }  
                 op->o_bd->bd_info = (BackendInfo *)on;                  op->o_bd->bd_info = (BackendInfo *)on;
                 if ( rc ) return;                  if ( rc ) return;
         } else {          } else {
                 e = op->ora_e;                  e = op->ora_e;
         }          }
   
           /* Never replicate these */
           if ( is_entry_syncConsumerSubentry( e )) {
                   goto done;
           }
         if ( saveit ) {          if ( saveit ) {
                 ber_dupbv_x( &opc->sdn, &e->e_name, op->o_tmpmemctx );                  ber_dupbv_x( &opc->sdn, &e->e_name, op->o_tmpmemctx );
                 ber_dupbv_x( &opc->sndn, &e->e_nname, op->o_tmpmemctx );                  ber_dupbv_x( &opc->sndn, &e->e_nname, op->o_tmpmemctx );
Line 1059  syncprov_matchops( Operation *op, opcook Line 985  syncprov_matchops( Operation *op, opcook
                                 opc->smatches = sm;                                  opc->smatches = sm;
                         } else {                          } else {
                                 /* if found send UPDATE else send ADD */                                  /* if found send UPDATE else send ADD */
                                 ss->s_inuse++;                                  syncprov_sendresp( op, opc, ss, e,
                                 ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );  
                                 syncprov_sendresp( op, opc, ss, &e,  
                                         found ? LDAP_SYNC_MODIFY : LDAP_SYNC_ADD, 1 );                                          found ? LDAP_SYNC_MODIFY : LDAP_SYNC_ADD, 1 );
                                 ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );  
                                 ss->s_inuse--;  
                         }                          }
                 } else if ( !saveit && found ) {                  } else if ( !saveit && found ) {
                         /* send DELETE */                          /* send DELETE */
                         ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );  
                         syncprov_sendresp( op, opc, ss, NULL, LDAP_SYNC_DELETE, 1 );                          syncprov_sendresp( op, opc, ss, NULL, LDAP_SYNC_DELETE, 1 );
                         ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );  
                 }                  }
         }          }
         ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );          ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
 done:  done:
         if ( op->o_tag != LDAP_REQ_ADD && e ) {          if ( op->o_tag != LDAP_REQ_ADD ) {
                 op->o_bd->bd_info = (BackendInfo *)on->on_info;                  op->o_bd->bd_info = (BackendInfo *)on->on_info;
                 be_entry_release_rw( op, e, 0 );                  be_entry_release_rw( op, e, 0 );
                 op->o_bd->bd_info = (BackendInfo *)on;                  op->o_bd->bd_info = (BackendInfo *)on;
Line 1105  syncprov_op_cleanup( Operation *op, Slap Line 1025  syncprov_op_cleanup( Operation *op, Slap
         mtdummy.mt_op = op;          mtdummy.mt_op = op;
         ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );          ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );
         mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );          mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );
           ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
         if ( mt ) {          if ( mt ) {
                 modinst *mi = mt->mt_mods;                  modinst *mi = mt->mt_mods;
   
Line 1115  syncprov_op_cleanup( Operation *op, Slap Line 1036  syncprov_op_cleanup( Operation *op, Slap
                         mt->mt_op = mt->mt_mods->mi_op;                          mt->mt_op = mt->mt_mods->mi_op;
                         ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );                          ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                 } else {                  } else {
                           ldap_pvt_thread_mutex_lock( &si->si_mods_mutex );
                         avl_delete( &si->si_mods, mt, sp_avl_cmp );                          avl_delete( &si->si_mods, mt, sp_avl_cmp );
                           ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
                         ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );                          ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                         ldap_pvt_thread_mutex_destroy( &mt->mt_mutex );                          ldap_pvt_thread_mutex_destroy( &mt->mt_mutex );
                         ch_free( mt );                          ch_free( mt );
                 }                  }
         }          }
         ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );  
         if ( !BER_BVISNULL( &opc->suuid ))          if ( !BER_BVISNULL( &opc->suuid ))
                 op->o_tmpfree( opc->suuid.bv_val, op->o_tmpmemctx );                  op->o_tmpfree( opc->suuid.bv_val, op->o_tmpmemctx );
         if ( !BER_BVISNULL( &opc->sndn ))          if ( !BER_BVISNULL( &opc->sndn ))
Line 1130  syncprov_op_cleanup( Operation *op, Slap Line 1052  syncprov_op_cleanup( Operation *op, Slap
                 op->o_tmpfree( opc->sdn.bv_val, op->o_tmpmemctx );                  op->o_tmpfree( opc->sdn.bv_val, op->o_tmpmemctx );
         op->o_callback = cb->sc_next;          op->o_callback = cb->sc_next;
         op->o_tmpfree(cb, op->o_tmpmemctx);          op->o_tmpfree(cb, op->o_tmpmemctx);
   
         return 0;  
 }  }
   
 static void  static void
Line 1141  syncprov_checkpoint( Operation *op, Slap Line 1061  syncprov_checkpoint( Operation *op, Slap
         Modifications mod;          Modifications mod;
         Operation opm;          Operation opm;
         struct berval bv[2];          struct berval bv[2];
           BackendInfo *orig;
         slap_callback cb = {0};          slap_callback cb = {0};
         int manage = get_manageDSAit(op);  
   
         mod.sml_values = bv;          mod.sml_values = bv;
         bv[1].bv_val = NULL;          bv[1].bv_val = NULL;
Line 1159  syncprov_checkpoint( Operation *op, Slap Line 1079  syncprov_checkpoint( Operation *op, Slap
         opm.orm_modlist = &mod;          opm.orm_modlist = &mod;
         opm.o_req_dn = op->o_bd->be_suffix[0];          opm.o_req_dn = op->o_bd->be_suffix[0];
         opm.o_req_ndn = op->o_bd->be_nsuffix[0];          opm.o_req_ndn = op->o_bd->be_nsuffix[0];
           orig = opm.o_bd->bd_info;
         opm.o_bd->bd_info = on->on_info->oi_orig;          opm.o_bd->bd_info = on->on_info->oi_orig;
         opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;  
         opm.o_bd->be_modify( &opm, rs );          opm.o_bd->be_modify( &opm, rs );
         opm.o_managedsait = manage;  
 }  }
   
 static void  static void
Line 1303  syncprov_playlog( Operation *op, SlapRep Line 1222  syncprov_playlog( Operation *op, SlapRep
                 SlapReply frs = { REP_RESULT };                  SlapReply frs = { REP_RESULT };
                 int rc;                  int rc;
                 Filter mf, af;                  Filter mf, af;
 #ifdef LDAP_COMP_MATCH  
                 AttributeAssertion eq = { NULL, BER_BVNULL, NULL };  
 #else  
                 AttributeAssertion eq;                  AttributeAssertion eq;
 #endif  
                 slap_callback cb = {0};                  slap_callback cb = {0};
   
                 fop = *op;                  fop = *op;
Line 1379  syncprov_op_response( Operation *op, Sla Line 1294  syncprov_op_response( Operation *op, Sla
                         }                          }
                 }                  }
   
                 /* Don't do any processing for consumer contextCSN updates */  
                 if ( SLAP_SYNC_SHADOW( op->o_bd ) &&   
                         op->o_msgid == SLAP_SYNC_UPDATE_MSGID ) {  
                         ldap_pvt_thread_mutex_unlock( &si->si_csn_mutex );  
                         return SLAP_CB_CONTINUE;  
                 }  
   
                 si->si_numops++;                  si->si_numops++;
                 if ( si->si_chkops || si->si_chktime ) {                  if ( si->si_chkops || si->si_chktime ) {
                         int do_check=0;                          int do_check=0;
Line 1420  syncprov_op_response( Operation *op, Sla Line 1328  syncprov_op_response( Operation *op, Sla
                                 /* for each match in opc->smatches:                                  /* for each match in opc->smatches:
                                  *   send DELETE msg                                   *   send DELETE msg
                                  */                                   */
                                   ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
                                 for ( sm = opc->smatches; sm; sm=sm->sm_next ) {                                  for ( sm = opc->smatches; sm; sm=sm->sm_next ) {
                                         if ( sm->sm_op->s_op->o_abandon )                                          if ( sm->sm_op->s_op->o_abandon )
                                                 continue;                                                  continue;
                                         syncprov_sendresp( op, opc, sm->sm_op, NULL,                                          syncprov_sendresp( op, opc, sm->sm_op, NULL,
                                                 LDAP_SYNC_DELETE, 1 );                                                  LDAP_SYNC_DELETE, 1 );
                                 }                                  }
                                   ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
                                 break;                                  break;
                         }                          }
                 }                  }
Line 1551  syncprov_op_mod( Operation *op, SlapRepl Line 1461  syncprov_op_mod( Operation *op, SlapRepl
                                 ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );                                  ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                                 ldap_pvt_thread_yield();                                  ldap_pvt_thread_yield();
                                 ldap_pvt_thread_mutex_lock( &mt->mt_mutex );                                  ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
   
                                 /* clean up if the caller is giving up */  
                                 if ( op->o_abandon ) {  
                                         modinst *m2;  
                                         for ( m2 = mt->mt_mods; m2->mi_next != mi;  
                                                 m2 = m2->mi_next );  
                                         m2->mi_next = mi->mi_next;  
                                         if ( mt->mt_tail == mi ) mt->mt_tail = m2;  
                                         op->o_tmpfree( cb, op->o_tmpmemctx );  
                                         ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );  
                                         return SLAPD_ABANDON;  
                                 }  
                         }                          }
                         ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );                          ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
                 } else {                  } else {
Line 1579  syncprov_op_mod( Operation *op, SlapRepl Line 1477  syncprov_op_mod( Operation *op, SlapRepl
   
         if (( si->si_ops || si->si_logs ) && op->o_tag != LDAP_REQ_ADD )          if (( si->si_ops || si->si_logs ) && op->o_tag != LDAP_REQ_ADD )
                 syncprov_matchops( op, opc, 1 );                  syncprov_matchops( op, opc, 1 );
                   
   
         return SLAP_CB_CONTINUE;          return SLAP_CB_CONTINUE;
 }  }
Line 1706  syncprov_search_response( Operation *op, Line 1605  syncprov_search_response( Operation *op,
                         Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );                          Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );
                         return SLAP_CB_CONTINUE;                          return SLAP_CB_CONTINUE;
                 }                  }
                 if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {                  if ( srs->sr_state.ctxcsn ) {
                         Attribute *a = attr_find( rs->sr_entry->e_attrs,                          Attribute *a = attr_find( rs->sr_entry->e_attrs,
                                 slap_schema.si_ad_entryCSN );                                  slap_schema.si_ad_entryCSN );
                                                   
                         /* Don't send the ctx entry twice */                          /* Don't send the ctx entry twice */
                         if ( a && bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )                          if ( a && bvmatch( &a->a_nvals[0], srs->sr_state.ctxcsn ) )
                                 return LDAP_SUCCESS;                                  return LDAP_SUCCESS;
                 }                  }
                 rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,                  rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
Line 1742  syncprov_search_response( Operation *op, Line 1641  syncprov_search_response( Operation *op,
                                 &cookie, 1, NULL, 0 );                                  &cookie, 1, NULL, 0 );
                         /* Flush any queued persist messages */                          /* Flush any queued persist messages */
                         if ( ss->ss_so->s_res ) {                          if ( ss->ss_so->s_res ) {
                                   syncres *sr, *srnext;
                                   Entry *e;
                                   opcookie opc;
   
                                   opc.son = on;
                                 ldap_pvt_thread_mutex_lock( &ss->ss_so->s_mutex );                                  ldap_pvt_thread_mutex_lock( &ss->ss_so->s_mutex );
                                 locked = 1;                                  locked = 1;
                                 syncprov_qplay( op, on, ss->ss_so );                                  for (sr = ss->ss_so->s_res; sr; sr=srnext) {
                                           int rc = LDAP_SUCCESS;
                                           srnext = sr->s_next;
                                           opc.sdn = sr->s_dn;
                                           opc.sndn = sr->s_ndn;
                                           opc.suuid = sr->s_uuid;
                                           opc.sctxcsn = sr->s_csn;
                                           opc.sreference = sr->s_isreference;
                                           e = NULL;
   
                                           if ( sr->s_mode != LDAP_SYNC_DELETE ) {
                                                   op->o_bd->bd_info = (BackendInfo *)on->on_info;
                                                   rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e );
                                                   op->o_bd->bd_info = (BackendInfo *)on;
                                           }
                                           if ( rc == LDAP_SUCCESS )
                                                   syncprov_sendresp( op, &opc, ss->ss_so, e,
                                                           sr->s_mode, 0 );
   
                                           if ( e ) {
                                                   op->o_bd->bd_info = (BackendInfo *)on->on_info;
                                                   be_entry_release_rw( op, e, 0 );
                                                   op->o_bd->bd_info = (BackendInfo *)on;
                                           }
                                           ch_free( sr );
                                   }
                                   ss->ss_so->s_res = NULL;
                                   ss->ss_so->s_restail = NULL;
                         }                          }
   
                         /* Turn off the refreshing flag */                          /* Turn off the refreshing flag */
Line 1784  syncprov_op_search( Operation *op, SlapR Line 1715  syncprov_op_search( Operation *op, SlapR
         }          }
   
         srs = op->o_controls[slap_cids.sc_LDAPsync];          srs = op->o_controls[slap_cids.sc_LDAPsync];
         op->o_managedsait = SLAP_CONTROL_NONCRITICAL;  
   
         /* If this is a persistent search, set it up right away */          /* If this is a persistent search, set it up right away */
         if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {          if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
Line 1830  syncprov_op_search( Operation *op, SlapR Line 1760  syncprov_op_search( Operation *op, SlapR
         ctxcsn.bv_val = csnbuf;          ctxcsn.bv_val = csnbuf;
                   
         /* If we have a cookie, handle the PRESENT lookups */          /* If we have a cookie, handle the PRESENT lookups */
         if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {          if ( srs->sr_state.ctxcsn ) {
                 sessionlog *sl;                  sessionlog *sl;
   
                 /* The cookie was validated when it was parsed, just use it */                  /* The cookie was validated when it was parsed, just use it */
   
                 /* If just Refreshing and nothing has changed, shortcut it */                  /* If just Refreshing and nothing has changed, shortcut it */
                 if ( bvmatch( &srs->sr_state.ctxcsn, &ctxcsn )) {                  if ( bvmatch( srs->sr_state.ctxcsn, &ctxcsn )) {
                         nochange = 1;                          nochange = 1;
                         if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {                          if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
                                 LDAPControl     *ctrls[2];                                  LDAPControl     *ctrls[2];
Line 1857  syncprov_op_search( Operation *op, SlapR Line 1787  syncprov_op_search( Operation *op, SlapR
                 sl=si->si_logs;                  sl=si->si_logs;
                 if ( sl ) {                  if ( sl ) {
                         ldap_pvt_thread_mutex_lock( &sl->sl_mutex );                          ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
                         if ( ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {                          if ( ber_bvcmp( srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {
                                 do_present = 0;                                  do_present = 0;
                                 /* mutex is unlocked in playlog */                                  /* mutex is unlocked in playlog */
                                 syncprov_playlog( op, rs, sl, &srs->sr_state.ctxcsn, &ctxcsn );                                  syncprov_playlog( op, rs, sl, srs->sr_state.ctxcsn, &ctxcsn );
                         } else {                          } else {
                                 ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );                                  ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
                         }                          }
Line 1900  shortcut: Line 1830  shortcut:
         fava->f_choice = LDAP_FILTER_LE;          fava->f_choice = LDAP_FILTER_LE;
         fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );          fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
         fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;          fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
 #ifdef LDAP_COMP_MATCH  
         fava->f_ava->aa_cf = NULL;  
 #endif  
         ber_dupbv_x( &fava->f_ava->aa_value, &ctxcsn, op->o_tmpmemctx );          ber_dupbv_x( &fava->f_ava->aa_value, &ctxcsn, op->o_tmpmemctx );
         fand->f_and = fava;          fand->f_and = fava;
         if ( gotstate ) {          if ( gotstate ) {
Line 1911  shortcut: Line 1838  shortcut:
                 fava->f_choice = LDAP_FILTER_GE;                  fava->f_choice = LDAP_FILTER_GE;
                 fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );                  fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
                 fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;                  fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
 #ifdef LDAP_COMP_MATCH                  ber_dupbv_x( &fava->f_ava->aa_value, srs->sr_state.ctxcsn, op->o_tmpmemctx );
                 fava->f_ava->aa_cf = NULL;  
 #endif  
                 ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );  
         }          }
         fava->f_next = op->ors_filter;          fava->f_next = op->ors_filter;
         op->ors_filter = fand;          op->ors_filter = fand;
Line 2081  syncprov_db_open( Line 2005  syncprov_db_open(
         Attribute *a;          Attribute *a;
         int rc;          int rc;
   
         if ( slapMode & SLAP_TOOL_MODE ) {  
                 return 0;  
         }  
   
         rc = overlay_register_control( be, LDAP_CONTROL_SYNC );  
         if ( rc ) {  
                 return rc;  
         }  
   
         connection_fake_init( &conn, op, thrctx );          connection_fake_init( &conn, op, thrctx );
         op->o_bd = be;          op->o_bd = be;
         op->o_dn = be->be_rootdn;          op->o_dn = be->be_rootdn;
Line 2118  syncprov_db_open( Line 2033  syncprov_db_open(
                 op->o_req_ndn = be->be_nsuffix[0];                  op->o_req_ndn = be->be_nsuffix[0];
                 op->ors_scope = LDAP_SCOPE_SUBTREE;                  op->ors_scope = LDAP_SCOPE_SUBTREE;
                 syncprov_findcsn( op, FIND_MAXCSN );                  syncprov_findcsn( op, FIND_MAXCSN );
         } else if ( SLAP_SYNC_SHADOW( op->o_bd )) {  
                 /* If we're also a consumer, and we didn't find the context entry,  
                  * then don't generate anything, wait for our provider to send it  
                  * to us.  
                  */  
                 goto out;  
         }          }
   
         if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {          if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) {
Line 2139  syncprov_db_open( Line 2048  syncprov_db_open(
                 syncprov_checkpoint( op, &rs, on );                  syncprov_checkpoint( op, &rs, on );
         }          }
   
 out:  
         op->o_bd->bd_info = (BackendInfo *)on;          op->o_bd->bd_info = (BackendInfo *)on;
         return 0;          return 0;
 }  }
Line 2155  syncprov_db_close( Line 2063  syncprov_db_close(
     syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;      syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
         int i;          int i;
   
         if ( slapMode & SLAP_TOOL_MODE ) {  
                 return 0;  
         }  
         if ( si->si_numops ) {          if ( si->si_numops ) {
                 Connection conn;                  Connection conn;
                 char opbuf[OPERATION_BUFFER_SIZE];                  char opbuf[OPERATION_BUFFER_SIZE];
Line 2305  static int syncprov_parseCtrl ( Line 2210  static int syncprov_parseCtrl (
         sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );          sr = op->o_tmpcalloc( 1, sizeof(struct sync_control), op->o_tmpmemctx );
         sr->sr_rhint = rhint;          sr->sr_rhint = rhint;
         if (!BER_BVISNULL(&cookie)) {          if (!BER_BVISNULL(&cookie)) {
                 ber_dupbv( &sr->sr_state.octet_str, &cookie );                  ber_bvarray_add( &sr->sr_state.octet_str, &cookie );
                 slap_parse_sync_cookie( &sr->sr_state );                  slap_parse_sync_cookie( &sr->sr_state );
         }          }
   

Removed from v.1.56.2.6  
changed lines
  Added in v.1.65


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org