Diff for /servers/slapd/back-meta/add.c between versions 1.27 and 1.27.2.14

version 1.27, 2004/09/04 02:54:33 version 1.27.2.14, 2006/04/05 21:27:52
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/add.c,v 1.26 2004/04/07 02:11:44 kurt Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/add.c,v 1.27.2.13 2006/04/04 22:34:43 kurt Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 1999-2004 The OpenLDAP Foundation.   * Copyright 1999-2006 The OpenLDAP Foundation.
  * Portions Copyright 2001-2003 Pierangelo Masarati.   * Portions Copyright 2001-2003 Pierangelo Masarati.
  * Portions Copyright 1999-2003 Howard Chu.   * Portions Copyright 1999-2003 Howard Chu.
  * All rights reserved.   * All rights reserved.
Line 35 Line 35
 int  int
 meta_back_add( Operation *op, SlapReply *rs )  meta_back_add( Operation *op, SlapReply *rs )
 {  {
         struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;          metainfo_t      *mi = ( metainfo_t * )op->o_bd->be_private;
         struct metaconn *lc;          metaconn_t      *mc;
         int i, candidate = -1;          int             i, candidate = -1;
         Attribute *a;          int             isupdate;
         LDAPMod **attrs;          Attribute       *a;
         struct berval mdn = BER_BVNULL, mapped;          LDAPMod         **attrs;
         dncookie dc;          struct berval   mdn = BER_BVNULL, mapped;
           dncookie        dc;
           int             msgid;
           int             do_retry = 1;
           int             maperr = 1;
   
         Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",          Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",
                         op->o_req_dn.bv_val, 0, 0 );                          op->o_req_dn.bv_val, 0, 0 );
Line 49  meta_back_add( Operation *op, SlapReply Line 53  meta_back_add( Operation *op, SlapReply
         /*          /*
          * get the current connection           * get the current connection
          */           */
         lc = meta_back_getconn( op, rs, META_OP_REQUIRE_SINGLE,          mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
                         &op->o_req_ndn, &candidate );          if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
         if ( !lc ) {                  return rs->sr_err;
                 send_ldap_result( op, rs );  
         }          }
   
         if ( !meta_back_dobind( lc, op )          assert( mc->mc_conns[ candidate ].msc_ld != NULL );
                         || !meta_back_is_valid( lc, candidate ) ) {  
                 rs->sr_err = LDAP_OTHER;  
                 send_ldap_result( op, rs );  
                 return -1;  
         }  
   
         /*          /*
          * Rewrite the add dn, if needed           * Rewrite the add dn, if needed
          */           */
         dc.rwmap = &li->targets[ candidate ]->rwmap;          dc.target = &mi->mi_targets[ candidate ];
         dc.conn = op->o_conn;          dc.conn = op->o_conn;
         dc.rs = rs;          dc.rs = rs;
         dc.ctx = "addDN";          dc.ctx = "addDN";
   
         if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {          if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                 send_ldap_result( op, rs );                  send_ldap_result( op, rs );
                 return -1;                  goto done;
         }          }
   
         /* Count number of attributes in entry */          /* Count number of attributes in entry ( +1 ) */
         for ( i = 1, a = op->oq_add.rs_e->e_attrs; a; i++, a = a->a_next );          for ( i = 1, a = op->ora_e->e_attrs; a; i++, a = a->a_next );
                   
         /* Create array of LDAPMods for ldap_add() */          /* Create array of LDAPMods for ldap_add() */
         attrs = ch_malloc( sizeof( LDAPMod * )*i );          attrs = ch_malloc( sizeof( LDAPMod * )*i );
   
         for ( i = 0, a = op->oq_add.rs_e->e_attrs; a; a = a->a_next ) {          dc.ctx = "addAttrDN";
                 int j;          isupdate = be_shadow_update( op );
           for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) {
                   int                     j, is_oc = 0;
   
                 if ( a->a_desc->ad_type->sat_no_user_mod  ) {                  if ( !isupdate && !get_manageDIT( op ) && a->a_desc->ad_type->sat_no_user_mod  )
                   {
                         continue;                          continue;
                 }                  }
   
                 ldap_back_map( &li->targets[ candidate ]->rwmap.rwm_at,                  if ( a->a_desc == slap_schema.si_ad_objectClass 
                                 &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );                                  || a->a_desc == slap_schema.si_ad_structuralObjectClass )
                 if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {                  {
                         continue;                          is_oc = 1;
                           mapped = a->a_desc->ad_cname;
   
                   } else {
                           ldap_back_map( &mi->mi_targets[ candidate ].mt_rwmap.rwm_at,
                                           &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
                           if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
                                   continue;
                           }
                 }                  }
   
                 attrs[ i ] = ch_malloc( sizeof( LDAPMod ) );                  attrs[ i ] = ch_malloc( sizeof( LDAPMod ) );
Line 101  meta_back_add( Operation *op, SlapReply Line 110  meta_back_add( Operation *op, SlapReply
                 attrs[ i ]->mod_op = LDAP_MOD_BVALUES;                  attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
                 attrs[ i ]->mod_type = mapped.bv_val;                  attrs[ i ]->mod_type = mapped.bv_val;
   
                 /*                  if ( is_oc ) {
                  * FIXME: dn-valued attrs should be rewritten                          for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
                  * to allow their use in ACLs at the back-ldap                                  ;
                  * level.  
                  */                          attrs[ i ]->mod_bvalues =
                 if ( strcmp( a->a_desc->ad_type->sat_syntax->ssyn_oid,                                  (struct berval **)ch_malloc( ( j + 1 ) *
                                         SLAPD_DN_SYNTAX ) == 0 ) {                                  sizeof( struct berval * ) );
                         (void)ldap_dnattr_rewrite( &dc, a->a_vals );  
                 }                          for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
                                   struct ldapmapping      *mapping;
                 for ( j = 0; a->a_vals[ j ].bv_val; j++ );  
                 attrs[ i ]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *));                                  ldap_back_mapping( &mi->mi_targets[ candidate ].mt_rwmap.rwm_oc,
                 for ( j = 0; a->a_vals[ j ].bv_val; j++ ) {                                                  &a->a_vals[ j ], &mapping, BACKLDAP_MAP );
                         attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ];  
                                   if ( mapping == NULL ) {
                                           if ( mi->mi_targets[ candidate ].mt_rwmap.rwm_oc.drop_missing ) {
                                                   continue;
                                           }
                                           attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
   
                                   } else {
                                           attrs[ i ]->mod_bvalues[ j ] = &mapping->dst;
                                   }
                                   j++;
                           }
                           attrs[ i ]->mod_bvalues[ j ] = NULL;
   
                   } else {
                           /*
                            * FIXME: dn-valued attrs should be rewritten
                            * to allow their use in ACLs at the back-ldap
                            * level.
                            */
                           if ( a->a_desc->ad_type->sat_syntax ==
                                   slap_schema.si_syn_distinguishedName )
                           {
                                   (void)ldap_dnattr_rewrite( &dc, a->a_vals );
                                   if ( a->a_vals == NULL ) {
                                           continue;
                                   }
                           }
   
                           for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
                                   ;
                           
                           attrs[ i ]->mod_bvalues = ch_malloc( ( j + 1 ) * sizeof( struct berval * ) );
                           for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
                                   attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
                           }
                           attrs[ i ]->mod_bvalues[ j ] = NULL;
                 }                  }
                 attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;  
                 i++;                  i++;
         }          }
         attrs[ i ] = NULL;          attrs[ i ] = NULL;
   
         ldap_add_s( lc->conns[ candidate ].ld, mdn.bv_val, attrs );  retry:;
           rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
                                 attrs, op->o_ctrls, NULL, &msgid );
           if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                   do_retry = 0;
                   if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                           goto retry;
                   }
                   goto cleanup;
   
           } else if ( rs->sr_err == LDAP_SUCCESS ) {
                   struct timeval  tv, *tvp = NULL;
                   LDAPMessage     *res = NULL;
                   int             rc;
   
                   if ( mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ] != 0 ) {
                           tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ LDAP_BACK_OP_ADD ];
                           tv.tv_usec = 0;
                           tvp = &tv;
                   }
   
                   rs->sr_err = LDAP_OTHER;
                   maperr = 0;
                   rc = ldap_result( mc->mc_conns[ candidate ].msc_ld,
                           msgid, LDAP_MSG_ALL, tvp, &res );
                   switch ( rc ) {
                   case -1:
                           break;
   
                   case 0:
                           ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
                                   msgid, NULL, NULL );
                           rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
                                   LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
                           break;
   
                   case LDAP_RES_ADD:
                           rc = ldap_parse_result( mc->mc_conns[ candidate ].msc_ld,
                                   res, &rs->sr_err, NULL, NULL, NULL, NULL, 1 );
                           if ( rc != LDAP_SUCCESS ) {
                                   rs->sr_err = rc;
                           }
                           maperr = 1;
                           break;
   
                   default:
                           ldap_msgfree( res );
                           break;
                   }
           }
   
           if ( maperr ) {
                   rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
   
           } else {
                   send_ldap_result( op, rs );
           }
   
   cleanup:;
         for ( --i; i >= 0; --i ) {          for ( --i; i >= 0; --i ) {
                 free( attrs[ i ]->mod_vals.modv_bvals );                  free( attrs[ i ]->mod_bvalues );
                 free( attrs[ i ] );                  free( attrs[ i ] );
         }          }
         free( attrs );          free( attrs );
         if ( mdn.bv_val != op->oq_add.rs_e->e_dn ) {          if ( mdn.bv_val != op->ora_e->e_dn ) {
                 free( mdn.bv_val );                  free( mdn.bv_val );
                   BER_BVZERO( &mdn );
           }
   
   done:;
           if ( mc ) {
                   meta_back_release_conn( op, mc );
         }          }
         return meta_back_op_result( lc, op, rs );  
           return rs->sr_err;
 }  }
   

Removed from v.1.27  
changed lines
  Added in v.1.27.2.14


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