]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/add.c
Merge remote branch 'origin/mdb.master'
[openldap] / servers / slapd / back-ldap / add.c
index 803bc4aef9819a3d260dbc8ebdad7f34cc56e187..827dd42522340162dff777416715e3a5ae40e8e8 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1999-2004 The OpenLDAP Foundation.
+ * Copyright 1999-2011 The OpenLDAP Foundation.
  * Portions Copyright 2000-2003 Pierangelo Masarati.
  * Portions Copyright 1999-2003 Howard Chu.
  * All rights reserved.
 
 int
 ldap_back_add(
-    Operation  *op,
-    SlapReply  *rs )
+       Operation       *op,
+       SlapReply       *rs )
 {
-       struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
-       struct ldapconn *lc;
-       int i, j;
-       Attribute *a;
-       LDAPMod **attrs;
-       struct berval mapped;
-       struct berval mdn = BER_BVNULL;
-       ber_int_t msgid;
-       dncookie dc;
-       int isupdate;
-#ifdef LDAP_BACK_PROXY_AUTHZ 
-       LDAPControl **ctrls = NULL;
-       int rc = LDAP_SUCCESS;
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( BACK_LDAP, ENTRY, "ldap_back_add: %s\n", op->o_req_dn.bv_val, 0, 0 );
-#else /* !NEW_LOGGING */
-       Debug(LDAP_DEBUG_ARGS, "==> ldap_back_add: %s\n", op->o_req_dn.bv_val, 0, 0);
-#endif /* !NEW_LOGGING */
+       ldapinfo_t              *li = (ldapinfo_t *)op->o_bd->be_private;
+
+       ldapconn_t              *lc = NULL;
+       int                     i = 0,
+                               j = 0;
+       Attribute               *a;
+       LDAPMod                 **attrs = NULL,
+                               *attrs2 = NULL;
+       ber_int_t               msgid;
+       int                     isupdate;
+       ldap_back_send_t        retrying = LDAP_BACK_RETRYING;
+       LDAPControl             **ctrls = NULL;
+
+       rs->sr_err = LDAP_SUCCESS;
        
-       lc = ldap_back_getconn(op, rs);
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
-               return( -1 );
-       }
+       Debug( LDAP_DEBUG_ARGS, "==> ldap_back_add(\"%s\")\n",
+                       op->o_req_dn.bv_val, 0, 0 );
 
-       /*
-        * Rewrite the add dn, if needed
-        */
-       dc.rwmap = &li->rwmap;
-#ifdef ENABLE_REWRITE
-       dc.conn = op->o_conn;
-       dc.rs = rs;
-       dc.ctx = "addDN";
-#else
-       dc.tofrom = 1;
-       dc.normalized = 0;
-#endif
-       if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
-               send_ldap_result( op, rs );
-               return -1;
+       if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
+               lc = NULL;
+               goto cleanup;
        }
 
        /* Count number of attributes in entry */
-       for (i = 1, a = op->oq_add.rs_e->e_attrs; a; i++, a = a->a_next)
-               ;
+       for ( i = 1, a = op->oq_add.rs_e->e_attrs; a; i++, a = a->a_next )
+               /* just count attrs */ ;
        
        /* Create array of LDAPMods for ldap_add() */
-       attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
-
-#ifdef ENABLE_REWRITE
-       dc.ctx = "addAttrDN";
-#endif
-
-       isupdate = be_isupdate( op ) || syncrepl_isupdate( op );
-       for (i=0, a=op->oq_add.rs_e->e_attrs; a; a=a->a_next) {
-               if ( !isupdate && a->a_desc->ad_type->sat_no_user_mod  ) {
-                       continue;
-               }
-
-               ldap_back_map(&li->rwmap.rwm_at, &a->a_desc->ad_cname, &mapped,
-                               BACKLDAP_MAP);
-               if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
-                       continue;
-               }
-
-               attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
-               if (attrs[i] == NULL) {
+       attrs = (LDAPMod **)ch_malloc( sizeof( LDAPMod * )*i 
+                       + sizeof( LDAPMod )*( i - 1 ) );
+       attrs2 = ( LDAPMod * )&attrs[ i ];
+
+       isupdate = be_shadow_update( op );
+       for ( i = 0, a = op->oq_add.rs_e->e_attrs; a; a = a->a_next ) {
+               if ( !isupdate && !get_relax( op ) && a->a_desc->ad_type->sat_no_user_mod  )
+               {
                        continue;
                }
 
-               attrs[i]->mod_op = LDAP_MOD_BVALUES;
-               attrs[i]->mod_type = mapped.bv_val;
+               attrs[ i ] = &attrs2[ i ];
+               attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
+               attrs[ i ]->mod_type = a->a_desc->ad_cname.bv_val;
 
-               if ( a->a_desc->ad_type->sat_syntax ==
-                       slap_schema.si_syn_distinguishedName ) {
-                       /*
-                        * FIXME: rewrite could fail; in this case
-                        * the operation should give up, right?
-                        */
-                       (void)ldap_dnattr_rewrite( &dc, a->a_vals );
+               for ( j = 0; a->a_vals[ j ].bv_val; j++ )
+                       /* just count vals */ ;
+               attrs[i]->mod_vals.modv_bvals = 
+                       ch_malloc( ( j + 1 )*sizeof( struct berval * ) );
+               for ( j = 0; a->a_vals[ j ].bv_val; j++ ) {
+                       attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ];
                }
-
-               for (j=0; a->a_vals[j].bv_val; j++);
-               attrs[i]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *));
-               for (j=0; a->a_vals[j].bv_val; j++)
-                       attrs[i]->mod_vals.modv_bvals[j] = &a->a_vals[j];
-               attrs[i]->mod_vals.modv_bvals[j] = NULL;
+               attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;
                i++;
        }
-       attrs[i] = NULL;
+       attrs[ i ] = NULL;
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
-       if ( rc != LDAP_SUCCESS ) {
+retry:
+       ctrls = op->o_ctrls;
+       rs->sr_err = ldap_back_controls_add( op, rs, lc, &ctrls );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
                goto cleanup;
        }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
 
-       rs->sr_err = ldap_add_ext(lc->ld, mdn.bv_val, attrs,
-#ifdef LDAP_BACK_PROXY_AUTHZ
-                       ctrls,
-#else /* ! LDAP_BACK_PROXY_AUTHZ */
-                       op->o_ctrls,
-#endif /* ! LDAP_BACK_PROXY_AUTHZ */
-                       NULL, &msgid);
+       rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs,
+                       ctrls, NULL, &msgid );
+       rs->sr_err = ldap_back_op_result( lc, op, rs, msgid,
+               li->li_timeout[ SLAP_OP_ADD ],
+               ( LDAP_BACK_SENDRESULT | retrying ) );
+       if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
+               retrying &= ~LDAP_BACK_RETRYING;
+               if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
+                       /* if the identity changed, there might be need to re-authz */
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
+                       goto retry;
+               }
+       }
 
-#ifdef LDAP_BACK_PROXY_AUTHZ
 cleanup:
-       if ( ctrls && ctrls != op->o_ctrls ) {
-               free( ctrls[ 0 ] );
-               free( ctrls );
-       } 
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-
-       for (--i; i>= 0; --i) {
-               ch_free(attrs[i]->mod_vals.modv_bvals);
-               ch_free(attrs[i]);
-       }
-       ch_free(attrs);
-       if ( mdn.bv_val != op->o_req_dn.bv_val ) {
-               free( mdn.bv_val );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
+
+       if ( attrs ) {
+               for ( --i; i >= 0; --i ) {
+                       ch_free( attrs[ i ]->mod_vals.modv_bvals );
+               }
+               ch_free( attrs );
        }
-#ifdef LDAP_BACK_PROXY_AUTHZ
-       if ( rc != LDAP_SUCCESS ) {
-               send_ldap_result( op, rs );
-               return -1;
+
+       if ( lc ) {
+               ldap_back_release_conn( li, lc );
        }
-#endif /* LDAP_BACK_PROXY_AUTHZ */
-       return ldap_back_op_result( lc, op, rs, msgid, 1 ) != LDAP_SUCCESS;
+
+       Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n",
+                       op->o_req_dn.bv_val, rs->sr_err, 0 );
+
+       return rs->sr_err;
 }