- attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
- attrs[i-1] = 0;
-
- for (i=0, a=e->e_attrs; a; i++, a=a->a_next) {
- attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
- attrs[i]->mod_op = LDAP_MOD_BVALUES;
-#ifdef SLAPD_SCHEMA_NOT_COMPAT
- attrs[i]->mod_type = a->a_desc->ad_cname->bv_val;
-#else
- attrs[i]->mod_type = a->a_type;
-#endif
- attrs[i]->mod_vals.modv_bvals = a->a_vals;
+ 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 ] = &attrs2[ i ];
+ attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
+ attrs[ i ]->mod_type = a->a_desc->ad_cname.bv_val;
+
+ 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 ];
+ }
+ attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;
+ i++;
+ }
+ attrs[ i ] = NULL;
+
+retry:
+ ctrls = op->o_ctrls;
+ rs->sr_err = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
+ li->li_version, &li->li_idassert, op, rs, &ctrls );
+ if ( rs->sr_err != LDAP_SUCCESS ) {
+ send_ldap_result( op, rs );
+ goto cleanup;
+ }
+
+ 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_proxy_authz_ctrl_free( op, &ctrls );
+ goto retry;
+ }
+ }
+
+cleanup:
+ (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+
+ if ( attrs ) {
+ for ( --i; i >= 0; --i ) {
+ ch_free( attrs[ i ]->mod_vals.modv_bvals );
+ }
+ ch_free( attrs );
+ }
+
+ if ( lc ) {
+ ldap_back_release_conn( li, lc );