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; |
} |
} |
|
|