Diff for /servers/slapd/overlays/refint.c between versions 1.19.2.3 and 1.19.2.4

version 1.19.2.3, 2007/02/13 20:22:30 version 1.19.2.4, 2007/08/31 23:14:06
Line 1 Line 1
 /* refint.c - referential integrity module */  /* refint.c - referential integrity module */
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/refint.c,v 1.30 2007/01/17 21:22:00 ando Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/refint.c,v 1.36 2007/08/22 15:46:55 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-2007 The OpenLDAP Foundation.   * Copyright 2004-2007 The OpenLDAP Foundation.
Line 48  static BerValue refint_dn = BER_BVC("cn= Line 48  static BerValue refint_dn = BER_BVC("cn=
 static BerValue refint_ndn = BER_BVC("cn=referential integrity overlay");  static BerValue refint_ndn = BER_BVC("cn=referential integrity overlay");
   
 typedef struct refint_attrs_s {  typedef struct refint_attrs_s {
         struct refint_attrs_s *next;          struct refint_attrs_s   *next;
         AttributeDescription *attr;          AttributeDescription    *attr;
           BerVarray               old_vals;
           BerVarray               old_nvals;
           BerVarray               new_vals;
           BerVarray               new_nvals;
 } refint_attrs;  } refint_attrs;
   
 typedef struct dependents_s {  typedef struct dependents_s {
Line 84  typedef struct refint_data_s { Line 88  typedef struct refint_data_s {
   
 #define RUNQ_INTERVAL   36000   /* a long time */  #define RUNQ_INTERVAL   36000   /* a long time */
   
   static MatchingRule     *mr_dnSubtreeMatch;
   
 enum {  enum {
         REFINT_ATTRS = 1,          REFINT_ATTRS = 1,
         REFINT_NOTHING          REFINT_NOTHING
Line 209  refint_cf_gen(ConfigArgs *c) Line 215  refint_cf_gen(ConfigArgs *c)
                                         ip->next = dd->attrs;                                          ip->next = dd->attrs;
                                         dd->attrs = ip;                                          dd->attrs = ip;
                                 } else {                                  } else {
                                         snprintf( c->msg, sizeof( c->msg ),                                          snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                                 "%s <%s>: %s", c->argv[0], c->argv[i], text );                                                  "%s <%s>: %s", c->argv[0], c->argv[i], text );
                                         Debug ( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,                                          Debug ( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
                                                 "%s: %s\n", c->log, c->msg, 0 );                                                  "%s: %s\n", c->log, c->cr_msg, 0 );
                                         rc = ARG_BAD_CONF;                                          rc = ARG_BAD_CONF;
                                 }                                  }
                         }                          }
Line 245  refint_cf_gen(ConfigArgs *c) Line 251  refint_cf_gen(ConfigArgs *c)
   
 static int  static int
 refint_db_init(  refint_db_init(
         BackendDB       *be          BackendDB       *be,
           ConfigReply     *cr
 )  )
 {  {
         slap_overinst *on = (slap_overinst *)be->bd_info;          slap_overinst *on = (slap_overinst *)be->bd_info;
Line 259  refint_db_init( Line 266  refint_db_init(
   
 static int  static int
 refint_db_destroy(  refint_db_destroy(
         BackendDB       *be          BackendDB       *be,
           ConfigReply     *cr
 )  )
 {  {
         slap_overinst *on = (slap_overinst *)be->bd_info;          slap_overinst *on = (slap_overinst *)be->bd_info;
Line 280  refint_db_destroy( Line 288  refint_db_destroy(
   
 static int  static int
 refint_open(  refint_open(
         BackendDB *be          BackendDB *be,
           ConfigReply *cr
 )  )
 {  {
         slap_overinst *on       = (slap_overinst *)be->bd_info;          slap_overinst *on       = (slap_overinst *)be->bd_info;
Line 308  refint_open( Line 317  refint_open(
   
 static int  static int
 refint_close(  refint_close(
         BackendDB *be          BackendDB *be,
           ConfigReply *cr
 )  )
 {  {
         slap_overinst *on       = (slap_overinst *) be->bd_info;          slap_overinst *on       = (slap_overinst *) be->bd_info;
Line 373  refint_search_cb( Line 383  refint_search_cb(
         rq->attrs = ip;          rq->attrs = ip;
         ip->attrs = NULL;          ip->attrs = NULL;
         for(ia = da; ia; ia = ia->next) {          for(ia = da; ia; ia = ia->next) {
             if ( (a = attr_find(rs->sr_entry->e_attrs, ia->attr) ) )                  if ( (a = attr_find(rs->sr_entry->e_attrs, ia->attr) ) ) {
                 for(i = 0, b = a->a_nvals; b[i].bv_val; i++)                          int             first = -1, count = 0, deleted = 0;
                     if(bvmatch(&rq->oldndn, &b[i])) {  
                         na = op->o_tmpalloc(sizeof( refint_attrs ), op->o_tmpmemctx );                          na = NULL;
                         na->next = ip->attrs;  
                         ip->attrs = na;                          for(i = 0, b = a->a_nvals; b[i].bv_val; i++) {
                         na->attr = ia->attr;                                  count++;
                         /* If this is a delete and there's only one value, and  
                          * we have a nothing DN configured, allocate the attr again.                                  if(dnIsSuffix(&b[i], &rq->oldndn)) {
                          */                                          /* first match? create structure */
                         if(!b[1].bv_val && BER_BVISEMPTY( &rq->newdn ) &&                                          if ( na == NULL ) {
                                 dd->nothing.bv_val) {                                                  na = op->o_tmpcalloc( 1,
                                 na = op->o_tmpalloc(sizeof( refint_attrs ), op->o_tmpmemctx );                                                          sizeof( refint_attrs ),
                                 na->next = ip->attrs;                                                          op->o_tmpmemctx );
                                 ip->attrs = na;                                                  na->next = ip->attrs;
                                 na->attr = ia->attr;                                                  ip->attrs = na;
                                                   na->attr = ia->attr;
   
                                                   /* delete, or exact match? note it's first match */
                                                   if ( BER_BVISEMPTY( &rq->newdn ) &&
                                                           b[i].bv_len == rq->oldndn.bv_len )
                                                   {
                                                           first = i;
                                                   }
                                           }
   
                                           /* if it's a rename, or a subordinate match,
                                            * save old and build new dn */
                                           if ( !BER_BVISEMPTY( &rq->newdn ) &&
                                                   b[i].bv_len != rq->oldndn.bv_len )
                                           {
                                                   struct berval   newsub, newdn, olddn, oldndn;
   
                                                   /* if not first, save first as well */
                                                   if ( first != -1 ) {
   
                                                           ber_dupbv_x( &olddn, &a->a_vals[first], op->o_tmpmemctx );
                                                           ber_bvarray_add_x( &na->old_vals, &olddn, op->o_tmpmemctx );
                                                           ber_dupbv_x( &oldndn, &a->a_nvals[first], op->o_tmpmemctx );
                                                           ber_bvarray_add_x( &na->old_nvals, &oldndn, op->o_tmpmemctx );
   
                                                           newsub = a->a_vals[first];
                                                           newsub.bv_len -= rq->olddn.bv_len + 1;
   
                                                           build_new_dn( &newdn, &rq->newdn, &newsub, op->o_tmpmemctx );
   
                                                           ber_bvarray_add_x( &na->new_vals, &newdn, op->o_tmpmemctx );
   
                                                           newsub = a->a_nvals[first];
                                                           newsub.bv_len -= rq->oldndn.bv_len + 1;
   
                                                           build_new_dn( &newdn, &rq->newndn, &newsub, op->o_tmpmemctx );
   
                                                           ber_bvarray_add_x( &na->new_nvals, &newdn, op->o_tmpmemctx );
                                                           
                                                           first = -1;
                                                   }
   
                                                   ber_dupbv_x( &olddn, &a->a_vals[i], op->o_tmpmemctx );
                                                   ber_bvarray_add_x( &na->old_vals, &olddn, op->o_tmpmemctx );
                                                   ber_dupbv_x( &oldndn, &a->a_nvals[i], op->o_tmpmemctx );
                                                   ber_bvarray_add_x( &na->old_nvals, &oldndn, op->o_tmpmemctx );
   
                                                   newsub = a->a_vals[i];
                                                   newsub.bv_len -= rq->olddn.bv_len + 1;
   
                                                   build_new_dn( &newdn, &rq->newdn, &newsub, op->o_tmpmemctx );
   
                                                   ber_bvarray_add_x( &na->new_vals, &newdn, op->o_tmpmemctx );
   
                                                   newsub = a->a_nvals[i];
                                                   newsub.bv_len -= rq->oldndn.bv_len + 1;
   
                                                   build_new_dn( &newdn, &rq->newndn, &newsub, op->o_tmpmemctx );
   
                                                   ber_bvarray_add_x( &na->new_nvals, &newdn, op->o_tmpmemctx );
                                           }
   
                                           /* count deteles */
                                           if ( BER_BVISEMPTY( &rq->newdn ) ) {
                                                   deleted++;
                                           }
                                   }
   
                                   /* If this is a delete and no value would be left, and
                                    * we have a nothing DN configured, allocate the attr again.
                                    */
                                   if ( count == deleted && !BER_BVISNULL(&dd->nothing) )
                                   {
                                           na = op->o_tmpcalloc( 1,
                                                   sizeof( refint_attrs ),
                                                   op->o_tmpmemctx );
                                           na->next = ip->attrs;
                                           ip->attrs = na;
                                           na->attr = ia->attr;
                                   }
   
                                   Debug( LDAP_DEBUG_TRACE, "refint_search_cb: %s: %s (#%d)\n",
                                           a->a_desc->ad_cname.bv_val, rq->olddn.bv_val, count );
                         }                          }
                         Debug(LDAP_DEBUG_TRACE, "refint_search_cb: %s: %s\n",                  }
                                 a->a_desc->ad_cname.bv_val, rq->olddn.bv_val, 0);  
                         break;  
             }  
         }          }
   
         return(0);          return(0);
 }  }
   
Line 410  refint_qtask( void *ctx, void *arg ) Line 501  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;          dependent_data *dp, *dp_next;
         refint_attrs *ra, *ip;          refint_attrs *ra, *ip;
         int rc;          int rc;
   
         op = (Operation *) &opbuf;          connection_fake_init( &conn, &opbuf, ctx );
         connection_fake_init( &conn, op, ctx );          op = &opbuf.ob_op;
   
         /*          /*
         ** build a search filter for all configured attributes;          ** build a search filter for all configured attributes;
Line 432  refint_qtask( void *ctx, void *arg ) Line 523  refint_qtask( void *ctx, void *arg )
         ftop.f_or = NULL;          ftop.f_or = NULL;
         op->ors_filter = &ftop;          op->ors_filter = &ftop;
         for(ip = id->attrs; ip; ip = ip->next) {          for(ip = id->attrs; ip; ip = ip->next) {
                 fptr = op->o_tmpalloc( sizeof(Filter) + sizeof(AttributeAssertion),                  fptr = op->o_tmpcalloc( sizeof(Filter) + sizeof(MatchingRuleAssertion),
                         op->o_tmpmemctx );                          1, op->o_tmpmemctx );
                 fptr->f_choice = LDAP_FILTER_EQUALITY;                  /* Use (attr:dnSubtreeMatch:=value) to catch subtree rename
                 fptr->f_ava = (AttributeAssertion *)(fptr+1);                   * and subtree delete where supported */
                 fptr->f_ava->aa_desc = ip->attr;                  fptr->f_choice = LDAP_FILTER_EXT;
                   fptr->f_mra = (MatchingRuleAssertion *)(fptr+1);
                   fptr->f_mr_rule = mr_dnSubtreeMatch;
                   fptr->f_mr_rule_text = mr_dnSubtreeMatch->smr_str;
                   fptr->f_mr_desc = ip->attr;
                   fptr->f_mr_dnattrs = 0;
                 fptr->f_next = ftop.f_or;                  fptr->f_next = ftop.f_or;
                 ftop.f_or = fptr;                  ftop.f_or = fptr;
         }          }
Line 455  refint_qtask( void *ctx, void *arg ) Line 551  refint_qtask( void *ctx, void *arg )
                         break;                          break;
   
                 for (fptr = ftop.f_or; fptr; fptr=fptr->f_next )                  for (fptr = ftop.f_or; fptr; fptr=fptr->f_next )
                         fptr->f_av_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 513  refint_qtask( void *ctx, void *arg ) Line 609  refint_qtask( void *ctx, void *arg )
                 **                  **
                 */                  */
   
                 for(dp = rq->attrs; dp; dp = dp->next) {                  for(dp = rq->attrs; dp; dp = dp_next) {
                         Modifications *m, *first = NULL;                          Modifications *m, *first = NULL;
   
                           dp_next = dp->next;
   
                         op->orm_modlist = NULL;                          op->orm_modlist = NULL;
   
                         op->o_req_dn    = dp->dn;                          op->o_req_dn    = dp->dn;
                         op->o_req_ndn   = dp->ndn;                          op->o_req_ndn   = dp->ndn;
                         op->o_bd = select_backend(&dp->ndn, 0, 1);                          op->o_bd = select_backend(&dp->ndn, 1);
                         if(!op->o_bd) {                          if(!op->o_bd) {
                                 Debug( LDAP_DEBUG_TRACE,                                  Debug( LDAP_DEBUG_TRACE,
                                         "refint_response: no backend for DN %s!\n",                                          "refint_response: no backend for DN %s!\n",
Line 529  refint_qtask( void *ctx, void *arg ) Line 627  refint_qtask( void *ctx, void *arg )
                         }                          }
                         rs.sr_type      = REP_RESULT;                          rs.sr_type      = REP_RESULT;
                         for (ra = dp->attrs; ra; ra = dp->attrs) {                          for (ra = dp->attrs; ra; ra = dp->attrs) {
                                   size_t  len;
   
                                 dp->attrs = ra->next;                                  dp->attrs = ra->next;
                                 /* Set our ModifiersName */                                  /* Set our ModifiersName */
                                 if ( SLAP_LASTMOD( op->o_bd )) {                                  if ( SLAP_LASTMOD( op->o_bd )) {
Line 550  refint_qtask( void *ctx, void *arg ) Line 650  refint_qtask( void *ctx, void *arg )
                                         m->sml_nvalues[0] = refint_ndn;                                          m->sml_nvalues[0] = refint_ndn;
                                 }                                  }
                                 if ( !BER_BVISEMPTY( &rq->newdn ) || ( ra->next &&                                  if ( !BER_BVISEMPTY( &rq->newdn ) || ( ra->next &&
                                         ra->attr == ra->next->attr )) {                                          ra->attr == ra->next->attr ))
                                         m = op->o_tmpalloc( sizeof(Modifications) +                                  {
                                                 4*sizeof(BerValue), op->o_tmpmemctx );                                          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;                                          m->sml_next = op->orm_modlist;
                                         if ( !first )                                          if ( !first )
                                                 first = m;                                                  first = m;
Line 561  refint_qtask( void *ctx, void *arg ) Line 667  refint_qtask( void *ctx, void *arg )
                                         m->sml_flags = 0;                                          m->sml_flags = 0;
                                         m->sml_desc = ra->attr;                                          m->sml_desc = ra->attr;
                                         m->sml_type = ra->attr->ad_cname;                                          m->sml_type = ra->attr->ad_cname;
                                         m->sml_values = (BerVarray)(m+1);                                          if ( ra->new_vals == NULL ) {
                                         m->sml_nvalues = m->sml_values+2;                                                  m->sml_values = (BerVarray)(m+1);
                                         BER_BVZERO( &m->sml_values[1] );                                                  m->sml_nvalues = m->sml_values+2;
                                         BER_BVZERO( &m->sml_nvalues[1] );                                                  BER_BVZERO( &m->sml_values[1] );
                                         if ( BER_BVISEMPTY( &rq->newdn )) {                                                  BER_BVZERO( &m->sml_nvalues[1] );
                                                 op->o_tmpfree( ra, op->o_tmpmemctx );                                                  if ( BER_BVISEMPTY( &rq->newdn )) {
                                                 ra = dp->attrs;                                                          op->o_tmpfree( ra, op->o_tmpmemctx );
                                                 dp->attrs = ra->next;                                                          ra = dp->attrs;
                                                 m->sml_values[0] = id->nothing;                                                          dp->attrs = ra->next;
                                                 m->sml_nvalues[0] = id->nnothing;                                                          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 {                                          } else {
                                                 m->sml_values[0] = rq->newdn;                                                  m->sml_values = ra->new_vals;
                                                 m->sml_nvalues[0] = rq->newndn;                                                  m->sml_nvalues = ra->new_nvals;
                                         }                                          }
                                 }                                  }
                                 m = op->o_tmpalloc( sizeof(Modifications) + 4*sizeof(BerValue),  
                                         op->o_tmpmemctx );                                  len = sizeof(Modifications);
                                   if ( ra->old_vals == NULL ) {
                                           len += 4*sizeof(BerValue);
                                   }
   
                                   m = op->o_tmpalloc( len, op->o_tmpmemctx );
                                 m->sml_next = op->orm_modlist;                                  m->sml_next = op->orm_modlist;
                                 op->orm_modlist = m;                                  op->orm_modlist = m;
                                 if ( !first )                                  if ( !first )
Line 586  refint_qtask( void *ctx, void *arg ) Line 702  refint_qtask( void *ctx, void *arg )
                                 m->sml_flags = 0;                                  m->sml_flags = 0;
                                 m->sml_desc = ra->attr;                                  m->sml_desc = ra->attr;
                                 m->sml_type = ra->attr->ad_cname;                                  m->sml_type = ra->attr->ad_cname;
                                 m->sml_values = (BerVarray)(m+1);                                  if ( ra->old_vals == NULL ) {
                                 m->sml_nvalues = m->sml_values+2;                                          m->sml_values = (BerVarray)(m+1);
                                 m->sml_values[0] = rq->olddn;                                          m->sml_nvalues = m->sml_values+2;
                                 m->sml_nvalues[0] = rq->oldndn;                                          m->sml_values[0] = rq->olddn;
                                 BER_BVZERO( &m->sml_values[1] );                                          m->sml_nvalues[0] = rq->oldndn;
                                 BER_BVZERO( &m->sml_nvalues[1] );                                          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;
                                   }
                                 op->o_tmpfree( ra, op->o_tmpmemctx );                                  op->o_tmpfree( ra, op->o_tmpmemctx );
                         }                          }
   
Line 606  refint_qtask( void *ctx, void *arg ) Line 727  refint_qtask( void *ctx, void *arg )
   
                         while (( m = op->orm_modlist )) {                          while (( m = op->orm_modlist )) {
                                 op->orm_modlist = m->sml_next;                                  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 );                                  op->o_tmpfree( m, op->o_tmpmemctx );
                                 if ( m == first ) break;                                  if ( m == first ) break;
                         }                          }
Line 624  done: Line 749  done:
                 ch_free( rq );                  ch_free( rq );
         }          }
   
           /* free filter */
           for ( fptr = ftop.f_or; fptr; ) {
                   Filter *f_next = fptr->f_next;
                   op->o_tmpfree( fptr, op->o_tmpmemctx );
                   fptr = f_next;
           }
   
         /* wait until we get explicitly scheduled again */          /* wait until we get explicitly scheduled again */
         ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );          ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
         ldap_pvt_runqueue_stoptask( &slapd_rq, id->qtask );          ldap_pvt_runqueue_stoptask( &slapd_rq, id->qtask );
Line 677  refint_response( Line 809  refint_response(
         **          **
         */          */
   
         db = select_backend(&id->dn, 0, 1);          db = select_backend(&id->dn, 1);
   
         if(db) {          if(db) {
                 if (!db->be_search || !db->be_modify) {                  if (!db->be_search || !db->be_modify) {
Line 754  refint_response( Line 886  refint_response(
 int refint_initialize() {  int refint_initialize() {
         int rc;          int rc;
   
           mr_dnSubtreeMatch = mr_find( "dnSubtreeMatch" );
           if ( mr_dnSubtreeMatch == NULL ) {
                   Debug( LDAP_DEBUG_ANY, "refint_initialize: "
                           "unable to find MatchingRule 'dnSubtreeMatch'.\n",
                           0, 0, 0 );
                   return 1;
           }
   
         /* statically declared just after the #includes at top */          /* statically declared just after the #includes at top */
         refint.on_bi.bi_type = "refint";          refint.on_bi.bi_type = "refint";
         refint.on_bi.bi_db_init = refint_db_init;          refint.on_bi.bi_db_init = refint_db_init;

Removed from v.1.19.2.3  
changed lines
  Added in v.1.19.2.4


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