Diff for /servers/slapd/overlays/refint.c between versions 1.40 and 1.41

version 1.40, 2008/03/15 17:22:25 version 1.41, 2008/03/15 17:27:24
Line 1 Line 1
 /* refint.c - referential integrity module */  /* refint.c - referential integrity module */
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/refint.c,v 1.39 2008/01/07 23:20:14 kurt Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/refint.c,v 1.40 2008/03/15 17:22:25 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 2004-2008 The OpenLDAP Foundation.   * Copyright 2004-2008 The OpenLDAP Foundation.
Line 492  refint_search_cb( Line 492  refint_search_cb(
         return(0);          return(0);
 }  }
   
   static int
   refint_repair(
           Operation       *op,
           SlapReply       *rs,
           refint_data     *id,
           refint_q        *rq )
   {
           dependent_data  *dp, *dp_next;
           int             rc;
   
           op->o_callback->sc_response = refint_search_cb;
           op->o_req_dn = op->o_bd->be_suffix[ 0 ];
           op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];
           op->o_dn = op->o_bd->be_rootdn;
           op->o_ndn = op->o_bd->be_rootndn;
   
           /* search */
           rc = op->o_bd->be_search( op, rs );
   
           if ( rc != LDAP_SUCCESS ) {
                   Debug( LDAP_DEBUG_TRACE,
                           "refint_repair: search failed: %d\n",
                           rc, 0, 0 );
                   return 0;
           }
   
           /* safety? paranoid just in case */
           if ( op->o_callback->sc_private == NULL ) {
                   Debug( LDAP_DEBUG_TRACE,
                           "refint_repair: callback wiped out sc_private?!\n",
                           0, 0, 0 );
                   return 0;
           }
   
           /* Set up the Modify requests */
           op->o_callback->sc_response = &slap_null_cb;
   
           /*
            * [our search callback builds a list of attrs]
            * foreach attr:
            *      make sure its dn has a backend;
            *      build Modification* chain;
            *      call the backend modify function;
            *
            */
   
           for ( dp = rq->attrs; dp; dp = dp_next ) {
                   Operation       op2 = *op;
                   SlapReply       rs2 = { 0 };
                   refint_attrs    *ra;
                   Modifications   *m, *first = NULL;
   
                   dp_next = dp->next;
   
                   op2.o_tag = LDAP_REQ_MODIFY;
                   op2.orm_modlist = NULL;
                   op2.o_req_dn    = dp->dn;
                   op2.o_req_ndn   = dp->ndn;
                   op2.o_bd = select_backend( &dp->ndn, 1 );
                   if ( !op2.o_bd ) {
                           Debug( LDAP_DEBUG_TRACE,
                                   "refint_repair: no backend for DN %s!\n",
                                   dp->dn.bv_val, 0, 0 );
                           return 0;
                   }
   
                   rs2.sr_type = REP_RESULT;
                   for ( ra = dp->attrs; ra; ra = dp->attrs ) {
                           size_t  len;
   
                           dp->attrs = ra->next;
                           /* Set our ModifiersName */
                           if ( SLAP_LASTMOD( op->o_bd ) ) {
                                   m = op2.o_tmpalloc( sizeof(Modifications) +
                                           4*sizeof(BerValue), op2.o_tmpmemctx );
                                   m->sml_next = op2.orm_modlist;
                                   if ( !first )
                                           first = m;
                                   op2.orm_modlist = m;
                                   m->sml_op = LDAP_MOD_REPLACE;
                                   m->sml_flags = SLAP_MOD_INTERNAL;
                                   m->sml_desc = slap_schema.si_ad_modifiersName;
                                   m->sml_type = m->sml_desc->ad_cname;
                                   m->sml_numvals = 1;
                                   m->sml_values = (BerVarray)(m+1);
                                   m->sml_nvalues = m->sml_values+2;
                                   BER_BVZERO( &m->sml_values[1] );
                                   BER_BVZERO( &m->sml_nvalues[1] );
                                   m->sml_values[0] = refint_dn;
                                   m->sml_nvalues[0] = refint_ndn;
                           }
                           if ( !BER_BVISEMPTY( &rq->newdn ) || ( ra->next &&
                                   ra->attr == ra->next->attr ) )
                           {
                                   len = sizeof(Modifications);
   
                                   if ( ra->new_vals == NULL ) {
                                           len += 4*sizeof(BerValue);
                                   }
   
                                   m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
                                   m->sml_next = op2.orm_modlist;
                                   if ( !first )
                                           first = m;
                                   op2.orm_modlist = m;
                                   m->sml_op = LDAP_MOD_ADD;
                                   m->sml_flags = 0;
                                   m->sml_desc = ra->attr;
                                   m->sml_type = ra->attr->ad_cname;
                                   if ( ra->new_vals == NULL ) {
                                           m->sml_values = (BerVarray)(m+1);
                                           m->sml_nvalues = m->sml_values+2;
                                           BER_BVZERO( &m->sml_values[1] );
                                           BER_BVZERO( &m->sml_nvalues[1] );
                                           m->sml_numvals = 1;
                                           if ( BER_BVISEMPTY( &rq->newdn ) ) {
                                                   op2.o_tmpfree( ra, op2.o_tmpmemctx );
                                                   ra = dp->attrs;
                                                   dp->attrs = ra->next;
                                                   m->sml_values[0] = id->nothing;
                                                   m->sml_nvalues[0] = id->nnothing;
                                           } else {
                                                   m->sml_values[0] = rq->newdn;
                                                   m->sml_nvalues[0] = rq->newndn;
                                           }
                                   } else {
                                           m->sml_values = ra->new_vals;
                                           m->sml_nvalues = ra->new_nvals;
                                           m->sml_numvals = ra->ra_numvals;
                                   }
                           }
   
                           len = sizeof(Modifications);
                           if ( ra->old_vals == NULL ) {
                                   len += 4*sizeof(BerValue);
                           }
   
                           m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
                           m->sml_next = op2.orm_modlist;
                           op2.orm_modlist = m;
                           if ( !first )
                                   first = m;
                           m->sml_op = LDAP_MOD_DELETE;
                           m->sml_flags = 0;
                           m->sml_desc = ra->attr;
                           m->sml_type = ra->attr->ad_cname;
                           if ( ra->old_vals == NULL ) {
                                   m->sml_numvals = 1;
                                   m->sml_values = (BerVarray)(m+1);
                                   m->sml_nvalues = m->sml_values+2;
                                   m->sml_values[0] = rq->olddn;
                                   m->sml_nvalues[0] = rq->oldndn;
                                   BER_BVZERO( &m->sml_values[1] );
                                   BER_BVZERO( &m->sml_nvalues[1] );
                           } else {
                                   m->sml_values = ra->old_vals;
                                   m->sml_nvalues = ra->old_nvals;
                                   m->sml_numvals = ra->ra_numvals;
                           }
                           op2.o_tmpfree( ra, op2.o_tmpmemctx );
                   }
   
                   op2.o_dn = op2.o_bd->be_rootdn;
                   op2.o_ndn = op2.o_bd->be_rootndn;
                   slap_op_time( &op2.o_time, &op2.o_tincr );
                   if ( ( rc = op2.o_bd->be_modify( &op2, &rs2 ) ) != LDAP_SUCCESS ) {
                           Debug( LDAP_DEBUG_TRACE,
                                   "refint_repair: dependent modify failed: %d\n",
                                   rs2.sr_err, 0, 0 );
                   }
   
                   while ( ( m = op2.orm_modlist ) ) {
                           op2.orm_modlist = m->sml_next;
                           if ( m->sml_values && m->sml_values != (BerVarray)(m+1) ) {
                                   ber_bvarray_free_x( m->sml_values, op2.o_tmpmemctx );
                                   ber_bvarray_free_x( m->sml_nvalues, op2.o_tmpmemctx );
                           }
                           op2.o_tmpfree( m, op2.o_tmpmemctx );
                           if ( m == first ) break;
                   }
                   slap_mods_free( op2.orm_modlist, 1 );
                   op2.o_tmpfree( dp->ndn.bv_val, op2.o_tmpmemctx );
                   op2.o_tmpfree( dp->dn.bv_val, op2.o_tmpmemctx );
                   op2.o_tmpfree( dp, op2.o_tmpmemctx );
           }
   
           return 0;
   }
   
 static void *  static void *
 refint_qtask( void *ctx, void *arg )  refint_qtask( void *ctx, void *arg )
 {  {
Line 504  refint_qtask( void *ctx, void *arg ) Line 693  refint_qtask( void *ctx, void *arg )
         slap_callback cb = { NULL, NULL, NULL, NULL };          slap_callback cb = { NULL, NULL, NULL, NULL };
         Filter ftop, *fptr;          Filter ftop, *fptr;
         refint_q *rq;          refint_q *rq;
         dependent_data *dp, *dp_next;          refint_attrs *ip;
         refint_attrs *ra, *ip;  
         int rc;  
   
         connection_fake_init( &conn, &opbuf, ctx );          connection_fake_init( &conn, &opbuf, ctx );
         op = &opbuf.ob_op;          op = &opbuf.ob_op;
Line 553  refint_qtask( void *ctx, void *arg ) Line 740  refint_qtask( void *ctx, void *arg )
                 if ( !rq )                  if ( !rq )
                         break;                          break;
   
                 for (fptr = ftop.f_or; fptr; fptr=fptr->f_next )                  for (fptr = ftop.f_or; fptr; fptr = fptr->f_next )
                         fptr->f_mr_value = rq->oldndn;                          fptr->f_mr_value = rq->oldndn;
   
                 filter2bv_x( op, op->ors_filter, &op->ors_filterstr );                  filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
Line 572  refint_qtask( void *ctx, void *arg ) Line 759  refint_qtask( void *ctx, void *arg )
                 /* no attrs! */                  /* no attrs! */
                 op->ors_attrs = slap_anlist_no_attrs;                  op->ors_attrs = slap_anlist_no_attrs;
   
                 op->o_req_ndn = id->dn;  
                 op->o_req_dn = id->dn;  
                 op->o_bd = rq->db;  
                 op->o_dn = op->o_bd->be_rootdn;  
                 op->o_ndn = op->o_bd->be_rootndn;  
                 slap_op_time( &op->o_time, &op->o_tincr );                  slap_op_time( &op->o_time, &op->o_tincr );
   
                 /* search */                  if ( rq->db != NULL ) {
                 rc = op->o_bd->be_search(op, &rs);                          op->o_bd = rq->db;
                           refint_repair( op, &rs, id, rq );
                 op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );  
   
                 if(rc != LDAP_SUCCESS) {  
                         Debug( LDAP_DEBUG_TRACE,  
                                 "refint_response: search failed: %d\n",  
                                 rc, 0, 0 );  
                         continue;  
                 }  
   
                 /* safety? paranoid just in case */                  } else {
                 if(!cb.sc_private) {                          BackendDB       *be;
                         Debug( LDAP_DEBUG_TRACE,  
                                 "refint_response: callback wiped out sc_private?!\n",  
                                 0, 0, 0 );  
                         continue;  
                 }  
   
                 /* Set up the Modify requests */  
                 cb.sc_response  = &slap_null_cb;  
                 op->o_tag       = LDAP_REQ_MODIFY;  
   
                 /*  
                 ** [our search callback builds a list of attrs]  
                 ** foreach attr:  
                 **      make sure its dn has a backend;  
                 **      build Modification* chain;  
                 **      call the backend modify function;  
                 **  
                 */  
   
                 for(dp = rq->attrs; dp; dp = dp_next) {  
                         Modifications *m, *first = NULL;  
   
                         dp_next = dp->next;  
   
                         op->orm_modlist = NULL;  
   
                         op->o_req_dn    = dp->dn;  
                         op->o_req_ndn   = dp->ndn;  
                         op->o_bd = select_backend(&dp->ndn, 1);  
                         if(!op->o_bd) {  
                                 Debug( LDAP_DEBUG_TRACE,  
                                         "refint_response: no backend for DN %s!\n",  
                                         dp->dn.bv_val, 0, 0 );  
                                 goto done;  
                         }  
                         rs.sr_type      = REP_RESULT;  
                         for (ra = dp->attrs; ra; ra = dp->attrs) {  
                                 size_t  len;  
   
                                 dp->attrs = ra->next;  
                                 /* Set our ModifiersName */  
                                 if ( SLAP_LASTMOD( op->o_bd )) {  
                                         m = op->o_tmpalloc( sizeof(Modifications) +  
                                                 4*sizeof(BerValue), op->o_tmpmemctx );  
                                         m->sml_next = op->orm_modlist;  
                                         if ( !first )  
                                                 first = m;  
                                         op->orm_modlist = m;  
                                         m->sml_op = LDAP_MOD_REPLACE;  
                                         m->sml_flags = SLAP_MOD_INTERNAL;  
                                         m->sml_desc = slap_schema.si_ad_modifiersName;  
                                         m->sml_type = m->sml_desc->ad_cname;  
                                         m->sml_numvals = 1;  
                                         m->sml_values = (BerVarray)(m+1);  
                                         m->sml_nvalues = m->sml_values+2;  
                                         BER_BVZERO( &m->sml_values[1] );  
                                         BER_BVZERO( &m->sml_nvalues[1] );  
                                         m->sml_values[0] = refint_dn;  
                                         m->sml_nvalues[0] = refint_ndn;  
                                 }  
                                 if ( !BER_BVISEMPTY( &rq->newdn ) || ( ra->next &&  
                                         ra->attr == ra->next->attr ))  
                                 {  
                                         len = sizeof(Modifications);  
   
                                         if ( ra->new_vals == NULL ) {  
                                                 len += 4*sizeof(BerValue);  
                                         }  
   
                                         m = op->o_tmpalloc( len, op->o_tmpmemctx );  
                                         m->sml_next = op->orm_modlist;  
                                         if ( !first )  
                                                 first = m;  
                                         op->orm_modlist = m;  
                                         m->sml_op = LDAP_MOD_ADD;  
                                         m->sml_flags = 0;  
                                         m->sml_desc = ra->attr;  
                                         m->sml_type = ra->attr->ad_cname;  
                                         if ( ra->new_vals == NULL ) {  
                                                 m->sml_values = (BerVarray)(m+1);  
                                                 m->sml_nvalues = m->sml_values+2;  
                                                 BER_BVZERO( &m->sml_values[1] );  
                                                 BER_BVZERO( &m->sml_nvalues[1] );  
                                                 m->sml_numvals = 1;  
                                                 if ( BER_BVISEMPTY( &rq->newdn )) {  
                                                         op->o_tmpfree( ra, op->o_tmpmemctx );  
                                                         ra = dp->attrs;  
                                                         dp->attrs = ra->next;  
                                                         m->sml_values[0] = id->nothing;  
                                                         m->sml_nvalues[0] = id->nnothing;  
                                                 } else {  
                                                         m->sml_values[0] = rq->newdn;  
                                                         m->sml_nvalues[0] = rq->newndn;  
                                                 }  
                                         } else {  
                                                 m->sml_values = ra->new_vals;  
                                                 m->sml_nvalues = ra->new_nvals;  
                                                 m->sml_numvals = ra->ra_numvals;  
                                         }  
                                 }  
   
                                 len = sizeof(Modifications);  
                                 if ( ra->old_vals == NULL ) {  
                                         len += 4*sizeof(BerValue);  
                                 }  
   
                                 m = op->o_tmpalloc( len, op->o_tmpmemctx );                          LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
                                 m->sml_next = op->orm_modlist;                                  /* we may want to skip cn=config */
                                 op->orm_modlist = m;                                  if ( be == LDAP_STAILQ_FIRST(&backendDB) ) {
                                 if ( !first )                                          continue;
                                         first = m;  
                                 m->sml_op = LDAP_MOD_DELETE;  
                                 m->sml_flags = 0;  
                                 m->sml_desc = ra->attr;  
                                 m->sml_type = ra->attr->ad_cname;  
                                 if ( ra->old_vals == NULL ) {  
                                         m->sml_numvals = 1;  
                                         m->sml_values = (BerVarray)(m+1);  
                                         m->sml_nvalues = m->sml_values+2;  
                                         m->sml_values[0] = rq->olddn;  
                                         m->sml_nvalues[0] = rq->oldndn;  
                                         BER_BVZERO( &m->sml_values[1] );  
                                         BER_BVZERO( &m->sml_nvalues[1] );  
                                 } else {  
                                         m->sml_values = ra->old_vals;  
                                         m->sml_nvalues = ra->old_nvals;  
                                         m->sml_numvals = ra->ra_numvals;  
                                 }                                  }
                                 op->o_tmpfree( ra, op->o_tmpmemctx );  
                         }  
   
                         op->o_dn = op->o_bd->be_rootdn;                                  if ( be->be_search && be->be_modify ) {
                         op->o_ndn = op->o_bd->be_rootndn;                                          op->o_bd = be;
                         slap_op_time( &op->o_time, &op->o_tincr );                                          refint_repair( op, &rs, id, rq );
                         if((rc = op->o_bd->be_modify(op, &rs)) != LDAP_SUCCESS) {  
                                 Debug( LDAP_DEBUG_TRACE,  
                                         "refint_response: dependent modify failed: %d\n",  
                                         rs.sr_err, 0, 0 );  
                         }  
   
                         while (( m = op->orm_modlist )) {  
                                 op->orm_modlist = m->sml_next;  
                                 if ( m->sml_values && m->sml_values != (BerVarray)(m+1) ) {  
                                         ber_bvarray_free_x( m->sml_values, op->o_tmpmemctx );  
                                         ber_bvarray_free_x( m->sml_nvalues, op->o_tmpmemctx );  
                                 }                                  }
                                 op->o_tmpfree( m, op->o_tmpmemctx );  
                                 if ( m == first ) break;  
                         }                          }
                         slap_mods_free( op->orm_modlist, 1 );  
                         op->o_tmpfree( dp->ndn.bv_val, op->o_tmpmemctx );  
                         op->o_tmpfree( dp->dn.bv_val, op->o_tmpmemctx );  
                         op->o_tmpfree( dp, op->o_tmpmemctx );  
                 }                  }
 done:  
                 if ( !BER_BVISNULL( &rq->newndn )) {                  if ( !BER_BVISNULL( &rq->newndn )) {
                         ch_free( rq->newndn.bv_val );                          ch_free( rq->newndn.bv_val );
                         ch_free( rq->newdn.bv_val );                          ch_free( rq->newdn.bv_val );
Line 789  refint_response( Line 822  refint_response(
         BerValue pdn;          BerValue pdn;
         int ac;          int ac;
         refint_q *rq;          refint_q *rq;
         BackendDB *db;          BackendDB *db = NULL;
         refint_attrs *ip;          refint_attrs *ip;
   
         id->message = "_refint_response";          id->message = "_refint_response";
Line 817  refint_response( Line 850  refint_response(
         **          **
         */          */
   
         db = select_backend(&id->dn, 1);          if ( on->on_info->oi_origdb != frontendDB ) {
                   db = select_backend(&id->dn, 1);
   
         if(db) {                  if ( db ) {
                 if (!db->be_search || !db->be_modify) {                          if ( !db->be_search || !db->be_modify ) {
                                   Debug( LDAP_DEBUG_TRACE,
                                           "refint_response: backend missing search and/or modify\n",
                                           0, 0, 0 );
                                   return SLAP_CB_CONTINUE;
                           }
                   } else {
                         Debug( LDAP_DEBUG_TRACE,                          Debug( LDAP_DEBUG_TRACE,
                                 "refint_response: backend missing search and/or modify\n",                                  "refint_response: no backend for our baseDN %s??\n",
                                 0, 0, 0 );                                  id->dn.bv_val, 0, 0 );
                         return SLAP_CB_CONTINUE;                          return SLAP_CB_CONTINUE;
                 }                  }
         } else {  
                 Debug( LDAP_DEBUG_TRACE,  
                         "refint_response: no backend for our baseDN %s??\n",  
                         id->dn.bv_val, 0, 0 );  
                 return SLAP_CB_CONTINUE;  
         }          }
   
         rq = ch_calloc( 1, sizeof( refint_q ));          rq = ch_calloc( 1, sizeof( refint_q ));
Line 839  refint_response( Line 874  refint_response(
         rq->db = db;          rq->db = db;
         rq->rdata = id;          rq->rdata = id;
   
         if(op->o_tag == LDAP_REQ_MODRDN) {          if ( op->o_tag == LDAP_REQ_MODRDN ) {
                 if ( op->oq_modrdn.rs_newSup ) {                  if ( op->oq_modrdn.rs_newSup ) {
                         pdn = *op->oq_modrdn.rs_newSup;                          pdn = *op->oq_modrdn.rs_newSup;
                 } else {                  } else {

Removed from v.1.40  
changed lines
  Added in v.1.41


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