/* return 0 IFF op_dn is a value in group_at (member) attribute * of entry with gr_dn AND that entry has an objectClass * value of group_oc (groupOfNames) */ int ldap_back_group( Backend *be, Connection *conn, Operation *op, Entry *target, struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, AttributeDescription* group_at ) { struct ldapinfo *li = (struct ldapinfo *) be->be_private; int rc = 1; Attribute *attr; LDAPMessage *result; char *gattr[2]; char *filter = NULL, *ptr; LDAP *ld; struct berval mop_ndn = { 0, NULL }, mgr_ndn = { 0, NULL }; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; struct berval group_oc_name = {0, NULL}; struct berval group_at_name = group_at->ad_cname; if( group_oc->soc_names && group_oc->soc_names[0] ) { group_oc_name.bv_val = group_oc->soc_names[0]; } else { group_oc_name.bv_val = group_oc->soc_oid; } if (group_oc_name.bv_val) group_oc_name.bv_len = strlen(group_oc_name.bv_val); if (target != NULL && dn_match( &target->e_nname, gr_ndn ) ) { /* we already have a copy of the entry */ /* attribute and objectclass mapping has already been done */ /* * first we need to check if the objectClass attribute * has been retieved; otherwise we need to repeat the search */ attr = attr_find( target->e_attrs, ad_objectClass ); if ( attr != NULL ) { /* * Now we can check for the group objectClass value */ if( !is_entry_objectclass( target, group_oc, 0 ) ) { return(1); } /* * This part has been reworked: the group attr compare * fails only if the attribute is PRESENT but the value * is NOT PRESENT; if the attribute is NOT PRESENT, the * search must be repeated as well. * This may happen if a search for an entry has already * been performed (target is not null) but the group * attribute has not been required */ if ((attr = attr_find(target->e_attrs, group_at)) != NULL) { if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH, attr->a_vals, op_ndn ) != LDAP_SUCCESS ) return(1); return(0); } /* else: repeat the search */ } /* else: repeat the search */ } /* else: do the search */ /* * Rewrite the op ndn if needed */ #ifdef ENABLE_REWRITE switch ( rewrite_session( li->rwinfo, "bindDn", op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) { case REWRITE_REGEXEC_OK: if ( mop_ndn.bv_val == NULL ) { mop_ndn = *op_ndn; } #ifdef NEW_LOGGING LDAP_LOG( BACK_LDAP, DETAIL1, "[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n", op_ndn->bv_val, mop_ndn.bv_val, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> bindDn (op ndn in group): \"%s\" -> \"%s\"\n%s", op_ndn->bv_val, mop_ndn.bv_val, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: case REWRITE_REGEXEC_ERR: goto cleanup; } /* * Rewrite the gr ndn if needed */ switch ( rewrite_session( li->rwinfo, "searchBase", gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) { case REWRITE_REGEXEC_OK: if ( mgr_ndn.bv_val == NULL ) { mgr_ndn = *gr_ndn; } #ifdef NEW_LOGGING LDAP_LOG( BACK_LDAP, DETAIL1, "[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n%s", gr_ndn->bv_val, mgr_ndn.bv_val, "" ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> searchBase (gr ndn in group):" " \"%s\" -> \"%s\"\n%s", gr_ndn->bv_val, mgr_ndn.bv_val, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: case REWRITE_REGEXEC_ERR: goto cleanup; } #else /* !ENABLE_REWRITE */ ldap_back_dn_massage( li, op_ndn, &mop_ndn, 1, 1 ); if ( mop_ndn.bv_val == NULL ) { goto cleanup; } ldap_back_dn_massage( li, gr_ndn, &mgr_ndn, 1, 1 ); if ( mgr_ndn.bv_val == NULL ) { goto cleanup; } #endif /* !ENABLE_REWRITE */ ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name, BACKLDAP_MAP); if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0') goto cleanup; ldap_back_map(&li->at_map, &group_at_name, &group_at_name, BACKLDAP_MAP); if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0') goto cleanup; filter = ch_malloc(sizeof("(&(objectclass=)(=))") + group_oc_name.bv_len + group_at_name.bv_len + mop_ndn.bv_len + 1); if (filter == NULL) goto cleanup; if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) { goto cleanup; } if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { goto cleanup; } ptr = lutil_strcopy(filter, "(&(objectclass="); ptr = lutil_strcopy(ptr, group_oc_name.bv_val); ptr = lutil_strcopy(ptr, ")("); ptr = lutil_strcopy(ptr, group_at_name.bv_val); ptr = lutil_strcopy(ptr, "="); ptr = lutil_strcopy(ptr, mop_ndn.bv_val); strcpy(ptr, "))"); gattr[0] = "objectclass"; gattr[1] = NULL; if (ldap_search_ext_s(ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter, gattr, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) { if (ldap_first_entry(ld, result) != NULL) rc = 0; ldap_msgfree(result); } cleanup:; if ( ld != NULL ) { ldap_unbind(ld); } ch_free(filter); if ( mop_ndn.bv_val != op_ndn->bv_val ) { free( mop_ndn.bv_val ); } if ( mgr_ndn.bv_val != gr_ndn->bv_val ) { free( mgr_ndn.bv_val ); } return(rc); }
/* * massages "in" into "dn" * * "dn" may contain the value of "in" if no massage occurred */ int rwm_dn_massage( dncookie *dc, struct berval *in, struct berval *dn ) { int rc = 0; struct berval mdn; static char *dmy = ""; char *in_val; assert( dc != NULL ); assert( in != NULL ); assert( dn != NULL ); /* protect from NULL berval */ in_val = in->bv_val ? in->bv_val : dmy; rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx, in_val, dc->conn, &mdn.bv_val ); switch ( rc ) { case REWRITE_REGEXEC_OK: if ( !BER_BVISNULL( &mdn ) && mdn.bv_val != in_val ) { mdn.bv_len = strlen( mdn.bv_val ); *dn = mdn; } else { dn->bv_len = in->bv_len; dn->bv_val = in_val; } rc = LDAP_SUCCESS; Debug( LDAP_DEBUG_ARGS, "[rw] %s: \"%s\" -> \"%s\"\n", dc->ctx, in_val, dn->bv_val ); break; case REWRITE_REGEXEC_UNWILLING: if ( dc->rs ) { dc->rs->sr_err = LDAP_UNWILLING_TO_PERFORM; dc->rs->sr_text = "Operation not allowed"; } rc = LDAP_UNWILLING_TO_PERFORM; break; case REWRITE_REGEXEC_ERR: if ( dc->rs ) { dc->rs->sr_err = LDAP_OTHER; dc->rs->sr_text = "Rewrite error"; } rc = LDAP_OTHER; break; } if ( mdn.bv_val == dmy ) { BER_BVZERO( &mdn ); } if ( dn->bv_val == dmy ) { BER_BVZERO( dn ); } return rc; }
/* * init_one_conn * * Initializes one connection */ static int init_one_conn( Connection *conn, Operation *op, struct metatarget *lt, struct metasingleconn *lsc ) { int err, vers; /* * Already init'ed */ if ( lsc->ld != NULL ) { return LDAP_SUCCESS; } /* * Attempts to initialize the connection to the target ds */ err = ldap_initialize( &lsc->ld, lt->uri ); if ( err != LDAP_SUCCESS ) { return ldap_back_map_result( err ); } /* * Set LDAP version. This will always succeed: If the client * bound with a particular version, then so can we. */ vers = conn->c_protocol; ldap_set_option( lsc->ld, LDAP_OPT_PROTOCOL_VERSION, &vers ); /* * Sets a cookie for the rewrite session */ ( void )rewrite_session_init( lt->rwinfo, conn ); /* * If the connection dn is not null, an attempt to rewrite it is made */ if ( conn->c_dn.bv_len != 0 ) { /* * Rewrite the bind dn if needed */ lsc->bound_dn.bv_val = NULL; switch ( rewrite_session( lt->rwinfo, "bindDn", conn->c_dn.bv_val, conn, &lsc->bound_dn.bv_val ) ) { case REWRITE_REGEXEC_OK: if ( lsc->bound_dn.bv_val == NULL ) { ber_dupbv( &lsc->bound_dn, &conn->c_dn ); } #ifdef NEW_LOGGING LDAP_LOG( BACK_META, DETAIL1, "[rw] bindDn: \"%s\" -> \"%s\"\n", conn->c_dn.bv_val, lsc->bound_dn.bv_val, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> bindDn: \"%s\" -> \"%s\"\n", conn->c_dn.bv_val, lsc->bound_dn.bv_val, 0 ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Operation not allowed", NULL, NULL ); return LDAP_UNWILLING_TO_PERFORM; case REWRITE_REGEXEC_ERR: send_ldap_result( conn, op, LDAP_OTHER, NULL, "Rewrite error", NULL, NULL ); return LDAP_OTHER; } assert( lsc->bound_dn.bv_val ); } else { ber_str2bv( "", 0, 1, &lsc->bound_dn ); } lsc->bound = META_UNBOUND; /* * The candidate is activated */ lsc->candidate = META_CANDIDATE; return LDAP_SUCCESS; }
int rwm_filter_map_rewrite( Operation *op, dncookie *dc, Filter *f, struct berval *fstr ) { int rc; dncookie fdc; struct berval ftmp; rc = rwm_int_filter_map_rewrite( op, dc, f, fstr ); if ( rc != 0 ) { return rc; } fdc = *dc; ftmp = *fstr; fdc.ctx = "searchFilter"; switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx, ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ), fdc.conn, &fstr->bv_val ) ) { case REWRITE_REGEXEC_OK: if ( !BER_BVISNULL( fstr ) ) { fstr->bv_len = strlen( fstr->bv_val ); } else { *fstr = ftmp; } Debug( LDAP_DEBUG_ARGS, "[rw] %s: \"%s\" -> \"%s\"\n", fdc.ctx, ftmp.bv_val, fstr->bv_val ); if ( fstr->bv_val != ftmp.bv_val ) { ber_bvreplace_x( &ftmp, fstr, op->o_tmpmemctx ); ch_free( fstr->bv_val ); *fstr = ftmp; } rc = LDAP_SUCCESS; break; case REWRITE_REGEXEC_UNWILLING: if ( fdc.rs ) { fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM; fdc.rs->sr_text = "Operation not allowed"; } op->o_tmpfree( ftmp.bv_val, op->o_tmpmemctx ); rc = LDAP_UNWILLING_TO_PERFORM; break; case REWRITE_REGEXEC_ERR: if ( fdc.rs ) { fdc.rs->sr_err = LDAP_OTHER; fdc.rs->sr_text = "Rewrite error"; } op->o_tmpfree( ftmp.bv_val, op->o_tmpmemctx ); rc = LDAP_OTHER; break; } return rc; }
int ldap_back_filter_map_rewrite( dncookie *dc, Filter *f, struct berval *fstr, int remap, void *memctx ) { int rc; dncookie fdc; struct berval ftmp; static char *dmy = ""; rc = ldap_back_int_filter_map_rewrite( dc, f, fstr, remap, memctx ); #ifdef ENABLE_REWRITE if ( rc != LDAP_SUCCESS ) { return rc; } fdc = *dc; ftmp = *fstr; fdc.ctx = "searchFilter"; switch ( rewrite_session( fdc.target->mt_rwmap.rwm_rw, fdc.ctx, ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : dmy ), fdc.conn, &fstr->bv_val ) ) { case REWRITE_REGEXEC_OK: if ( !BER_BVISNULL( fstr ) ) { fstr->bv_len = strlen( fstr->bv_val ); } else { *fstr = ftmp; } Debug( LDAP_DEBUG_ARGS, "[rw] %s: \"%s\" -> \"%s\"\n", fdc.ctx, BER_BVISNULL( &ftmp ) ? "" : ftmp.bv_val, BER_BVISNULL( fstr ) ? "" : fstr->bv_val ); rc = LDAP_SUCCESS; break; case REWRITE_REGEXEC_UNWILLING: if ( fdc.rs ) { fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM; fdc.rs->sr_text = "Operation not allowed"; } rc = LDAP_UNWILLING_TO_PERFORM; break; case REWRITE_REGEXEC_ERR: if ( fdc.rs ) { fdc.rs->sr_err = LDAP_OTHER; fdc.rs->sr_text = "Rewrite error"; } rc = LDAP_OTHER; break; } if ( fstr->bv_val == dmy ) { BER_BVZERO( fstr ); } else if ( fstr->bv_val != ftmp.bv_val ) { /* NOTE: need to realloc mapped filter on slab * and free the original one, until librewrite * becomes slab-aware */ ber_dupbv_x( &ftmp, fstr, memctx ); ch_free( fstr->bv_val ); *fstr = ftmp; } #endif /* ENABLE_REWRITE */ return rc; }
int meta_back_compare( Backend *be, Connection *conn, Operation *op, struct berval *dn, struct berval *ndn, AttributeAssertion *ava ) { struct metainfo *li = ( struct metainfo * )be->be_private; struct metaconn *lc; struct metasingleconn *lsc; char *match = NULL, *err = NULL, *mmatch = NULL; int candidates = 0, last = 0, i, count, rc; int cres = LDAP_SUCCESS, rres = LDAP_SUCCESS; int *msgid; lc = meta_back_getconn( li, conn, op, META_OP_ALLOW_MULTIPLE, ndn, NULL ); if ( !lc || !meta_back_dobind( lc, op ) ) { send_ldap_result( conn, op, LDAP_OTHER, NULL, NULL, NULL, NULL ); return -1; } msgid = ch_calloc( sizeof( int ), li->ntargets ); if ( msgid == NULL ) { return -1; } /* * start an asynchronous compare for each candidate target */ for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) { char *mdn = NULL; struct berval mapped_attr = ava->aa_desc->ad_cname; struct berval mapped_value = ava->aa_value; if ( lsc->candidate != META_CANDIDATE ) { msgid[ i ] = -1; continue; } /* * Rewrite the compare dn, if needed */ switch ( rewrite_session( li->targets[ i ]->rwinfo, "compareDn", dn->bv_val, conn, &mdn ) ) { case REWRITE_REGEXEC_OK: if ( mdn == NULL ) { mdn = ( char * )dn->bv_val; } #ifdef NEW_LOGGING LDAP_LOG( BACK_META, DETAIL1, "[rw] compareDn: \"%s\" -> \"%s\"\n", dn->bv_val, mdn, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> compareDn: \"%s\" -> \"%s\"\n%s", dn->bv_val, mdn, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Operation not allowed", NULL, NULL ); return -1; case REWRITE_REGEXEC_ERR: send_ldap_result( conn, op, LDAP_OTHER, NULL, "Rewrite error", NULL, NULL ); return -1; } /* * if attr is objectClass, try to remap the value */ if ( ava->aa_desc == slap_schema.si_ad_objectClass ) { ldap_back_map( &li->targets[ i ]->oc_map, &ava->aa_value, &mapped_value, BACKLDAP_MAP ); if ( mapped_value.bv_val == NULL || mapped_value.bv_val[0] == '\0' ) { continue; } /* * else try to remap the attribute */ } else { ldap_back_map( &li->targets[ i ]->at_map, &ava->aa_desc->ad_cname, &mapped_attr, BACKLDAP_MAP ); if ( mapped_attr.bv_val == NULL || mapped_attr.bv_val[0] == '\0' ) { continue; } } /* * the compare op is spawned across the targets and the first * that returns determines the result; a constraint on unicity * of the result ought to be enforced */ msgid[ i ] = ldap_compare( lc->conns[ i ].ld, mdn, mapped_attr.bv_val, mapped_value.bv_val ); if ( mdn != dn->bv_val ) { free( mdn ); } if ( mapped_attr.bv_val != ava->aa_desc->ad_cname.bv_val ) { free( mapped_attr.bv_val ); } if ( mapped_value.bv_val != ava->aa_value.bv_val ) { free( mapped_value.bv_val ); } if ( msgid[ i ] == -1 ) { continue; } ++candidates; } /* * wait for replies */ for ( rc = 0, count = 0; candidates > 0; ) { /* * FIXME: should we check for abandon? */ for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) { int lrc; LDAPMessage *res = NULL; if ( msgid[ i ] == -1 ) { continue; } lrc = ldap_result( lsc->ld, msgid[ i ], 0, NULL, &res ); if ( lrc == 0 ) { /* * FIXME: should we yield? */ if ( res ) { ldap_msgfree( res ); } continue; } else if ( lrc == LDAP_RES_COMPARE ) { if ( count > 0 ) { rres = LDAP_OTHER; rc = -1; goto finish; } cres = ldap_result2error( lsc->ld, res, 1 ); switch ( cres ) { case LDAP_COMPARE_TRUE: case LDAP_COMPARE_FALSE: /* * true or flase, got it; * sending to cache ... */ if ( li->cache.ttl != META_DNCACHE_DISABLED ) { ( void )meta_dncache_update_entry( &li->cache, ndn, i ); } count++; rc = 0; break; default: rres = ldap_back_map_result( cres ); if ( err != NULL ) { free( err ); } ldap_get_option( lsc->ld, LDAP_OPT_ERROR_STRING, &err ); if ( match != NULL ) { free( match ); } ldap_get_option( lsc->ld, LDAP_OPT_MATCHED_DN, &match ); last = i; break; } msgid[ i ] = -1; --candidates; } else { msgid[ i ] = -1; --candidates; if ( res ) { ldap_msgfree( res ); } break; } } } finish:; /* * Rewrite the matched portion of the search base, if required * * FIXME: only the last one gets caught! */ if ( count == 1 ) { if ( match != NULL ) { free( match ); match = NULL; } /* * the result of the compare is assigned to the res code * that will be returned */ rres = cres; } else if ( match != NULL ) { /* * At least one compare failed with matched portion, * and none was successful */ switch ( rewrite_session( li->targets[ last ]->rwinfo, "matchedDn", match, conn, &mmatch ) ) { case REWRITE_REGEXEC_OK: if ( mmatch == NULL ) { mmatch = ( char * )match; } #ifdef NEW_LOGGING LDAP_LOG( BACK_META, DETAIL1, "[rw] matchedDn: \"%s\" -> \"%s\"\n", match, mmatch, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> matchedDn:" " \"%s\" -> \"%s\"\n%s", match, mmatch, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Operation not allowed", NULL, NULL ); rc = -1; goto cleanup; case REWRITE_REGEXEC_ERR: send_ldap_result( conn, op, LDAP_OTHER, NULL, "Rewrite error", NULL, NULL ); rc = -1; goto cleanup; } } send_ldap_result( conn, op, rres, mmatch, err, NULL, NULL ); cleanup:; if ( match != NULL ) { if ( mmatch != match ) { free( mmatch ); } free( match ); } if ( msgid ) { free( msgid ); } return rc; }
static void apply( FILE *fin, const char *rewriteContext, const char *arg ) { struct rewrite_info *info; char *string, *sep, *result = NULL; int rc; void *cookie = &info; info = rewrite_info_init( REWRITE_MODE_ERR ); if ( rewrite_read( fin, info ) != 0 ) { exit( EXIT_FAILURE ); } rewrite_param_set( info, "prog", "rewrite" ); rewrite_session_init( info, cookie ); string = (char *)arg; for ( sep = strchr( rewriteContext, ',' ); rewriteContext != NULL; rewriteContext = sep, sep ? sep = strchr( rewriteContext, ',' ) : NULL ) { char *errmsg = ""; if ( sep != NULL ) { sep[ 0 ] = '\0'; sep++; } /* rc = rewrite( info, rewriteContext, string, &result ); */ rc = rewrite_session( info, rewriteContext, string, cookie, &result ); switch ( rc ) { case REWRITE_REGEXEC_OK: errmsg = "ok"; break; case REWRITE_REGEXEC_ERR: errmsg = "error"; break; case REWRITE_REGEXEC_STOP: errmsg = "stop"; break; case REWRITE_REGEXEC_UNWILLING: errmsg = "unwilling to perform"; break; default: if (rc >= REWRITE_REGEXEC_USER) { errmsg = "user-defined"; } else { errmsg = "unknown"; } break; } fprintf( stdout, "%s -> %s [%d:%s]\n", string, ( result ? result : "(null)" ), rc, errmsg ); if ( result == NULL ) { break; } if ( string != arg && string != result ) { free( string ); } string = result; } if ( result && result != arg ) { free( result ); } rewrite_session_delete( info, cookie ); rewrite_info_delete( &info ); }
int meta_back_modify( Backend *be, Connection *conn, Operation *op, struct berval *dn, struct berval *ndn, Modifications *modlist ) { struct metainfo *li = ( struct metainfo * )be->be_private; struct metaconn *lc; LDAPMod **modv; LDAPMod *mods; Modifications *ml; int candidate = -1, i; char *mdn; struct berval mapped; lc = meta_back_getconn( li, conn, op, META_OP_REQUIRE_SINGLE, ndn, &candidate ); if ( !lc || !meta_back_dobind( lc, op ) || !meta_back_is_valid( lc, candidate ) ) { send_ldap_result( conn, op, LDAP_OTHER, NULL, NULL, NULL, NULL ); return -1; } /* * Rewrite the modify dn, if needed */ switch ( rewrite_session( li->targets[ candidate ]->rwinfo, "modifyDn", dn->bv_val, conn, &mdn ) ) { case REWRITE_REGEXEC_OK: if ( mdn == NULL ) { mdn = ( char * )dn->bv_val; } #ifdef NEW_LOGGING LDAP_LOG( BACK_META, DETAIL1, "[rw] modifyDn: \"%s\" -> \"%s\"\n", dn->bv_val, mdn, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> modifyDn: \"%s\" -> \"%s\"\n%s", dn->bv_val, mdn, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL, "Operation not allowed", NULL, NULL ); return -1; case REWRITE_REGEXEC_ERR: send_ldap_result( conn, op, LDAP_OTHER, NULL, "Rewrite error", NULL, NULL ); return -1; } for ( i = 0, ml = modlist; ml; i++ ,ml = ml->sml_next ) ; mods = ch_malloc( sizeof( LDAPMod )*i ); if ( mods == NULL ) { if ( mdn != dn->bv_val ) { free( mdn ); } return -1; } modv = ( LDAPMod ** )ch_malloc( ( i + 1 )*sizeof( LDAPMod * ) ); if ( modv == NULL ) { free( mods ); if ( mdn != dn->bv_val ) { free( mdn ); } return -1; } for ( i = 0, ml = modlist; ml; ml = ml->sml_next ) { int j; if ( ml->sml_desc->ad_type->sat_no_user_mod ) { continue; } ldap_back_map( &li->targets[ candidate ]->at_map, &ml->sml_desc->ad_cname, &mapped, BACKLDAP_MAP ); if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) { continue; } modv[ i ] = &mods[ i ]; mods[ i ].mod_op = ml->sml_op | LDAP_MOD_BVALUES; mods[ i ].mod_type = mapped.bv_val; /* * FIXME: dn-valued attrs should be rewritten * to allow their use in ACLs at the back-ldap * level. */ if ( strcmp( ml->sml_desc->ad_type->sat_syntax->ssyn_oid, SLAPD_DN_SYNTAX ) == 0 ) { ldap_dnattr_rewrite( li->targets[ candidate ]->rwinfo, ml->sml_bvalues, conn ); } if ( ml->sml_bvalues != NULL ){ for (j = 0; ml->sml_bvalues[ j ].bv_val; j++); mods[ i ].mod_bvalues = (struct berval **)ch_malloc((j+1) * sizeof(struct berval *)); for (j = 0; ml->sml_bvalues[ j ].bv_val; j++) mods[ i ].mod_bvalues[ j ] = &ml->sml_bvalues[j]; mods[ i ].mod_bvalues[ j ] = NULL; } else { mods[ i ].mod_bvalues = NULL; } i++; } modv[ i ] = 0; ldap_modify_s( lc->conns[ candidate ].ld, mdn, modv ); if ( mdn != dn->bv_val ) { free( mdn ); } for ( i=0; modv[ i ]; i++) free( modv[ i ]->mod_bvalues ); free( mods ); free( modv ); return meta_back_op_result( lc, op ); }