Example #1
0
void
slap_sl_mem_destroy(
    void *key,
    void *data
)
{
    struct slab_heap *sh = data;
    int pad = 2*sizeof(int)-1, pad_shift;
    int order_start = -1, i;
    struct slab_object *so;

    if (sh->sh_stack) {
        ber_memfree_x(sh->sh_base, NULL);
        ber_memfree_x(sh, NULL);
    } else {
        pad_shift = pad - 1;
        do {
            order_start++;
        } while (pad_shift >>= 1);

        for (i = 0; i <= sh->sh_maxorder - order_start; i++) {
            so = LDAP_LIST_FIRST(&sh->sh_free[i]);
            while (so) {
                struct slab_object *so_tmp = so;
                so = LDAP_LIST_NEXT(so, so_link);
                LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_tmp, so_link);
            }
            ch_free(sh->sh_map[i]);
        }
        ch_free(sh->sh_free);
        ch_free(sh->sh_map);

        so = LDAP_LIST_FIRST(&sh->sh_sopool);
        while (so) {
            struct slab_object *so_tmp = so;
            so = LDAP_LIST_NEXT(so, so_link);
            if (!so_tmp->so_blockhead) {
                LDAP_LIST_REMOVE(so_tmp, so_link);
            }
        }
        so = LDAP_LIST_FIRST(&sh->sh_sopool);
        while (so) {
            struct slab_object *so_tmp = so;
            so = LDAP_LIST_NEXT(so, so_link);
            ch_free(so_tmp);
        }
        ber_memfree_x(sh->sh_base, NULL);
        ber_memfree_x(sh, NULL);
    }
}
RETCODE
backsql_FreeRow_x( BACKSQL_ROW_NTS *row, void *ctx )
{
	if ( row->cols == NULL ) {
		return SQL_ERROR;
	}

	ber_bvarray_free_x( row->col_names, ctx );
	ber_memfree_x( row->col_prec, ctx );
	ber_memfree_x( row->col_type, ctx );
	ber_memvfree_x( (void **)row->cols, ctx );
	ber_memfree_x( row->value_len, ctx );

	return SQL_SUCCESS;
}
Example #3
0
void
anlist_free( AttributeName *an, int freename, void *ctx )
{
	if ( an == NULL ) {
		return;
	}

	if ( freename ) {
		int	i;

		for ( i = 0; an[i].an_name.bv_val; i++ ) {
			ber_memfree_x( an[i].an_name.bv_val, ctx );
		}
	}

	ber_memfree_x( an, ctx );
}
Example #4
0
static void scope_chunk_free( void *key, void *data )
{
	ID2 *p1, *p2;
	for (p1 = data; p1; p1 = p2) {
		p2 = p1[0].mval.mv_data;
		ber_memfree_x(p1, NULL);
	}
}
Example #5
0
void
slap_op_free( Operation *op, void *ctx )
{
    OperationBuffer *opbuf;

    assert( LDAP_STAILQ_NEXT(op, o_next) == NULL );

    if ( op->o_ber != NULL ) {
        ber_free( op->o_ber, 1 );
    }
    if ( !BER_BVISNULL( &op->o_dn ) ) {
        ch_free( op->o_dn.bv_val );
    }
    if ( !BER_BVISNULL( &op->o_ndn ) ) {
        ch_free( op->o_ndn.bv_val );
    }
    if ( !BER_BVISNULL( &op->o_authmech ) ) {
        ch_free( op->o_authmech.bv_val );
    }
    if ( op->o_ctrls != NULL ) {
        slap_free_ctrls( op, op->o_ctrls );
    }

#ifdef LDAP_CONNECTIONLESS
    if ( op->o_res_ber != NULL ) {
        ber_free( op->o_res_ber, 1 );
    }
#endif

    if ( op->o_groups ) {
        slap_op_groups_free( op );
    }

#if defined( LDAP_SLAPI )
    if ( slapi_plugins_used ) {
        slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op );
    }
#endif /* defined( LDAP_SLAPI ) */

    if ( !BER_BVISNULL( &op->o_csn ) ) {
        op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx );
        BER_BVZERO( &op->o_csn );
    }

    opbuf = (OperationBuffer *) op;
    memset( opbuf, 0, sizeof(*opbuf) );
    op->o_hdr = &opbuf->ob_hdr;
    op->o_controls = opbuf->ob_controls;

    if ( ctx ) {
        void *op2 = NULL;
        ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free,
                                     op, slap_op_q_destroy, &op2, NULL );
        LDAP_STAILQ_NEXT( op, o_next ) = op2;
    } else {
        ber_memfree_x( op, NULL );
    }
}
Example #6
0
void
ber_free_buf( BerElement *ber )
{
	Seqorset *s, *next;

	assert( LBER_VALID( ber ) );

	if ( ber->ber_buf) ber_memfree_x( ber->ber_buf, ber->ber_memctx );

	for( s = ber->ber_sos ; s != NULL ; s = next ) {
		next = s->sos_next;
		ber_memfree_x( s, ber->ber_memctx );
	}

	ber->ber_buf = NULL;
	ber->ber_sos = NULL;
	ber->ber_valid = LBER_UNINITIALIZED;
}
Example #7
0
static void
slap_op_q_destroy( void *key, void *data )
{
    Operation *op, *op2;
    for ( op = data; op; op = op2 ) {
        op2 = LDAP_STAILQ_NEXT( op, o_next );
        ber_memfree_x( op, NULL );
    }
}
Example #8
0
/* Destroy the context, or if key==NULL clean it up for reuse. */
void
slap_sl_mem_destroy(
	void *key,
	void *data
)
{
	struct slab_heap *sh = data;
	struct slab_object *so;
	int i;

	if (!sh->sh_stack) {
		for (i = 0; i <= sh->sh_maxorder - order_start; i++) {
			so = LDAP_LIST_FIRST(&sh->sh_free[i]);
			while (so) {
				struct slab_object *so_tmp = so;
				so = LDAP_LIST_NEXT(so, so_link);
				LDAP_LIST_INSERT_HEAD(&sh->sh_sopool, so_tmp, so_link);
			}
			ch_free(sh->sh_map[i]);
		}
		ch_free(sh->sh_free);
		ch_free(sh->sh_map);

		so = LDAP_LIST_FIRST(&sh->sh_sopool);
		while (so) {
			struct slab_object *so_tmp = so;
			so = LDAP_LIST_NEXT(so, so_link);
			if (!so_tmp->so_blockhead) {
				LDAP_LIST_REMOVE(so_tmp, so_link);
			}
		}
		so = LDAP_LIST_FIRST(&sh->sh_sopool);
		while (so) {
			struct slab_object *so_tmp = so;
			so = LDAP_LIST_NEXT(so, so_link);
			ch_free(so_tmp);
		}
	}

	if (key != NULL) {
		ber_memfree_x(sh->sh_base, NULL);
		ber_memfree_x(sh, NULL);
	}
}
Example #9
0
static int
retcode_op_internal( Operation *op, SlapReply *rs )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;

	Operation	op2 = *op;
	BackendDB	db = *op->o_bd;
	slap_callback	sc = { 0 };
	retcode_cb_t	rdc;

	int		rc;

	op2.o_tag = LDAP_REQ_SEARCH;
	op2.ors_scope = LDAP_SCOPE_BASE;
	op2.ors_deref = LDAP_DEREF_NEVER;
	op2.ors_tlimit = SLAP_NO_LIMIT;
	op2.ors_slimit = SLAP_NO_LIMIT;
	op2.ors_limit = NULL;
	op2.ors_attrsonly = 0;
	op2.ors_attrs = slap_anlist_all_attributes;

	ber_str2bv_x( "(objectClass=errAbsObject)",
		STRLENOF( "(objectClass=errAbsObject)" ),
		1, &op2.ors_filterstr, op2.o_tmpmemctx );
	op2.ors_filter = str2filter_x( &op2, op2.ors_filterstr.bv_val );

	/* errAbsObject is defined by this overlay! */
	assert( op2.ors_filter != NULL );

	db.bd_info = on->on_info->oi_orig;
	op2.o_bd = &db;

	rdc.rdc_info = on->on_info->oi_orig;
	rdc.rdc_flags = RETCODE_FINDIR;
	if ( op->o_tag == LDAP_REQ_SEARCH ) {
		rdc.rdc_attrs = op->ors_attrs;
	}
	rdc.rdc_tag = op->o_tag;
	sc.sc_response = retcode_cb_response;
	sc.sc_private = &rdc;
	op2.o_callback = &sc;

	rc = op2.o_bd->be_search( &op2, rs );
	op->o_abandon = op2.o_abandon;

	filter_free_x( &op2, op2.ors_filter, 1 );
	ber_memfree_x( op2.ors_filterstr.bv_val, op2.o_tmpmemctx );

	if ( rdc.rdc_flags == SLAP_CB_CONTINUE ) {
		return SLAP_CB_CONTINUE;
	}

	return rc;
}
Example #10
0
void
ber_free_buf( BerElement *ber )
{
	assert( LBER_VALID( ber ) );

	if ( ber->ber_buf) ber_memfree_x( ber->ber_buf, ber->ber_memctx );

	ber->ber_buf = NULL;
	ber->ber_sos_ptr = NULL;
	ber->ber_valid = LBER_UNINITIALIZED;
}
Example #11
0
static int
OpenLDAPaciNormalizeRights(
	struct berval	*actions,
	struct berval	*nactions,
	void		*ctx )

{
	struct berval	bv = BER_BVNULL;
	int		i;

	BER_BVZERO( nactions );
	for ( i = 0; acl_get_part( actions, i, '$', &bv ) >= 0; i++ ) {
		int		rc;
		struct berval	nbv;

		rc = OpenLDAPaciNormalizeRight( &bv, &nbv, ctx );
		if ( rc != LDAP_SUCCESS ) {
			ber_memfree_x( nactions->bv_val, ctx );
			BER_BVZERO( nactions );
			return LDAP_INVALID_SYNTAX;
		}

		if ( i == 0 ) {
			*nactions = nbv;

		} else {
			nactions->bv_val = ber_memrealloc_x( nactions->bv_val,
				nactions->bv_len + STRLENOF( "$" )
				+ nbv.bv_len + 1,
				ctx );
			nactions->bv_val[ nactions->bv_len ] = '$';
			memcpy( &nactions->bv_val[ nactions->bv_len + 1 ],
				nbv.bv_val, nbv.bv_len + 1 );
			ber_memfree_x( nbv.bv_val, ctx );
			nactions->bv_len += STRLENOF( "$" ) + nbv.bv_len;
		}
		BER_BVZERO( &nbv );
	}

	return LDAP_SUCCESS;
}
Example #12
0
void
ber_free( BerElement *ber, int freebuf )
{
	if( ber == NULL ) {
		LDAP_MEMORY_DEBUG_ASSERT( ber != NULL );
		return;
	}

	if( freebuf ) ber_free_buf( ber );

	ber_memfree_x( (char *) ber, ber->ber_memctx );
}
Example #13
0
void
ldap_ldif_record_done( LDIFRecord *lr )
{
	int i;

	/* the LDAPControl stuff does not allow the use of memory contexts */
	if (lr->lr_ctrls != NULL) {
		ldap_controls_free( lr->lr_ctrls );
	}
	if ( lr->lr_lm != NULL ) {
		ber_memfree_x( lr->lr_lm, lr->lr_ctx );
	}
	if ( lr->lr_mops != NULL ) {
		ber_memfree_x( lr->lr_mops, lr->lr_ctx );
	}
	for (i=lr->lr_lines-1; i>=0; i--)
		if ( lr->lr_freeval[i] ) ber_memfree_x( lr->lr_vals[i].bv_val, lr->lr_ctx );
	ber_memfree_x( lr->lr_btype, lr->lr_ctx );

	memset( lr, 0, sizeof(LDIFRecord) );
}
Example #14
0
static int
monitor_subsys_rww_destroy(
	BackendDB		*be,
	monitor_subsys_t	*ms )
{
	int		i;

	for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
		ber_memfree_x( monitor_rww[ i ].nrdn.bv_val, NULL );
	}

	return 0;
}
Example #15
0
/*
 * meta_clear_one_candidate
 *
 * clears the selected candidate
 */
int
meta_clear_one_candidate(
	Operation	*op,
	metaconn_t	*mc,
	int		candidate )
{
	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];

	if ( msc->msc_ld != NULL ) {

#ifdef DEBUG_205
		char	buf[ BUFSIZ ];

		snprintf( buf, sizeof( buf ), "meta_clear_one_candidate ldap_unbind_ext[%d] mc=%p ld=%p",
			candidate, (void *)mc, (void *)msc->msc_ld );
		Debug( LDAP_DEBUG_ANY, "### %s %s\n",
			op ? op->o_log_prefix : "", buf, 0 );
#endif /* DEBUG_205 */

		ldap_unbind_ext( msc->msc_ld, NULL, NULL );
		msc->msc_ld = NULL;
	}

	if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
		ber_memfree_x( msc->msc_bound_ndn.bv_val, NULL );
		BER_BVZERO( &msc->msc_bound_ndn );
	}

	if ( !BER_BVISNULL( &msc->msc_cred ) ) {
		memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
		ber_memfree_x( msc->msc_cred.bv_val, NULL );
		BER_BVZERO( &msc->msc_cred );
	}

	msc->msc_mscflags = 0;

	return 0;
}
Example #16
0
static int
OpenLDAPaciNormalizeRight(
	struct berval	*action,
	struct berval	*naction,
	void		*ctx )
{
	struct berval	grantdeny,
			perms = BER_BVNULL,
			bv = BER_BVNULL;
	int		idx,
			i;

	/* grant|deny */
	if ( acl_get_part( action, 0, ';', &grantdeny ) < 0 ) {
	        Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: missing ';' in '%s'\n", action->bv_val );
		return LDAP_INVALID_SYNTAX;
	}
	idx = bv_getcaseidx( &grantdeny, ACIgrantdeny );
	if ( idx == -1 ) {
	        Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: '%s' must be grant or deny\n", grantdeny.bv_val );
		return LDAP_INVALID_SYNTAX;
	}

	ber_dupbv_x( naction, (struct berval *)ACIgrantdeny[ idx ], ctx );

	for ( i = 1; acl_get_part( action, i, ';', &bv ) >= 0; i++ ) {
		struct berval	nattrs = BER_BVNULL;
		int		freenattrs = 1;
		if ( i & 1 ) {
			/* perms */
			if ( OpenLDAPaciValidatePerms( &bv ) != LDAP_SUCCESS )
			{
				return LDAP_INVALID_SYNTAX;
			}
			perms = bv;

		} else {
			/* attr */
			char		*ptr;

			/* could be "[all]" or an attribute description */
			if ( ber_bvstrcasecmp( &bv, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
				nattrs = aci_bv[ ACI_BV_BR_ALL ];
				freenattrs = 0;

			} else {
				AttributeDescription	*ad = NULL;
				AttributeDescription	adstatic= { 0 };
				const char		*text = NULL;
				struct berval		attr, left, right;
				int			j;
				int			len;

				for ( j = 0; acl_get_part( &bv, j, ',', &attr ) >= 0; j++ )
				{
					ad = NULL;
					text = NULL;
					/* openldap 2.1 aci compabitibility [entry] -> entry */
					if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ENTRY ] ) == 0 ) {
						ad = &adstatic;
						adstatic.ad_cname = aci_bv[ ACI_BV_ENTRY ];

					/* openldap 2.1 aci compabitibility [children] -> children */
					} else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_CHILDREN ] ) == 0 ) {
						ad = &adstatic;
						adstatic.ad_cname = aci_bv[ ACI_BV_CHILDREN ];

					/* openldap 2.1 aci compabitibility [all] -> only [all] */
					} else if ( ber_bvstrcasecmp( &attr, &aci_bv[ ACI_BV_BR_ALL ] ) == 0 ) {
						ber_memfree_x( nattrs.bv_val, ctx );
						nattrs = aci_bv[ ACI_BV_BR_ALL ];
						freenattrs = 0;
						break;

					} else if ( acl_get_part( &attr, 0, '=', &left ) < 0
				     		|| acl_get_part( &attr, 1, '=', &right ) < 0 )
					{
						if ( slap_bv2ad( &attr, &ad, &text ) != LDAP_SUCCESS )
						{
							ber_memfree_x( nattrs.bv_val, ctx );
							Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", attr.bv_val );
							return LDAP_INVALID_SYNTAX;
						}

					} else {
						if ( slap_bv2ad( &left, &ad, &text ) != LDAP_SUCCESS )
						{
							ber_memfree_x( nattrs.bv_val, ctx );
							Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: unknown attribute: '%s'\n", left.bv_val );
							return LDAP_INVALID_SYNTAX;
						}
					}


					len = nattrs.bv_len + ( !BER_BVISEMPTY( &nattrs ) ? STRLENOF( "," ) : 0 )
				      		+ ad->ad_cname.bv_len;
					nattrs.bv_val = ber_memrealloc_x( nattrs.bv_val, len + 1, ctx );
	                        	ptr = &nattrs.bv_val[ nattrs.bv_len ];
					if ( !BER_BVISEMPTY( &nattrs ) ) {
						*ptr++ = ',';
					}
					ptr = lutil_strncopy( ptr, ad->ad_cname.bv_val, ad->ad_cname.bv_len );
                                	ptr[ 0 ] = '\0';
                                	nattrs.bv_len = len;
				}

			}

			naction->bv_val = ber_memrealloc_x( naction->bv_val,
				naction->bv_len + STRLENOF( ";" )
				+ perms.bv_len + STRLENOF( ";" )
				+ nattrs.bv_len + 1,
				ctx );

			ptr = &naction->bv_val[ naction->bv_len ];
			ptr[ 0 ] = ';';
			ptr++;
			ptr = lutil_strncopy( ptr, perms.bv_val, perms.bv_len );
			ptr[ 0 ] = ';';
			ptr++;
			ptr = lutil_strncopy( ptr, nattrs.bv_val, nattrs.bv_len );
			ptr[ 0 ] = '\0';
			naction->bv_len += STRLENOF( ";" ) + perms.bv_len
				+ STRLENOF( ";" ) + nattrs.bv_len;
			if ( freenattrs ) {
				ber_memfree_x( nattrs.bv_val, ctx );
			}
		}
	}

	/* perms;attr go in pairs */
	if ( i > 1 && ( i & 1 ) ) {
		return LDAP_SUCCESS;

	} else {
		Debug( LDAP_DEBUG_ACL, "aciNormalizeRight: perms:attr need to be pairs in '%s'\n", action->bv_val );
		return LDAP_INVALID_SYNTAX;
	}
}
Example #17
0
static void search_stack_free( void *key, void *data )
{
	ber_memfree_x(data, NULL);
}
Example #18
0
int
asyncmeta_handle_search_msg(LDAPMessage *res, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	Operation *op = bc->op;
	SlapReply *rs;
	int	   i, rc = LDAP_SUCCESS, sres;
	SlapReply *candidates;
	char		**references = NULL;
	LDAPControl	**ctrls = NULL;
	a_dncookie dc;
	LDAPMessage *msg;
	ber_int_t id;

	rs = &bc->rs;
	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];
	dc.op = op;
	dc.target = mt;
	dc.to_from = MASSAGE_REP;
	id = ldap_msgid(res);


	candidates = bc->candidates;
	i = candidate;

	while (res && !META_BACK_CONN_INVALID(msc)) {
	for (msg = ldap_first_message(msc->msc_ldr, res); msg; msg = ldap_next_message(msc->msc_ldr, msg)) {
		switch(ldap_msgtype(msg)) {
		case LDAP_RES_SEARCH_ENTRY:
			Debug( LDAP_DEBUG_TRACE,
				"%s asyncmeta_handle_search_msg: msc %p entry\n",
				op->o_log_prefix, msc );
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			/* count entries returned by target */
			candidates[ i ].sr_nentries++;
			if (bc->c_peer_name.bv_val == op->o_conn->c_peer_name.bv_val && !op->o_abandon) {
				rs->sr_err = asyncmeta_send_entry( &bc->copy_op, rs, mc, i, msg );
			} else {
				goto err_cleanup;
			}
			switch ( rs->sr_err ) {
			case LDAP_SIZELIMIT_EXCEEDED:
				asyncmeta_send_ldap_result(bc, op, rs);
				rs->sr_err = LDAP_SUCCESS;
				goto err_cleanup;
			case LDAP_UNAVAILABLE:
				rs->sr_err = LDAP_OTHER;
				break;
			default:
				break;
			}
			bc->is_ok++;
			break;

		case LDAP_RES_SEARCH_REFERENCE:
			if ( META_BACK_TGT_NOREFS( mt ) ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;
			rc = ldap_parse_reference( msc->msc_ldr, msg,
				   &references, &rs->sr_ctrls, 0 );

			if ( rc != LDAP_SUCCESS || references == NULL ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			/* FIXME: merge all and return at the end */

			{
				int cnt;
				for ( cnt = 0; references[ cnt ]; cnt++ )
					;

				rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

				for ( cnt = 0; references[ cnt ]; cnt++ ) {
					ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ],
							  op->o_tmpmemctx );
				}
				BER_BVZERO( &rs->sr_ref[ cnt ] );
			}

			{
				dc.memctx = op->o_tmpmemctx;
				( void )asyncmeta_referral_result_rewrite( &dc, rs->sr_ref );
			}

			if ( rs->sr_ref != NULL ) {
				if (!BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
					/* ignore return value by now */
					( void )send_search_reference( op, rs );
				}

				ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx );
				rs->sr_ref = NULL;
			}

			/* cleanup */
			if ( references ) {
				ber_memvfree( (void **)references );
			}

			if ( rs->sr_ctrls ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_INTERMEDIATE:
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;

			/* FIXME: response controls
			 * are passed without checks */
			rs->sr_err = ldap_parse_intermediate( msc->msc_ldr,
								  msg,
								  (char **)&rs->sr_rspoid,
								  &rs->sr_rspdata,
								  &rs->sr_ctrls,
								  0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_type = REP_RESULT;
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			slap_send_ldap_intermediate( op, rs );

			if ( rs->sr_rspoid != NULL ) {
				ber_memfree( (char *)rs->sr_rspoid );
				rs->sr_rspoid = NULL;
			}

			if ( rs->sr_rspdata != NULL ) {
				ber_bvfree( rs->sr_rspdata );
				rs->sr_rspdata = NULL;
			}

			if ( rs->sr_ctrls != NULL ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_SEARCH_RESULT:
			if ( mi->mi_idle_timeout != 0 ) {
				asyncmeta_set_msc_time(msc);
			}
			Debug( LDAP_DEBUG_TRACE,
			       "%s asyncmeta_handle_search_msg: msc %p result\n",
			       op->o_log_prefix, msc );
			candidates[ i ].sr_type = REP_RESULT;
			candidates[ i ].sr_msgid = META_MSGID_IGNORE;
			/* NOTE: ignores response controls
			 * (and intermediate response controls
			 * as well, except for those with search
			 * references); this may not be correct,
			 * but if they're not ignored then
			 * back-meta would need to merge them
			 * consistently (think of pagedResults...)
			 */
			/* FIXME: response controls? */
			rs->sr_err = ldap_parse_result( msc->msc_ldr,
							msg,
							&candidates[ i ].sr_err,
								(char **)&candidates[ i ].sr_matched,
							(char **)&candidates[ i ].sr_text,
							&references,
							&ctrls /* &candidates[ i ].sr_ctrls (unused) */ ,
							0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_err = rs->sr_err;
				sres = slap_map_api2result( &candidates[ i ] );
				candidates[ i ].sr_type = REP_RESULT;
				goto finish;
			}

			rs->sr_err = candidates[ i ].sr_err;

			/* massage matchedDN if need be */
			if ( candidates[ i ].sr_matched != NULL ) {
				struct berval	match, mmatch;

				ber_str2bv( candidates[ i ].sr_matched,
						0, 0, &match );
				candidates[ i ].sr_matched = NULL;

				dc.memctx = NULL;
				asyncmeta_dn_massage( &dc, &match, &mmatch );
				if ( mmatch.bv_val == match.bv_val ) {
					candidates[ i ].sr_matched
						= ch_strdup( mmatch.bv_val );

				} else {
					candidates[ i ].sr_matched = mmatch.bv_val;
				}

				bc->candidate_match++;
				ldap_memfree( match.bv_val );
			}

			/* add references to array */
			/* RFC 4511: referrals can only appear
			 * if result code is LDAP_REFERRAL */
			if ( references != NULL
				 && references[ 0 ] != NULL
				 && references[ 0 ][ 0 ] != '\0' )
			{
				if ( rs->sr_err != LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						   "%s asncmeta_search_result[%d]: "
						   "got referrals with err=%d\n",
						   op->o_log_prefix,
						   i, rs->sr_err );

				} else {
					BerVarray	sr_ref;
					int		cnt;

					for ( cnt = 0; references[ cnt ]; cnt++ )
						;

					sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

					for ( cnt = 0; references[ cnt ]; cnt++ ) {
						ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ],
								  op->o_tmpmemctx );
					}
					BER_BVZERO( &sr_ref[ cnt ] );

					dc.memctx = op->o_tmpmemctx;
					( void )asyncmeta_referral_result_rewrite( &dc, sr_ref );

					if ( rs->sr_v2ref == NULL ) {
						rs->sr_v2ref = sr_ref;

					} else {
						for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
							ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ],
									   op->o_tmpmemctx );
						}
						ber_memfree_x( sr_ref, op->o_tmpmemctx );
					}
				}

			} else if ( rs->sr_err == LDAP_REFERRAL ) {
				Debug( LDAP_DEBUG_TRACE,
					   "%s asyncmeta_search_result[%d]: "
					   "got err=%d with null "
					   "or empty referrals\n",
					   op->o_log_prefix,
					   i, rs->sr_err );

				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}

			/* cleanup */
			ber_memvfree( (void **)references );

			sres = slap_map_api2result( rs );

			if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
				       (long) candidates[ i ].sr_err );
			} else {
					Debug( LDAP_DEBUG_ANY,  "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld (%s)",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
					       (long) candidates[ i ].sr_err, ldap_err2string( candidates[ i ].sr_err ) );
			}

			switch ( sres ) {
			case LDAP_NO_SUCH_OBJECT:
				/* is_ok is touched any time a valid
				 * (even intermediate) result is
				 * returned; as a consequence, if
				 * a candidate returns noSuchObject
				 * it is ignored and the candidate
				 * is simply demoted. */
				if ( bc->is_ok ) {
					sres = LDAP_SUCCESS;
				}
				break;

			case LDAP_SUCCESS:
				if ( ctrls != NULL && ctrls[0] != NULL ) {
#ifdef SLAPD_META_CLIENT_PR
					LDAPControl *pr_c;

					pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
					if ( pr_c != NULL ) {
						BerElementBuffer berbuf;
						BerElement *ber = (BerElement *)&berbuf;
						ber_tag_t tag;
						ber_int_t prsize;
						struct berval prcookie;

						/* unsolicited, do not accept */
						if ( mt->mt_ps == 0 ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER );

						tag = ber_scanf( ber, "{im}", &prsize, &prcookie );
						if ( tag == LBER_ERROR ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						/* more pages? new search request */
						if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) {
							if ( mt->mt_ps > 0 ) {
								/* ignore size if specified */
								prsize = 0;

							} else if ( prsize == 0 ) {
								/* guess the page size from the entries returned so far */
								prsize = candidates[ i ].sr_nentries;
							}

							candidates[ i ].sr_nentries = 0;
							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
							candidates[ i ].sr_type = REP_INTERMEDIATE;

							assert( candidates[ i ].sr_matched == NULL );
							assert( candidates[ i ].sr_text == NULL );
							assert( candidates[ i ].sr_ref == NULL );

							switch ( asyncmeta_back_search_start( &bc->copy_op, rs, mc, bc, i, &prcookie, prsize, 1 ) )
							{
							case META_SEARCH_CANDIDATE:
								assert( candidates[ i ].sr_msgid >= 0 );
								ldap_controls_free( ctrls );
								//	goto free_message;

							case META_SEARCH_ERR:
							case META_SEARCH_NEED_BIND:
err_pr:;
								candidates[ i ].sr_err = rs->sr_err;
								candidates[ i ].sr_type = REP_RESULT;
								if ( META_BACK_ONERR_STOP( mi ) ) {
									asyncmeta_send_ldap_result(bc, op, rs);
									ldap_controls_free( ctrls );
									goto err_cleanup;
								}
								/* fallthru */

							case META_SEARCH_NOT_CANDIDATE:
								/* means that asyncmeta_back_search_start()
								 * failed but onerr == continue */
								candidates[ i ].sr_msgid = META_MSGID_IGNORE;
								candidates[ i ].sr_type = REP_RESULT;
								break;

							default:
								/* impossible */
								assert( 0 );
								break;
							}
							break;
						}
					}
#endif /* SLAPD_META_CLIENT_PR */

					ldap_controls_free( ctrls );
				}
				/* fallthru */

			case LDAP_REFERRAL:
				bc->is_ok++;
				break;

			case LDAP_SIZELIMIT_EXCEEDED:
				/* if a target returned sizelimitExceeded
				 * and the entry count is equal to the
				 * proxy's limit, the target would have
				 * returned more, and the error must be
				 * propagated to the client; otherwise,
				 * the target enforced a limit lower
				 * than what requested by the proxy;
				 * ignore it */
				candidates[ i ].sr_err = rs->sr_err;
				if ( rs->sr_nentries == op->ors_slimit
					 || META_BACK_ONERR_STOP( mi ) )
				{
					const char *save_text;
got_err:
					save_text = rs->sr_text;
					rs->sr_text = candidates[ i ].sr_text;
					asyncmeta_send_ldap_result(bc, op, rs);
					if (candidates[ i ].sr_text != NULL) {
						ch_free( (char *)candidates[ i ].sr_text );
						candidates[ i ].sr_text = NULL;
					}
					rs->sr_text = save_text;
					ldap_controls_free( ctrls );
					goto err_cleanup;
				}
				break;

			default:
				candidates[ i ].sr_err = rs->sr_err;
				if ( META_BACK_ONERR_STOP( mi ) ) {
					goto got_err;
				}
				break;
			}
			/* if this is the last result we will ever receive, send it back  */
			rc = rs->sr_err;
			if (asyncmeta_is_last_result(mc, bc, i) == 0) {
				Debug( LDAP_DEBUG_TRACE,
					"%s asyncmeta_handle_search_msg: msc %p last result\n",
					op->o_log_prefix, msc );
				asyncmeta_search_last_result(mc, bc, i, sres);
err_cleanup:
				rc = rs->sr_err;
				ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
				asyncmeta_drop_bc( mc, bc);
				asyncmeta_clear_bm_context(bc);
				ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
				ldap_msgfree(res);
				return rc;
			}
finish:
			break;

		default:
			continue;
		}
	}
		ldap_msgfree(res);
		res = NULL;
		if (candidates[ i ].sr_type != REP_RESULT) {
			struct timeval	tv = {0};
			rc = ldap_result( msc->msc_ldr, id, LDAP_MSG_RECEIVED, &tv, &res );
			if (res != NULL) {
				msc->msc_result_time = slap_get_time();
			}
		}
	}
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	bc->bc_active--;
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	return rc;
}
Example #19
0
static int
deref_parseCtrl (
	Operation *op,
	SlapReply *rs,
	LDAPControl *ctrl )
{
	ber_tag_t tag;
	BerElementBuffer berbuf;
	BerElement *ber = (BerElement *)&berbuf;
	ber_len_t len;
	char *last;
	DerefSpec *dshead = NULL, **dsp = &dshead;
	BerVarray attributes = NULL;

	if ( op->o_deref != SLAP_CONTROL_NONE ) {
		rs->sr_text = "Dereference control specified multiple times";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dereference control value is absent";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dereference control value is empty";
		return LDAP_PROTOCOL_ERROR;
	}

	ber_init2( ber, &ctrl->ldctl_value, 0 );

	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
	{
		struct berval derefAttr;
		DerefSpec *ds, *dstmp;
		const char *text;
		int rc;
		ber_len_t cnt = sizeof(struct berval);
		ber_len_t off = 0;

		if ( ber_scanf( ber, "{m{M}}", &derefAttr, &attributes, &cnt, off ) == LBER_ERROR
			|| !cnt )
		{
			rs->sr_text = "Dereference control: derefSpec decoding error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		ds = (DerefSpec *)op->o_tmpcalloc( 1,
			sizeof(DerefSpec) + sizeof(AttributeDescription *)*(cnt + 1),
			op->o_tmpmemctx );
		ds->ds_attributes = (AttributeDescription **)&ds[ 1 ];
		ds->ds_nattrs = cnt;

		rc = slap_bv2ad( &derefAttr, &ds->ds_derefAttr, &text );
		if ( rc != LDAP_SUCCESS ) {
			rs->sr_text = "Dereference control: derefAttr decoding error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		for ( dstmp = dshead; dstmp && dstmp != ds; dstmp = dstmp->ds_next ) {
			if ( dstmp->ds_derefAttr == ds->ds_derefAttr ) {
				rs->sr_text = "Dereference control: derefAttr must be unique within control";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}
		}

		if ( !( ds->ds_derefAttr->ad_type->sat_syntax->ssyn_flags & SLAP_SYNTAX_DN )) {
			if ( ctrl->ldctl_iscritical ) {
				rs->sr_text = "Dereference control: derefAttr syntax not distinguishedName";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}

			rs->sr_err = LDAP_SUCCESS;
			goto justcleanup;
		}

		for ( cnt = 0; !BER_BVISNULL( &attributes[ cnt ] ); cnt++ ) {
			rc = slap_bv2ad( &attributes[ cnt ], &ds->ds_attributes[ cnt ], &text );
			if ( rc != LDAP_SUCCESS ) {
				rs->sr_text = "Dereference control: attribute decoding error";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}
		}

		ber_memfree_x( attributes, op->o_tmpmemctx );
		attributes = NULL;

		*dsp = ds;
		dsp = &ds->ds_next;
	}

	op->o_ctrlderef = (void *)dshead;

	op->o_deref = ctrl->ldctl_iscritical
		? SLAP_CONTROL_CRITICAL
		: SLAP_CONTROL_NONCRITICAL;

	rs->sr_err = LDAP_SUCCESS;

done:;
	if ( rs->sr_err != LDAP_SUCCESS ) {
justcleanup:;
		for ( ; dshead; ) {
			DerefSpec *dsnext = dshead->ds_next;
			op->o_tmpfree( dshead, op->o_tmpmemctx );
			dshead = dsnext;
		}
	}

	if ( attributes != NULL ) {
		ber_memfree_x( attributes, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Example #20
0
int
fe_op_modrdn( Operation *op, SlapReply *rs )
{
	struct berval	dest_ndn = BER_BVNULL, dest_pndn, pdn = BER_BVNULL;
	BackendDB	*op_be, *bd = op->o_bd;
	ber_slen_t	diff;
	
	if( op->o_req_ndn.bv_len == 0 ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: root dse!\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"cannot rename the root DSE" );
		goto cleanup;

	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: subschema subentry: %s (%ld)\n",
			op->o_log_prefix, frontendDB->be_schemandn.bv_val, (long)frontendDB->be_schemandn.bv_len );

		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"cannot rename subschema subentry" );
		goto cleanup;
	}

	if( op->orr_nnewSup ) {
		dest_pndn = *op->orr_nnewSup;
	} else {
		dnParent( &op->o_req_ndn, &dest_pndn );
	}
	build_new_dn( &dest_ndn, &dest_pndn, &op->orr_nnewrdn, op->o_tmpmemctx );

	diff = (ber_slen_t) dest_ndn.bv_len - (ber_slen_t) op->o_req_ndn.bv_len;
	if ( diff > 0 ? dnIsSuffix( &dest_ndn, &op->o_req_ndn )
		: diff < 0 && dnIsSuffix( &op->o_req_ndn, &dest_ndn ) )
	{
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			diff > 0 ? "cannot place an entry below itself"
			: "cannot place an entry above itself" );
		goto cleanup;
	}

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one, or send a referral to our "referral server"
	 * if we don't hold it.
	 */
	op->o_bd = select_backend( &op->o_req_ndn, 1 );
	if ( op->o_bd == NULL ) {
		op->o_bd = bd;
		rs->sr_ref = referral_rewrite( default_referral,
			NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
		if (!rs->sr_ref) rs->sr_ref = default_referral;

		if ( rs->sr_ref != NULL ) {
			rs->sr_err = LDAP_REFERRAL;
			send_ldap_result( op, rs );

			if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
		} else {
			send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
				"no global superior knowledge" );
		}
		goto cleanup;
	}

	/* If we've got a glued backend, check the real backend */
	op_be = op->o_bd;
	if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
		op->o_bd = select_backend( &op->o_req_ndn, 0 );
	}

	/* check restrictions */
	if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	/* check for referrals */
	if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) {
		goto cleanup;
	}

	/* check that destination DN is in the same backend as source DN */
	if ( select_backend( &dest_ndn, 0 ) != op->o_bd ) {
			send_ldap_error( op, rs, LDAP_AFFECTS_MULTIPLE_DSAS,
				"cannot rename between DSAs" );
			goto cleanup;
	}

	/*
	 * do the modrdn if 1 && (2 || 3)
	 * 1) there is a modrdn function implemented in this backend;
	 * 2) this backend is master for what it holds;
	 * 3) it's a replica and the dn supplied is the update_ndn.
	 */
	if ( op->o_bd->be_modrdn ) {
		/* do the update here */
		int repl_user = be_isupdate( op );
		if ( !SLAP_SINGLE_SHADOW(op->o_bd) || repl_user )
		{
			op->o_bd = op_be;
			op->o_bd->be_modrdn( op, rs );

			if ( op->o_bd->be_delete ) {
				struct berval	org_req_dn = BER_BVNULL;
				struct berval	org_req_ndn = BER_BVNULL;
				struct berval	org_dn = BER_BVNULL;
				struct berval	org_ndn = BER_BVNULL;
				int		org_managedsait;

				org_req_dn = op->o_req_dn;
				org_req_ndn = op->o_req_ndn;
				org_dn = op->o_dn;
				org_ndn = op->o_ndn;
				org_managedsait = get_manageDSAit( op );
				op->o_dn = op->o_bd->be_rootdn;
				op->o_ndn = op->o_bd->be_rootndn;
				op->o_managedsait = SLAP_CONTROL_NONCRITICAL;

				while ( rs->sr_err == LDAP_SUCCESS &&
						op->o_delete_glue_parent ) {
					op->o_delete_glue_parent = 0;
					if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
						slap_callback cb = { NULL };
						cb.sc_response = slap_null_cb;
						dnParent( &op->o_req_ndn, &pdn );
						op->o_req_dn = pdn;
						op->o_req_ndn = pdn;
						op->o_callback = &cb;
						op->o_bd->be_delete( op, rs );
					} else {
						break;
					}
				}
				op->o_managedsait = org_managedsait;
				op->o_dn = org_dn;
				op->o_ndn = org_ndn;
				op->o_req_dn = org_req_dn;
				op->o_req_ndn = org_req_ndn;
				op->o_delete_glue_parent = 0;
			}

		} else {
			BerVarray defref = op->o_bd->be_update_refs
				? op->o_bd->be_update_refs : default_referral;

			if ( defref != NULL ) {
				rs->sr_ref = referral_rewrite( defref,
					NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
				if (!rs->sr_ref) rs->sr_ref = defref;

				rs->sr_err = LDAP_REFERRAL;
				send_ldap_result( op, rs );

				if (rs->sr_ref != defref) ber_bvarray_free( rs->sr_ref );
			} else {
				send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
					"shadow context; no update referral" );
			}
		}
	} else {
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"operation not supported within namingContext" );
	}

cleanup:;
	if ( dest_ndn.bv_val != NULL )
		ber_memfree_x( dest_ndn.bv_val, op->o_tmpmemctx );
	op->o_bd = bd;
	return rs->sr_err;
}
Example #21
0
static int
asyncmeta_send_entry(
	Operation 	*op,
	SlapReply	*rs,
	a_metaconn_t	*mc,
	int 		target,
	LDAPMessage 	*e )
{
	a_metainfo_t 		*mi = mc->mc_info;
	struct berval		a, mapped = BER_BVNULL;
	int			check_sorted_attrs = 0;
	Entry 			ent = {0};
	BerElement 		ber = *ldap_get_message_ber( e );
	Attribute 		*attr, **attrp;
	struct berval 		bdn,
				dn = BER_BVNULL;
	const char 		*text;
	a_dncookie		dc;
	ber_len_t		len;
	int			rc;
	void	*mem_mark;

	mem_mark = slap_sl_mark( op->o_tmpmemctx );
	ber_set_option( &ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );

	if ( ber_scanf( &ber, "l{", &len ) == LBER_ERROR ) {
		return LDAP_DECODING_ERROR;
	}

	if ( ber_set_option( &ber, LBER_OPT_REMAINING_BYTES, &len ) != LBER_OPT_SUCCESS ) {
		return LDAP_OTHER;
	}

	if ( ber_scanf( &ber, "m{", &bdn ) == LBER_ERROR ) {
		return LDAP_DECODING_ERROR;
	}

	/*
	 * Rewrite the dn of the result, if needed
	 */
	dc.op = op;
	dc.target = mi->mi_targets[ target ];
	dc.memctx = op->o_tmpmemctx;
	dc.to_from = MASSAGE_REP;
	asyncmeta_dn_massage( &dc, &bdn, &dn );

	/*
	 * Note: this may fail if the target host(s) schema differs
	 * from the one known to the meta, and a DN with unknown
	 * attributes is returned.
	 *
	 * FIXME: should we log anything, or delegate to dnNormalize?
	 */
	rc = dnPrettyNormal( NULL, &dn, &ent.e_name, &ent.e_nname,
		op->o_tmpmemctx );
	if ( dn.bv_val != bdn.bv_val ) {
			op->o_tmpfree( dn.bv_val, op->o_tmpmemctx );
	}
	BER_BVZERO( &dn );

	if ( rc != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY,
			"%s asyncmeta_send_entry(\"%s\"): "
			"invalid DN syntax\n",
			op->o_log_prefix, ent.e_name.bv_val );
		rc = LDAP_INVALID_DN_SYNTAX;
		goto done;
	}

	/*
	 * cache dn
	 */
	if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED ) {
		( void )asyncmeta_dncache_update_entry( &mi->mi_cache,
				&ent.e_nname, target );
	}

	attrp = &ent.e_attrs;

	while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
		int				last = 0;
		slap_syntax_validate_func	*validate;
		slap_syntax_transform_func	*pretty;

		if ( ber_pvt_ber_remaining( &ber ) < 0 ) {
			Debug( LDAP_DEBUG_ANY,
				"%s asyncmeta_send_entry(\"%s\"): "
				"unable to parse attr \"%s\".\n",
				op->o_log_prefix, ent.e_name.bv_val, a.bv_val );

			rc = LDAP_OTHER;
			goto done;
		}

		if ( ber_pvt_ber_remaining( &ber ) == 0 ) {
			break;
		}

		attr = op->o_tmpcalloc( 1, sizeof(Attribute), op->o_tmpmemctx );
		if ( slap_bv2ad( &a, &attr->a_desc, &text )
				!= LDAP_SUCCESS) {
			if ( slap_bv2undef_ad( &a, &attr->a_desc, &text,
				SLAP_AD_PROXIED ) != LDAP_SUCCESS )
			{
				Debug(LDAP_DEBUG_ANY,
				      "%s meta_send_entry(\"%s\"): " "slap_bv2undef_ad(%s): %s\n",
				      op->o_log_prefix, ent.e_name.bv_val,
				      mapped.bv_val, text );
				( void )ber_scanf( &ber, "x" /* [W] */ );
				op->o_tmpfree( attr, op->o_tmpmemctx );
				continue;
			}
		}

		if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL )
			check_sorted_attrs = 1;

		/* no subschemaSubentry */
		if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry
			|| attr->a_desc == slap_schema.si_ad_entryDN )
		{

			/*
			 * We eat target's subschemaSubentry because
			 * a search for this value is likely not
			 * to resolve to the appropriate backend;
			 * later, the local subschemaSubentry is
			 * added.
			 *
			 * We also eat entryDN because the frontend
			 * will reattach it without checking if already
			 * present...
			 */
			( void )ber_scanf( &ber, "x" /* [W] */ );
			op->o_tmpfree( attr, op->o_tmpmemctx );
			continue;
		}

		if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
				|| attr->a_vals == NULL )
		{
			attr->a_vals = (struct berval *)&slap_dummy_bv;

		} else {
			for ( last = 0; !BER_BVISNULL( &attr->a_vals[ last ] ); ++last )
				;
		}
		attr->a_numvals = last;

		validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate;
		pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;

		if ( !validate && !pretty ) {
			ber_bvarray_free_x( attr->a_vals, op->o_tmpmemctx );
			op->o_tmpfree( attr, op->o_tmpmemctx );
			goto next_attr;
		}

		/*
		 * It is necessary to try to rewrite attributes with
		 * dn syntax because they might be used in ACLs as
		 * members of groups; since ACLs are applied to the
		 * rewritten stuff, no dn-based subecj clause could
		 * be used at the ldap backend side (see
		 * http://www.OpenLDAP.org/faq/data/cache/452.html)
		 * The problem can be overcome by moving the dn-based
		 * ACLs to the target directory server, and letting
		 * everything pass thru the ldap backend.
		 */
		{
			int	i;

			if ( attr->a_desc->ad_type->sat_syntax ==
				slap_schema.si_syn_distinguishedName )
			{
				asyncmeta_dnattr_result_rewrite( &dc, attr->a_vals );

			} else if ( attr->a_desc == slap_schema.si_ad_ref ) {
				asyncmeta_referral_result_rewrite( &dc, attr->a_vals );

			}

			for ( i = 0; i < last; i++ ) {
				struct berval	pval;
				int		rc;

				if ( pretty ) {
					rc = ordered_value_pretty( attr->a_desc,
						&attr->a_vals[i], &pval, op->o_tmpmemctx );

				} else {
					rc = ordered_value_validate( attr->a_desc,
						&attr->a_vals[i], 0 );
				}

				if ( rc ) {
					ber_memfree_x( attr->a_vals[i].bv_val, op->o_tmpmemctx );
					if ( --last == i ) {
						BER_BVZERO( &attr->a_vals[ i ] );
						break;
					}
					attr->a_vals[i] = attr->a_vals[last];
					BER_BVZERO( &attr->a_vals[last] );
					i--;
					continue;
				}

				if ( pretty ) {
					ber_memfree_x( attr->a_vals[i].bv_val, op->o_tmpmemctx );
					attr->a_vals[i] = pval;
				}
			}

			if ( last == 0 && attr->a_vals != &slap_dummy_bv ) {
				ber_bvarray_free_x( attr->a_vals, op->o_tmpmemctx );
				op->o_tmpfree( attr, op->o_tmpmemctx );
				goto next_attr;
			}
		}

		if ( last && attr->a_desc->ad_type->sat_equality &&
			attr->a_desc->ad_type->sat_equality->smr_normalize )
		{
			int i;

			attr->a_nvals = op->o_tmpalloc( ( last + 1 ) * sizeof( struct berval ), op->o_tmpmemctx );
			for ( i = 0; i<last; i++ ) {
				/* if normalizer fails, drop this value */
				if ( ordered_value_normalize(
					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
					attr->a_desc,
					attr->a_desc->ad_type->sat_equality,
					&attr->a_vals[i], &attr->a_nvals[i],
					op->o_tmpmemctx )) {
					ber_memfree_x( attr->a_vals[i].bv_val, op->o_tmpmemctx );
					if ( --last == i ) {
						BER_BVZERO( &attr->a_vals[ i ] );
						break;
					}
					attr->a_vals[i] = attr->a_vals[last];
					BER_BVZERO( &attr->a_vals[last] );
					i--;
				}
			}
			BER_BVZERO( &attr->a_nvals[i] );
			if ( last == 0 ) {
				ber_bvarray_free_x( attr->a_vals, op->o_tmpmemctx );
				ber_bvarray_free_x( attr->a_nvals, op->o_tmpmemctx );
				op->o_tmpfree( attr, op->o_tmpmemctx );
				goto next_attr;
			}

		} else {
			attr->a_nvals = attr->a_vals;
		}

		attr->a_numvals = last;
		*attrp = attr;
		attrp = &attr->a_next;
next_attr:;
	}

	/* Check for sorted attributes */
	if ( check_sorted_attrs ) {
		for ( attr = ent.e_attrs; attr; attr = attr->a_next ) {
			if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
				while ( attr->a_numvals > 1 ) {
					int i;
					int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx );
					if ( rc != LDAP_TYPE_OR_VALUE_EXISTS )
						break;

					/* Strip duplicate values */
					if ( attr->a_nvals != attr->a_vals )
						ber_memfree_x( attr->a_nvals[i].bv_val, op->o_tmpmemctx );
					ber_memfree_x( attr->a_vals[i].bv_val, op->o_tmpmemctx );
					attr->a_numvals--;
					if ( (unsigned)i < attr->a_numvals ) {
						attr->a_vals[i] = attr->a_vals[attr->a_numvals];
						if ( attr->a_nvals != attr->a_vals )
							attr->a_nvals[i] = attr->a_nvals[attr->a_numvals];
					}
					BER_BVZERO(&attr->a_vals[attr->a_numvals]);
					if ( attr->a_nvals != attr->a_vals )
						BER_BVZERO(&attr->a_nvals[attr->a_numvals]);
				}
				attr->a_flags |= SLAP_ATTR_SORTED_VALS;
			}
		}
	}
	Debug( LDAP_DEBUG_TRACE,
	       "%s asyncmeta_send_entry(\"%s\"): "
	       ".\n",
	       op->o_log_prefix, ent.e_name.bv_val );
	ldap_get_entry_controls( mc->mc_conns[target].msc_ldr,
		e, &rs->sr_ctrls );
	rs->sr_entry = &ent;
	rs->sr_attrs = op->ors_attrs;
	rs->sr_operational_attrs = NULL;
	rs->sr_flags = mi->mi_targets[ target ]->mt_rep_flags;
	rs->sr_err = LDAP_SUCCESS;
	rc = send_search_entry( op, rs );
	switch ( rc ) {
	case LDAP_UNAVAILABLE:
		rc = LDAP_OTHER;
		break;
	}

done:;
	if ( rs->sr_ctrls != NULL ) {
		ldap_controls_free( rs->sr_ctrls );
		rs->sr_ctrls = NULL;
	}
#if 0
	while ( ent.e_attrs ) {
		attr = ent.e_attrs;
		ent.e_attrs = attr->a_next;
		if ( attr->a_nvals != attr->a_vals )
			ber_bvarray_free_x( attr->a_nvals, op->o_tmpmemctx );
		ber_bvarray_free_x( attr->a_vals, op->o_tmpmemctx );
		op->o_tmpfree( attr, op->o_tmpmemctx );
	}
	if (ent.e_name.bv_val != NULL) {
		op->o_tmpfree( ent.e_name.bv_val, op->o_tmpmemctx );
	}

	if (ent.e_nname.bv_val != NULL) {
		op->o_tmpfree( ent.e_nname.bv_val, op->o_tmpmemctx );
	}
	if (rs->sr_entry && rs->sr_entry != &ent) {
		entry_free( rs->sr_entry );
	}
#endif
	slap_sl_release( mem_mark, op->o_tmpmemctx );
	rs->sr_entry = NULL;
	rs->sr_attrs = NULL;
	return rc;
}
Example #22
0
int
ldap_back_referral_result_rewrite(
	dncookie		*dc,
	BerVarray		a_vals,
	void			*memctx
)
{
	int		i, last;

	assert( dc != NULL );
	assert( a_vals != NULL );

	for ( last = 0; !BER_BVISNULL( &a_vals[ last ] ); last++ )
		;
	last--;

	for ( i = 0; !BER_BVISNULL( &a_vals[ i ] ); i++ ) {
		struct berval	dn,
				olddn = BER_BVNULL;
		int		rc;
		LDAPURLDesc	*ludp;

		rc = ldap_url_parse( a_vals[ i ].bv_val, &ludp );
		if ( rc != LDAP_URL_SUCCESS ) {
			/* leave attr untouched if massage failed */
			continue;
		}

		/* FIXME: URLs like "ldap:///dc=suffix" if passed
		 * thru ldap_url_parse() and ldap_url_desc2str()
		 * get rewritten as "ldap:///dc=suffix??base";
		 * we don't want this to occur... */
		if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
			ludp->lud_scope = LDAP_SCOPE_DEFAULT;
		}

		ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
		
		rc = ldap_back_dn_massage( dc, &olddn, &dn );
		switch ( rc ) {
		case LDAP_UNWILLING_TO_PERFORM:
			/*
			 * FIXME: need to check if it may be considered 
			 * legal to trim values when adding/modifying;
			 * it should be when searching (e.g. ACLs).
			 */
			ber_memfree( a_vals[ i ].bv_val );
			if ( last > i ) {
				a_vals[ i ] = a_vals[ last ];
			}
			BER_BVZERO( &a_vals[ last ] );
			last--;
			i--;
			break;

		default:
			/* leave attr untouched if massage failed */
			if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val )
			{
				char	*newurl;

				ludp->lud_dn = dn.bv_val;
				newurl = ldap_url_desc2str( ludp );
				free( dn.bv_val );
				if ( newurl == NULL ) {
					/* FIXME: leave attr untouched
					 * even if ldap_url_desc2str failed...
					 */
					break;
				}

				ber_memfree_x( a_vals[ i ].bv_val, memctx );
				ber_str2bv_x( newurl, 0, 1, &a_vals[ i ], memctx );
				ber_memfree( newurl );
				ludp->lud_dn = olddn.bv_val;
			}
			break;
		}

		ldap_free_urldesc( ludp );
	}

	return 0;
}
Example #23
0
/*
 * Do basic attribute type checking and syntax validation.
 */
int slap_mods_check(
	Operation *op,
	Modifications *ml,
	const char **text,
	char *textbuf,
	size_t textlen,
	void *ctx )
{
	int rc;

	for( ; ml != NULL; ml = ml->sml_next ) {
		AttributeDescription *ad = NULL;

		/* convert to attribute description */
		if ( ml->sml_desc == NULL ) {
			rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, text );
			if( rc != LDAP_SUCCESS ) {
				if ( get_no_schema_check( op )) {
					rc = slap_bv2undef_ad( &ml->sml_type, &ml->sml_desc,
						text, 0 );
				}
			}
			if( rc != LDAP_SUCCESS ) {
				snprintf( textbuf, textlen, "%s: %s",
					ml->sml_type.bv_val, *text );
				*text = textbuf;
				return rc;
			}
		}

		ad = ml->sml_desc;

		if( slap_syntax_is_binary( ad->ad_type->sat_syntax )
			&& !slap_ad_is_binary( ad ))
		{
			/* attribute requires binary transfer */
			snprintf( textbuf, textlen,
				"%s: requires ;binary transfer",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

		if( !slap_syntax_is_binary( ad->ad_type->sat_syntax )
			&& slap_ad_is_binary( ad ))
		{
			/* attribute does not require binary transfer */
			snprintf( textbuf, textlen,
				"%s: disallows ;binary transfer",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

		if( slap_ad_is_tag_range( ad )) {
			/* attribute requires binary transfer */
			snprintf( textbuf, textlen,
				"%s: inappropriate use of tag range option",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

#if 0
		if ( is_at_obsolete( ad->ad_type ) &&
			(( ml->sml_op != LDAP_MOD_REPLACE &&
				ml->sml_op != LDAP_MOD_DELETE ) ||
					ml->sml_values != NULL ))
		{
			/*
			 * attribute is obsolete,
			 * only allow replace/delete with no values
			 */
			snprintf( textbuf, textlen,
				"%s: attribute is obsolete",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_CONSTRAINT_VIOLATION;
		}
#endif

		if ( ml->sml_op == LDAP_MOD_INCREMENT &&
#ifdef SLAPD_REAL_SYNTAX
			!is_at_syntax( ad->ad_type, SLAPD_REAL_SYNTAX ) &&
#endif
			!is_at_syntax( ad->ad_type, SLAPD_INTEGER_SYNTAX ) )
		{
			/*
			 * attribute values must be INTEGER or REAL
			 */
			snprintf( textbuf, textlen,
				"%s: attribute syntax inappropriate for increment",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_CONSTRAINT_VIOLATION;
		}

		/*
		 * check values
		 */
		if( ml->sml_values != NULL ) {
			ber_len_t nvals;
			slap_syntax_validate_func *validate =
				ad->ad_type->sat_syntax->ssyn_validate;
			slap_syntax_transform_func *pretty =
				ad->ad_type->sat_syntax->ssyn_pretty;
 
			if( !pretty && !validate ) {
				*text = "no validator for syntax";
				snprintf( textbuf, textlen,
					"%s: no validator for syntax %s",
					ml->sml_type.bv_val,
					ad->ad_type->sat_syntax->ssyn_oid );
				*text = textbuf;
				return LDAP_INVALID_SYNTAX;
			}

			/*
			 * check that each value is valid per syntax
			 *	and pretty if appropriate
			 */
			for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
				struct berval pval;

				if ( pretty ) {
					rc = ordered_value_pretty( ad,
						&ml->sml_values[nvals], &pval, ctx );
				} else {
					rc = ordered_value_validate( ad,
						&ml->sml_values[nvals], ml->sml_op );
				}

				if( rc != 0 ) {
					snprintf( textbuf, textlen,
						"%s: value #%ld invalid per syntax",
						ml->sml_type.bv_val, (long) nvals );
					*text = textbuf;
					return LDAP_INVALID_SYNTAX;
				}

				if( pretty ) {
					ber_memfree_x( ml->sml_values[nvals].bv_val, ctx );
					ml->sml_values[nvals] = pval;
				}
			}
			ml->sml_values[nvals].bv_len = 0;
			ml->sml_numvals = nvals;

			/*
			 * a rough single value check... an additional check is needed
			 * to catch add of single value to existing single valued attribute
			 */
			if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
				&& nvals > 1 && is_at_single_value( ad->ad_type ))
			{
				snprintf( textbuf, textlen,
					"%s: multiple values provided",
					ml->sml_type.bv_val );
				*text = textbuf;
				return LDAP_CONSTRAINT_VIOLATION;
			}

			/* if the type has a normalizer, generate the
			 * normalized values. otherwise leave them NULL.
			 *
			 * this is different from the rule for attributes
			 * in an entry - in an attribute list, the normalized
			 * value is set equal to the non-normalized value
			 * when there is no normalizer.
			 */
			if( nvals && ad->ad_type->sat_equality &&
				ad->ad_type->sat_equality->smr_normalize )
			{
				ml->sml_nvalues = ber_memalloc_x(
					(nvals+1)*sizeof(struct berval), ctx );

				for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
					rc = ordered_value_normalize(
						SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
						ad,
						ad->ad_type->sat_equality,
						&ml->sml_values[nvals], &ml->sml_nvalues[nvals], ctx );
					if ( rc ) {
						Debug( LDAP_DEBUG_ANY,
							"<= str2entry NULL (ssyn_normalize %d)\n",
							rc, 0, 0 );
						snprintf( textbuf, textlen,
							"%s: value #%ld normalization failed",
							ml->sml_type.bv_val, (long) nvals );
						*text = textbuf;
						BER_BVZERO( &ml->sml_nvalues[nvals] );
						return rc;
					}
				}

				BER_BVZERO( &ml->sml_nvalues[nvals] );
			}

			/* check for duplicates, but ignore Deletes.
			 */
			if( nvals > 1 && ml->sml_op != LDAP_MOD_DELETE ) {
				int i;
				rc = slap_sort_vals( ml, text, &i, ctx );
				if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
					/* value exists already */
					snprintf( textbuf, textlen,
						"%s: value #%d provided more than once",
						ml->sml_desc->ad_cname.bv_val, i );
					*text = textbuf;
				}
				if ( rc )
					return rc;
			}
		} else {
			ml->sml_numvals = 0;
		}
	}

	return LDAP_SUCCESS;
}
Example #24
0
RETCODE
backsql_BindRowAsStrings_x( SQLHSTMT sth, BACKSQL_ROW_NTS *row, void *ctx )
{
	RETCODE		rc;

	if ( row == NULL ) {
		return SQL_ERROR;
	}

#ifdef BACKSQL_TRACE
	Debug( LDAP_DEBUG_TRACE, "==> backsql_BindRowAsStrings()\n", 0, 0, 0 );
#endif /* BACKSQL_TRACE */
	
	rc = SQLNumResultCols( sth, &row->ncols );
	if ( rc != SQL_SUCCESS ) {
#ifdef BACKSQL_TRACE
		Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings(): "
			"SQLNumResultCols() failed:\n", 0, 0, 0 );
#endif /* BACKSQL_TRACE */
		
		backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );

	} else {
		SQLCHAR		colname[ 64 ];
		SQLSMALLINT	name_len, col_type, col_scale, col_null;
		UDWORD		col_prec;
		int		i;

#ifdef BACKSQL_TRACE
		Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
			"ncols=%d\n", (int)row->ncols, 0, 0 );
#endif /* BACKSQL_TRACE */

		row->col_names = (BerVarray)ber_memcalloc_x( row->ncols + 1, 
				sizeof( struct berval ), ctx );
		if ( row->col_names == NULL ) {
			goto nomem;
		}

		row->col_prec = (UDWORD *)ber_memcalloc_x( row->ncols,
				sizeof( UDWORD ), ctx );
		if ( row->col_prec == NULL ) {
			goto nomem;
		}

		row->col_type = (SQLSMALLINT *)ber_memcalloc_x( row->ncols,
				sizeof( SQLSMALLINT ), ctx );
		if ( row->col_type == NULL ) {
			goto nomem;
		}

		row->cols = (char **)ber_memcalloc_x( row->ncols + 1, 
				sizeof( char * ), ctx );
		if ( row->cols == NULL ) {
			goto nomem;
		}

		row->value_len = (SQLINTEGER *)ber_memcalloc_x( row->ncols,
				sizeof( SQLINTEGER ), ctx );
		if ( row->value_len == NULL ) {
			goto nomem;
		}

		if ( 0 ) {
nomem:
			ber_memfree_x( row->col_names, ctx );
			row->col_names = NULL;
			ber_memfree_x( row->col_prec, ctx );
			row->col_prec = NULL;
			ber_memfree_x( row->col_type, ctx );
			row->col_type = NULL;
			ber_memfree_x( row->cols, ctx );
			row->cols = NULL;
			ber_memfree_x( row->value_len, ctx );
			row->value_len = NULL;

			Debug( LDAP_DEBUG_ANY, "backsql_BindRowAsStrings: "
				"out of memory\n", 0, 0, 0 );

			return LDAP_NO_MEMORY;
		}

		for ( i = 0; i < row->ncols; i++ ) {
			SQLSMALLINT	TargetType;

			rc = SQLDescribeCol( sth, (SQLSMALLINT)(i + 1), &colname[ 0 ],
					(SQLUINTEGER)( sizeof( colname ) - 1 ),
					&name_len, &col_type,
					&col_prec, &col_scale, &col_null );
			/* FIXME: test rc? */

			ber_str2bv_x( (char *)colname, 0, 1,
					&row->col_names[ i ], ctx );
#ifdef BACKSQL_TRACE
			Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
				"col_name=%s, col_prec[%d]=%d\n",
				colname, (int)(i + 1), (int)col_prec );
#endif /* BACKSQL_TRACE */
			if ( col_type != SQL_CHAR && col_type != SQL_VARCHAR )
			{
				col_prec = MAX_ATTR_LEN;
			}

			row->cols[ i ] = (char *)ber_memcalloc_x( col_prec + 1,
					sizeof( char ), ctx );
			row->col_prec[ i ] = col_prec;
			row->col_type[ i ] = col_type;

			/*
			 * ITS#3386, ITS#3113 - 20070308
			 * Note: there are many differences between various DPMS and ODBC
			 * Systems; some support SQL_C_BLOB, SQL_C_BLOB_LOCATOR.  YMMV:
			 * This has only been tested on Linux/MySQL/UnixODBC
			 * For BINARY-type Fields (BLOB, etc), read the data as BINARY
			 */
			if ( BACKSQL_IS_BINARY( col_type ) ) {
#ifdef BACKSQL_TRACE
				Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
					"col_name=%s, col_type[%d]=%d: reading binary data\n",
					colname, (int)(i + 1), (int)col_type);
#endif /* BACKSQL_TRACE */
				TargetType = SQL_C_BINARY;

			} else {
				/* Otherwise read it as Character data */
#ifdef BACKSQL_TRACE
				Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
					"col_name=%s, col_type[%d]=%d: reading character data\n",
					colname, (int)(i + 1), (int)col_type);
#endif /* BACKSQL_TRACE */
				TargetType = SQL_C_CHAR;
			}

			rc = SQLBindCol( sth, (SQLUSMALLINT)(i + 1),
				 TargetType,
				 (SQLPOINTER)row->cols[ i ],
				 col_prec + 1,
				 &row->value_len[ i ] );

			/* FIXME: test rc? */
		}

		BER_BVZERO( &row->col_names[ i ] );
		row->cols[ i ] = NULL;
	}

#ifdef BACKSQL_TRACE
	Debug( LDAP_DEBUG_TRACE, "<== backsql_BindRowAsStrings()\n", 0, 0, 0 );
#endif /* BACKSQL_TRACE */

	return rc;
}
Example #25
0
/*
 * Combination of both dnPretty and dnNormalize
 */
int
dnPrettyNormal(
	Syntax *syntax,
	struct berval *val,
	struct berval *pretty,
	struct berval *normal,
	void *ctx)
{
	assert( val != NULL );
	assert( pretty != NULL );
	assert( normal != NULL );
	Debug( LDAP_DEBUG_TRACE, ">>> dnPrettyNormal: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 );

	if ( val->bv_len == 0 ) {
		ber_dupbv_x( pretty, val, ctx );
		ber_dupbv_x( normal, val, ctx );

	} else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) {
		/* too big */
		return LDAP_INVALID_SYNTAX;

	} else {
		LDAPDN		dn = NULL;
		int		rc;

		pretty->bv_val = NULL;
		normal->bv_val = NULL;
		pretty->bv_len = 0;
		normal->bv_len = 0;

		/* FIXME: should be liberal in what we accept */
		rc = ldap_bv2dn_x( val, &dn, LDAP_DN_FORMAT_LDAP, ctx );
		if ( rc != LDAP_SUCCESS ) {
			return LDAP_INVALID_SYNTAX;
		}

		assert( strlen( val->bv_val ) == val->bv_len );

		/*
		 * Schema-aware rewrite
		 */
		if ( LDAPDN_rewrite( dn, SLAP_LDAPDN_PRETTY, ctx ) != LDAP_SUCCESS ) {
			ldap_dnfree_x( dn, ctx );
			return LDAP_INVALID_SYNTAX;
		}

		rc = ldap_dn2bv_x( dn, pretty,
			LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY, ctx );

		if ( rc != LDAP_SUCCESS ) {
			ldap_dnfree_x( dn, ctx );
			return LDAP_INVALID_SYNTAX;
		}

		if ( LDAPDN_rewrite( dn, 0, ctx ) != LDAP_SUCCESS ) {
			ldap_dnfree_x( dn, ctx );
			ber_memfree_x( pretty->bv_val, ctx );
			pretty->bv_val = NULL;
			pretty->bv_len = 0;
			return LDAP_INVALID_SYNTAX;
		}

		rc = ldap_dn2bv_x( dn, normal,
			LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY, ctx );

		ldap_dnfree_x( dn, ctx );
		if ( rc != LDAP_SUCCESS ) {
			ber_memfree_x( pretty->bv_val, ctx );
			pretty->bv_val = NULL;
			pretty->bv_len = 0;
			return LDAP_INVALID_SYNTAX;
		}
	}

	Debug( LDAP_DEBUG_TRACE, "<<< dnPrettyNormal: <%s>, <%s>\n",
		pretty->bv_val ? pretty->bv_val : "",
		normal->bv_val ? normal->bv_val : "", 0 );

	return LDAP_SUCCESS;
}
Example #26
0
int
meta_back_db_destroy(
	Backend		*be,
	ConfigReply	*cr )
{
	metainfo_t	*mi;

	if ( be->be_private ) {
		int i;

		mi = ( metainfo_t * )be->be_private;

		/*
		 * Destroy the connection tree
		 */
		ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );

		if ( mi->mi_conninfo.lai_tree ) {
			avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free );
		}
		for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
			while ( !LDAP_TAILQ_EMPTY( &mi->mi_conn_priv[ i ].mic_priv ) ) {
				metaconn_t	*mc = LDAP_TAILQ_FIRST( &mi->mi_conn_priv[ i ].mic_priv );

				LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ i ].mic_priv, mc, mc_q );
				meta_back_conn_free( mc );
			}
		}

		/*
		 * Destroy the per-target stuff (assuming there's at
		 * least one ...)
		 */
		if ( mi->mi_targets != NULL ) {
			for ( i = 0; i < mi->mi_ntargets; i++ ) {
				metatarget_t	*mt = mi->mi_targets[ i ];

				if ( META_BACK_TGT_QUARANTINE( mt ) ) {
					if ( mt->mt_quarantine.ri_num != mi->mi_quarantine.ri_num )
					{
						mi->mi_ldap_extra->retry_info_destroy( &mt->mt_quarantine );
					}

					ldap_pvt_thread_mutex_destroy( &mt->mt_quarantine_mutex );
				}

				target_free( mt );
			}

			free( mi->mi_targets );
		}

		ldap_pvt_thread_mutex_lock( &mi->mi_cache.mutex );
		if ( mi->mi_cache.tree ) {
			avl_free( mi->mi_cache.tree, meta_dncache_free );
		}
		
		ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex );
		ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex );

		ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
		ldap_pvt_thread_mutex_destroy( &mi->mi_conninfo.lai_mutex );

		if ( mi->mi_candidates != NULL ) {
			ber_memfree_x( mi->mi_candidates, NULL );
		}

		if ( META_BACK_QUARANTINE( mi ) ) {
			mi->mi_ldap_extra->retry_info_destroy( &mi->mi_quarantine );
		}
	}

	free( be->be_private );
	return 0;
}
Example #27
0
static int
map_attr_value(
	dncookie		*dc,
	AttributeDescription 	**adp,
	struct berval		*mapped_attr,
	struct berval		*value,
	struct berval		*mapped_value,
	int			remap,
	void			*memctx )
{
	struct berval		vtmp = BER_BVNULL;
	int			freeval = 0;
	AttributeDescription	*ad = *adp;
	struct ldapmapping	*mapping = NULL;

	rwm_mapping( &dc->rwmap->rwm_at, &ad->ad_cname, &mapping, remap );
	if ( mapping == NULL ) {
		if ( dc->rwmap->rwm_at.drop_missing ) {
			return -1;
		}

		*mapped_attr = ad->ad_cname;

	} else {
		*mapped_attr = mapping->m_dst;
	}

	if ( value != NULL ) {
		assert( mapped_value != NULL );

		if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName
				|| ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
		{
			dncookie 	fdc = *dc;
			int		rc;

			fdc.ctx = "searchFilterAttrDN";

			vtmp = *value;
			rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
			switch ( rc ) {
			case LDAP_SUCCESS:
				if ( vtmp.bv_val != value->bv_val ) {
					freeval = 1;
				}
				break;
		
			case LDAP_UNWILLING_TO_PERFORM:
			case LDAP_OTHER:
			default:
				return -1;
			}

		} else if ( ad->ad_type->sat_equality &&
			( ad->ad_type->sat_equality->smr_usage & SLAP_MR_MUTATION_NORMALIZER ) )
		{
			if ( ad->ad_type->sat_equality->smr_normalize(
				(SLAP_MR_DENORMALIZE|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX),
				NULL, NULL, value, &vtmp, memctx ) )
			{
				return -1;
			}
			freeval = 2;

		} else if ( ad == slap_schema.si_ad_objectClass
				|| ad == slap_schema.si_ad_structuralObjectClass )
		{
			rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
			if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
				vtmp = *value;
			}
		
		} else {
			vtmp = *value;
		}

		filter_escape_value_x( &vtmp, mapped_value, memctx );

		switch ( freeval ) {
		case 1:
			ch_free( vtmp.bv_val );
			break;

		case 2:
			ber_memfree_x( vtmp.bv_val, memctx );
			break;
		}
	}
	
	if ( mapping != NULL ) {
		assert( mapping->m_dst_ad != NULL );
		*adp = mapping->m_dst_ad;
	}

	return 0;
}
Example #28
0
static int
dupent_parseCtrl (
	Operation *op,
	SlapReply *rs,
	LDAPControl *ctrl )
{
	ber_tag_t tag;
	BerElementBuffer berbuf;
	BerElement *ber = (BerElement *)&berbuf;
	ber_len_t len;
	BerVarray AttributeDescriptionList = NULL;
	ber_len_t cnt = sizeof(struct berval);
	ber_len_t off = 0;
	ber_int_t PartialApplicationAllowed = 1;
	dupent_t *ds = NULL;
	int i;

	if ( op->o_dupent != SLAP_CONTROL_NONE ) {
		rs->sr_text = "Dupent control specified multiple times";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dupent control value is absent";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dupent control value is empty";
		return LDAP_PROTOCOL_ERROR;
	}

	ber_init2( ber, &ctrl->ldctl_value, 0 );

	/*

   DuplicateEntryRequest ::= SEQUENCE { 
        AttributeDescriptionList, -- from [RFC2251] 
        PartialApplicationAllowed BOOLEAN DEFAULT TRUE } 

        AttributeDescriptionList ::= SEQUENCE OF 
                AttributeDescription 
    
        AttributeDescription ::= LDAPString 
    
        attributeDescription = AttributeType [ ";" <options> ] 

	 */

	tag = ber_skip_tag( ber, &len );
	if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
	if ( ber_scanf( ber, "{M}", &AttributeDescriptionList, &cnt, off )
		== LBER_ERROR )
	{
		rs->sr_text = "Dupent control: dupentSpec decoding error";
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}
	tag = ber_skip_tag( ber, &len );
	if ( tag == LBER_BOOLEAN ) {
		/* NOTE: PartialApplicationAllowed is ignored, since the control
		 * can always be honored
		 */
		if ( ber_scanf( ber, "b", &PartialApplicationAllowed ) == LBER_ERROR )
		{
			rs->sr_text = "Dupent control: dupentSpec decoding error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}
		tag = ber_skip_tag( ber, &len );
	}
	if ( len || tag != LBER_DEFAULT ) {
		rs->sr_text = "Dupent control: dupentSpec decoding error";
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	ds = (dupent_t *)op->o_tmpcalloc( 1,
		sizeof(dupent_t) + sizeof(AttributeName)*cnt,
		op->o_tmpmemctx );

	ds->ds_paa = PartialApplicationAllowed;

	if ( cnt == 0 ) {
		ds->ds_flags |= SLAP_USERATTRS_YES;

	} else {
		int c;

		ds->ds_an = (AttributeName *)&ds[ 1 ];

		for ( i = 0, c = 0; i < cnt; i++ ) {
			const char *text;
			int j;
			int rc;
			AttributeDescription *ad = NULL;

			if ( bvmatch( &AttributeDescriptionList[i],
				slap_bv_all_user_attrs ) )
			{
				if ( ds->ds_flags & SLAP_USERATTRS_YES ) {
					rs->sr_text = "Dupent control: AttributeDescription decoding error";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}

				ds->ds_flags |= SLAP_USERATTRS_YES;
				continue;
			}

			rc = slap_bv2ad( &AttributeDescriptionList[i], &ad, &text );
			if ( rc != LDAP_SUCCESS ) {
				continue;
			}

			ds->ds_an[c].an_desc = ad;
			ds->ds_an[c].an_name = ad->ad_cname;

			/* FIXME: not specified; consider this an error, just in case */
			for ( j = 0; j < c; j++ ) {
				if ( ds->ds_an[c].an_desc == ds->ds_an[j].an_desc ) {
					rs->sr_text = "Dupent control: AttributeDescription must be unique within AttributeDescriptionList";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}
			}

			c++;
		}

		ds->ds_nattrs = c;

		if ( ds->ds_flags & SLAP_USERATTRS_YES ) {
			/* purge user attrs */
			for ( i = 0; i < ds->ds_nattrs;  ) {
				if ( is_at_operational( ds->ds_an[i].an_desc->ad_type ) ) {
					i++;
					continue;
				}

				ds->ds_nattrs--;
				if ( i < ds->ds_nattrs ) {
					ds->ds_an[i] = ds->ds_an[ds->ds_nattrs];
				}
			}
		}
	}

	op->o_ctrldupent = (void *)ds;

	op->o_dupent = ctrl->ldctl_iscritical
		? SLAP_CONTROL_CRITICAL
		: SLAP_CONTROL_NONCRITICAL;

	rs->sr_err = LDAP_SUCCESS;

done:;
	if ( rs->sr_err != LDAP_SUCCESS ) {
		op->o_tmpfree( ds, op->o_tmpmemctx );
	}

	if ( AttributeDescriptionList != NULL ) {
		ber_memfree_x( AttributeDescriptionList, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Example #29
0
static int
OpenLDAPaciPrettyNormal(
	struct berval	*val,
	struct berval	*out,
	void		*ctx,
	int		normalize )
{
	struct berval	oid = BER_BVNULL,
			scope = BER_BVNULL,
			rights = BER_BVNULL,
			nrights = BER_BVNULL,
			type = BER_BVNULL,
			ntype = BER_BVNULL,
			subject = BER_BVNULL,
			nsubject = BER_BVNULL;
	int		idx,
			rc = LDAP_SUCCESS,
			freesubject = 0,
			freetype = 0;
	char		*ptr;

	BER_BVZERO( out );

	if ( BER_BVISEMPTY( val ) ) {
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: value is empty\n" );
		return LDAP_INVALID_SYNTAX;
	}

	/* oid: if valid, it's already normalized */
	if ( acl_get_part( val, 0, '#', &oid ) < 0 ||
		numericoidValidate( NULL, &oid ) != LDAP_SUCCESS )
	{
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid oid '%s'\n", oid.bv_val );
		return LDAP_INVALID_SYNTAX;
	}

	/* scope: normalize by replacing with OpenLDAPaciscopes */
	if ( acl_get_part( val, 1, '#', &scope ) < 0 ) {
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing scope in '%s'\n", val->bv_val );
		return LDAP_INVALID_SYNTAX;
	}
	idx = bv_getcaseidx( &scope, OpenLDAPaciscopes );
	if ( idx == -1 ) {
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid scope '%s'\n", scope.bv_val );
		return LDAP_INVALID_SYNTAX;
	}
	scope = *OpenLDAPaciscopes[ idx ];

	/* rights */
	if ( acl_get_part( val, 2, '#', &rights ) < 0 ) {
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing rights in '%s'\n", val->bv_val );
		return LDAP_INVALID_SYNTAX;
	}
	if ( OpenLDAPaciNormalizeRights( &rights, &nrights, ctx )
		!= LDAP_SUCCESS )
	{
		return LDAP_INVALID_SYNTAX;
	}

	/* type */
	if ( acl_get_part( val, 3, '#', &type ) < 0 ) {
		Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing type in '%s'\n", val->bv_val );
		rc = LDAP_INVALID_SYNTAX;
		goto cleanup;
	}
	idx = bv_getcaseidx( &type, OpenLDAPacitypes );
	if ( idx == -1 ) {
		struct berval	isgr;

		if ( acl_get_part( &type, 0, '/', &isgr ) < 0 ) {
		        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", type.bv_val );
			rc = LDAP_INVALID_SYNTAX;
			goto cleanup;
		}

		idx = bv_getcaseidx( &isgr, OpenLDAPacitypes );
		if ( idx == -1 || idx >= LAST_OPTIONAL ) {
		        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid type '%s'\n", isgr.bv_val );
			rc = LDAP_INVALID_SYNTAX;
			goto cleanup;
		}
	}
	ntype = *OpenLDAPacitypes[ idx ];

	/* subject */
	bv_get_tail( val, &type, &subject );

	if ( BER_BVISEMPTY( &subject ) || subject.bv_val[ 0 ] != '#' ) {
	        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: missing subject in '%s'\n", val->bv_val );
		rc = LDAP_INVALID_SYNTAX;
		goto cleanup;
	}

	subject.bv_val++;
	subject.bv_len--;

	if ( idx < LAST_DNVALUED ) {
		/* FIXME: pass DN syntax? */
		if ( normalize ) {
			rc = dnNormalize( 0, NULL, NULL,
				&subject, &nsubject, ctx );
		} else {
			rc = dnPretty( NULL, &subject, &nsubject, ctx );
		}

		if ( rc == LDAP_SUCCESS ) {
			freesubject = 1;

		} else {
	                Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid subject dn '%s'\n", subject.bv_val );
			goto cleanup;
		}

		if ( OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_GROUP ]
			|| OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_ROLE ] )
		{
			/* do {group|role}/oc/at check */
			struct berval	ocbv = BER_BVNULL,
					atbv = BER_BVNULL;

			ocbv.bv_val = ber_bvchr( &type, '/' );
			if ( ocbv.bv_val != NULL ) {
				ObjectClass		*oc = NULL;
				AttributeDescription	*ad = NULL;
				const char		*text = NULL;
				int			rc;
				struct berval		bv;

				bv.bv_len = ntype.bv_len;

				ocbv.bv_val++;
				ocbv.bv_len = type.bv_len - ( ocbv.bv_val - type.bv_val );

				atbv.bv_val = ber_bvchr( &ocbv, '/' );
				if ( atbv.bv_val != NULL ) {
					atbv.bv_val++;
					atbv.bv_len = type.bv_len
						- ( atbv.bv_val - type.bv_val );
					ocbv.bv_len = atbv.bv_val - ocbv.bv_val - 1;

					rc = slap_bv2ad( &atbv, &ad, &text );
					if ( rc != LDAP_SUCCESS ) {
	                                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown group attribute '%s'\n", atbv.bv_val );
						rc = LDAP_INVALID_SYNTAX;
						goto cleanup;
					}

					bv.bv_len += STRLENOF( "/" ) + ad->ad_cname.bv_len;
				}

				oc = oc_bvfind( &ocbv );
				if ( oc == NULL ) {
                                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: invalid group '%s'\n", ocbv.bv_val );
					rc = LDAP_INVALID_SYNTAX;
					goto cleanup;
				}

				bv.bv_len += STRLENOF( "/" ) + oc->soc_cname.bv_len;
				bv.bv_val = ber_memalloc_x( bv.bv_len + 1, ctx );

				ptr = bv.bv_val;
				ptr = lutil_strncopy( ptr, ntype.bv_val, ntype.bv_len );
				ptr[ 0 ] = '/';
				ptr++;
				ptr = lutil_strncopy( ptr,
					oc->soc_cname.bv_val,
					oc->soc_cname.bv_len );
				if ( ad != NULL ) {
					ptr[ 0 ] = '/';
					ptr++;
					ptr = lutil_strncopy( ptr,
						ad->ad_cname.bv_val,
						ad->ad_cname.bv_len );
				}
				ptr[ 0 ] = '\0';

				ntype = bv;
				freetype = 1;
			}
		}

	} else if ( OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_DNATTR ] ) {
		AttributeDescription	*ad = NULL;
		const char		*text = NULL;
		int			rc;

		rc = slap_bv2ad( &subject, &ad, &text );
		if ( rc != LDAP_SUCCESS ) {
                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: unknown dn attribute '%s'\n", subject.bv_val );
			rc = LDAP_INVALID_SYNTAX;
			goto cleanup;
		}

		if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
			/* FIXME: allow nameAndOptionalUID? */
                        Debug( LDAP_DEBUG_ACL, "aciPrettyNormal: wrong syntax for dn attribute '%s'\n", subject.bv_val );
			rc = LDAP_INVALID_SYNTAX;
			goto cleanup;
		}

		nsubject = ad->ad_cname;

	} else if ( OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_SET ]
		|| OpenLDAPacitypes[ idx ] == &aci_bv[ ACI_BV_SET_REF ] )
	{
		/* NOTE: dunno how to normalize it... */
		nsubject = subject;
	}


	out->bv_len =
		oid.bv_len + STRLENOF( "#" )
		+ scope.bv_len + STRLENOF( "#" )
		+ nrights.bv_len + STRLENOF( "#" )
		+ ntype.bv_len + STRLENOF( "#" )
		+ nsubject.bv_len;

	out->bv_val = ber_memalloc_x( out->bv_len + 1, ctx );
	ptr = lutil_strncopy( out->bv_val, oid.bv_val, oid.bv_len );
	ptr[ 0 ] = '#';
	ptr++;
	ptr = lutil_strncopy( ptr, scope.bv_val, scope.bv_len );
	ptr[ 0 ] = '#';
	ptr++;
	ptr = lutil_strncopy( ptr, nrights.bv_val, nrights.bv_len );
	ptr[ 0 ] = '#';
	ptr++;
	ptr = lutil_strncopy( ptr, ntype.bv_val, ntype.bv_len );
	ptr[ 0 ] = '#';
	ptr++;
	if ( !BER_BVISNULL( &nsubject ) ) {
		ptr = lutil_strncopy( ptr, nsubject.bv_val, nsubject.bv_len );
	}
	ptr[ 0 ] = '\0';

cleanup:;
	if ( freesubject ) {
		ber_memfree_x( nsubject.bv_val, ctx );
	}

	if ( freetype ) {
		ber_memfree_x( ntype.bv_val, ctx );
	}

	if ( !BER_BVISNULL( &nrights ) ) {
		ber_memfree_x( nrights.bv_val, ctx );
	}

	return rc;
}
Example #30
0
static int
LDAPRDN_rewrite( LDAPRDN rdn, unsigned flags, void *ctx )
{

	int rc, iAVA, do_sort = 0;

	for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
		LDAPAVA			*ava = rdn[ iAVA ];
		AttributeDescription	*ad;
		slap_syntax_validate_func *validf = NULL;
		slap_mr_normalize_func *normf = NULL;
		slap_syntax_transform_func *transf = NULL;
		MatchingRule *mr = NULL;
		struct berval		bv = BER_BVNULL;

		assert( ava != NULL );

		if ( ( ad = AVA_PRIVATE( ava ) ) == NULL ) {
			const char	*text = NULL;

			rc = slap_bv2ad( &ava->la_attr, &ad, &text );
			if ( rc != LDAP_SUCCESS ) {
				rc = slap_bv2undef_ad( &ava->la_attr,
					&ad, &text,
					SLAP_AD_PROXIED|slap_DN_strict );
				if ( rc != LDAP_SUCCESS ) {
					return LDAP_INVALID_SYNTAX;
				}
			}
			
			ava->la_private = ( void * )ad;
			do_sort = 1;
		}

		/* 
		 * Replace attr oid/name with the canonical name
		 */
		ava->la_attr = ad->ad_cname;

		if( ava->la_flags & LDAP_AVA_BINARY ) {
			/* AVA is binary encoded, not supported */
			return LDAP_INVALID_SYNTAX;

			/* Do not allow X-ORDERED 'VALUES' naming attributes */
		} else if( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) {
			return LDAP_INVALID_SYNTAX;

		} else if( flags & SLAP_LDAPDN_PRETTY ) {
			transf = ad->ad_type->sat_syntax->ssyn_pretty;
			if( !transf ) {
				validf = ad->ad_type->sat_syntax->ssyn_validate;
			}
		} else { /* normalization */
			validf = ad->ad_type->sat_syntax->ssyn_validate;
			mr = ad->ad_type->sat_equality;
			if( mr && (!( mr->smr_usage & SLAP_MR_MUTATION_NORMALIZER ))) {
				normf = mr->smr_normalize;
			}
		}

		if ( validf ) {
			/* validate value before normalization */
			rc = ( *validf )( ad->ad_type->sat_syntax,
				ava->la_value.bv_len
					? &ava->la_value
					: (struct berval *) &slap_empty_bv );

			if ( rc != LDAP_SUCCESS ) {
				return LDAP_INVALID_SYNTAX;
			}
		}

		if ( transf ) {
			/*
		 	 * transform value by pretty function
			 *	if value is empty, use empty_bv
			 */
			rc = ( *transf )( ad->ad_type->sat_syntax,
				ava->la_value.bv_len
					? &ava->la_value
					: (struct berval *) &slap_empty_bv,
				&bv, ctx );
		
			if ( rc != LDAP_SUCCESS ) {
				return LDAP_INVALID_SYNTAX;
			}
		}

		if ( normf ) {
			/*
		 	 * normalize value
			 *	if value is empty, use empty_bv
			 */
			rc = ( *normf )(
				SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
				ad->ad_type->sat_syntax,
				mr,
				ava->la_value.bv_len
					? &ava->la_value
					: (struct berval *) &slap_empty_bv,
				&bv, ctx );
		
			if ( rc != LDAP_SUCCESS ) {
				return LDAP_INVALID_SYNTAX;
			}
		}


		if( bv.bv_val ) {
			if ( ava->la_flags & LDAP_AVA_FREE_VALUE )
				ber_memfree_x( ava->la_value.bv_val, ctx );
			ava->la_value = bv;
			ava->la_flags |= LDAP_AVA_FREE_VALUE;
		}
		/* reject empty values */
		if (!ava->la_value.bv_len) {
			return LDAP_INVALID_SYNTAX;
		}
	}
	rc = LDAP_SUCCESS;

	if ( do_sort ) {
		rc = AVA_Sort( rdn, iAVA );
	}

	return rc;
}