Beispiel #1
0
static int
collect_response( Operation *op, SlapReply *rs )
{
	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
	collect_info *ci = on->on_bi.bi_private;

	/* If we've been configured and the current response is
	 * a search entry
	 */
	if ( ci && rs->sr_type == REP_SEARCH ) {
		int rc;

		op->o_bd->bd_info = (BackendInfo *)on->on_info;

		for (; ci; ci=ci->ci_next ) {
			int idx=0;

			/* Is this entry an ancestor of this collectinfo ? */
			if (!dnIsSuffix(&rs->sr_entry->e_nname, &ci->ci_dn)) {
				/* collectinfo does not match */
				continue;
			}

			/* Is this entry the same as the template DN ? */
			if ( dn_match(&rs->sr_entry->e_nname, &ci->ci_dn)) {
				/* dont apply change to parent */
				continue;
			}

			/* The current entry may live in a cache, so
			* don't modify it directly. Make a copy and
			* work with that instead.
			*/
			rs_entry2modifiable( op, rs, on );

			/* Loop for each attribute in this collectinfo */
			for(idx=0; idx<ci->ci_ad_num; idx++) {
				BerVarray vals = NULL;

				/* Extract the values of the desired attribute from
			 	 * the ancestor entry */
				rc = backend_attribute( op, NULL, &ci->ci_dn, 
					ci->ci_ad[idx], &vals, ACL_READ );

				/* If there are any values, merge them into the
			 	 * current search result
			 	 */
				if ( vals ) {
					attr_merge( rs->sr_entry, ci->ci_ad[idx], 
						vals, NULL );
					ber_bvarray_free_x( vals, op->o_tmpmemctx );
				}
			}
		}
	}

	/* Default is to just fall through to the normal processing */
	return SLAP_CB_CONTINUE;
}
Beispiel #2
0
static int
usn_operational(
	Operation *op,
	SlapReply *rs )
{
	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;
	usn_info_t		*ui = (usn_info_t *)on->on_bi.bi_private;

	if ( rs->sr_entry &&
		dn_match( &rs->sr_entry->e_nname, op->o_bd->be_nsuffix )) {

		if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
			ad_inlist( ad_usnChanged, rs->sr_attrs )) {
			Attribute *a, **ap = NULL;
			char intbuf[64];
			struct berval bv;
			int my_usn;

			for ( a=rs->sr_entry->e_attrs; a; a=a->a_next ) {
				if ( a->a_desc == ad_usnChanged )
					break;
			}

			if ( !a ) {
				for ( ap = &rs->sr_operational_attrs; *ap;
					ap=&(*ap)->a_next );

					a = attr_alloc( ad_usnChanged );
					*ap = a;
				}

			if ( !ap ) {
				if ( rs_entry2modifiable( op,rs, on )) {
					a = attr_find( rs->sr_entry->e_attrs,
						ad_usnChanged );
				}
				ber_bvarray_free( a->a_vals );
				a->a_vals = NULL;
				a->a_numvals = 0;
			}
			ldap_pvt_thread_mutex_lock( &ui->ui_mutex );
			my_usn = ui->ui_current;
			ldap_pvt_thread_mutex_unlock( &ui->ui_mutex );
			bv.bv_len = snprintf( intbuf, sizeof(intbuf), "%d", my_usn );
			bv.bv_val = intbuf;
			attr_valadd( a, &bv, NULL, 1 );
		}
	}
	return SLAP_CB_CONTINUE;
}
Beispiel #3
0
static int
valsort_response( Operation *op, SlapReply *rs )
{
    slap_overinst *on;
    valsort_info *vi;
    Attribute *a;

    /* If this is not a search response, or it is a syncrepl response,
     * or the valsort control wants raw results, pass thru unmodified.
     */
    if ( rs->sr_type != REP_SEARCH ||
            ( _SCM(op->o_sync) > SLAP_CONTROL_IGNORED ) ||
            ( op->o_ctrlflag[valsort_cid] & SLAP_CONTROL_DATA0))
        return SLAP_CB_CONTINUE;

    on = (slap_overinst *) op->o_bd->bd_info;
    vi = on->on_bi.bi_private;

    /* And we must have something configured */
    if ( !vi ) return SLAP_CB_CONTINUE;

    /* Find a rule whose baseDN matches this entry */
    for (; vi; vi = vi->vi_next ) {
        int i, n;

        if ( !dnIsSuffix( &rs->sr_entry->e_nname, &vi->vi_dn ))
            continue;

        /* Find attr that this rule affects */
        a = attr_find( rs->sr_entry->e_attrs, vi->vi_ad );
        if ( !a ) continue;

        if ( rs_entry2modifiable( op, rs, on )) {
            a = attr_find( rs->sr_entry->e_attrs, vi->vi_ad );
        }

        n = a->a_numvals;
        if ( vi->vi_sort & VALSORT_WEIGHTED ) {
            int j, gotnvals;
            long *index = op->o_tmpalloc( n * sizeof(long), op->o_tmpmemctx );

            gotnvals = (a->a_vals != a->a_nvals );

            for (i=0; i<n; i++) {
                char *ptr = ber_bvchr( &a->a_nvals[i], '{' );
                char *end = NULL;
                if ( !ptr ) {
                    Debug(LDAP_DEBUG_TRACE, "weights missing from attr %s "
                          "in entry %s\n", vi->vi_ad->ad_cname.bv_val,
                          rs->sr_entry->e_name.bv_val, 0 );
                    break;
                }
                index[i] = strtol( ptr+1, &end, 0 );
                if ( *end != '}' ) {
                    Debug(LDAP_DEBUG_TRACE, "weights misformatted "
                          "in entry %s\n",
                          rs->sr_entry->e_name.bv_val, 0, 0 );
                    break;
                }
                /* Strip out weights */
                ptr = a->a_nvals[i].bv_val;
                end++;
                for (; *end;)
                    *ptr++ = *end++;
                *ptr = '\0';
                a->a_nvals[i].bv_len = ptr - a->a_nvals[i].bv_val;

                if ( a->a_vals != a->a_nvals ) {
                    ptr = a->a_vals[i].bv_val;
                    end = ber_bvchr( &a->a_vals[i], '}' );
                    assert( end != NULL );
                    end++;
                    for (; *end;)
                        *ptr++ = *end++;
                    *ptr = '\0';
                    a->a_vals[i].bv_len = ptr - a->a_vals[i].bv_val;
                }
            }
            /* An attr was missing weights here, ignore it */
            if ( i<n ) {
                op->o_tmpfree( index, op->o_tmpmemctx );
                continue;
            }
            /* Insertion sort */
            for ( i=1; i<n; i++) {
                long idx = index[i];
                struct berval tmp = a->a_vals[i], ntmp;
                if ( gotnvals ) ntmp = a->a_nvals[i];
                j = i;
                while (( j>0 ) && (index[j-1] > idx )) {
                    index[j] = index[j-1];
                    a->a_vals[j] = a->a_vals[j-1];
                    if ( gotnvals ) a->a_nvals[j] = a->a_nvals[j-1];
                    j--;
                }
                index[j] = idx;
                a->a_vals[j] = tmp;
                if ( gotnvals ) a->a_nvals[j] = ntmp;
            }
            /* Check for secondary sort */
            if ( vi->vi_sort ^ VALSORT_WEIGHTED ) {
                for ( i=0; i<n;) {
                    for (j=i+1; j<n; j++) {
                        if (index[i] != index[j])
                            break;
                    }
                    if( j-i > 1 )
                        do_sort( op, a, i, j-i, vi->vi_sort );
                    i = j;
                }
            }
            op->o_tmpfree( index, op->o_tmpmemctx );
        } else {
            do_sort( op, a, 0, n, vi->vi_sort );
        }
    }
    return SLAP_CB_CONTINUE;
}
Beispiel #4
0
static int
dupent_response_entry( Operation *op, SlapReply *rs )
{
	dupent_cb_t	*dc = (dupent_cb_t *)op->o_callback->sc_private;
	int			nattrs = 0;
	valnum_t	*valnum = NULL;
	Attribute	**app, *ap_list = NULL;
	int			i, c;
	Entry		*e = NULL;
	int			rc;

	assert( rs->sr_type == REP_SEARCH );

	for ( i = 0; i < dc->dc_ds->ds_nattrs; i++ ) {
		Attribute *ap;

		ap = attr_find( rs->sr_entry->e_attrs,
			dc->dc_ds->ds_an[ i ].an_desc );
		if ( ap && ap->a_numvals > 1 ) {
			nattrs++;
		}
	}

	if ( dc->dc_ds->ds_flags & SLAP_USERATTRS_YES ) {
		Attribute *ap;

		for ( ap = rs->sr_entry->e_attrs; ap != NULL; ap = ap->a_next ) {
			if ( !is_at_operational( ap->a_desc->ad_type ) && ap->a_numvals > 1 ) {
				nattrs++;
			}
		}
	}

	if ( !nattrs ) {
		return SLAP_CB_CONTINUE;
	}

	rs_entry2modifiable( op, rs, dc->dc_on );
	rs->sr_flags &= ~(REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED);
	e = rs->sr_entry;

	valnum = op->o_tmpcalloc( sizeof(valnum_t), nattrs, op->o_tmpmemctx );

	for ( c = 0, i = 0; i < dc->dc_ds->ds_nattrs; i++ ) {
		for ( app = &e->e_attrs; *app != NULL; app = &(*app)->a_next ) {
			if ( (*app)->a_desc == dc->dc_ds->ds_an[ i ].an_desc ) {
				break;
			}
		}

		if ( *app != NULL && (*app)->a_numvals > 1 ) {
			assert( c < nattrs );
			dupent_attr_prepare( dc->dc_ds, e, valnum, nattrs, c, app, &ap_list );
			c++;
		}
	}

	if ( dc->dc_ds->ds_flags & SLAP_USERATTRS_YES ) {
		for ( app = &e->e_attrs; *app != NULL; app = &(*app)->a_next ) {
			if ( !is_at_operational( (*app)->a_desc->ad_type ) && (*app)->a_numvals > 1 ) {
				assert( c < nattrs );
				dupent_attr_prepare( dc->dc_ds, e, valnum, nattrs, c, app, &ap_list );
				c++;
			}
		}
	}

	for ( app = &e->e_attrs; *app != NULL; app = &(*app)->a_next )
		/* goto tail */ ;

	*app = &valnum[0].a;

	/* NOTE: since send_search_entry() does not honor the
	 * REP_CTRLS_MUSTBEFREED flag set by slap_add_ctrls(),
	 * the control could be added here once for all (ITS#6629)
	 */

	dc->dc_skip = 1;
	rc = dupent_response_entry_1level( op, rs, e, valnum, nattrs, 0 );
	dc->dc_skip = 0;

	*app = ap_list;

	entry_free( e );

	op->o_tmpfree( valnum, op->o_tmpmemctx );

	return rc;
}
Beispiel #5
0
static int
cloak_search_response_cb( Operation *op, SlapReply *rs )
{
	slap_callback   *sc;
	cloak_info_t	*ci;
	Entry		*e = NULL;
	Entry		*me = NULL;

	assert( op && op->o_callback && rs );

	if ( rs->sr_type != REP_SEARCH || !rs->sr_entry ) {
		return ( SLAP_CB_CONTINUE );
	}

	sc = op->o_callback;
	e = rs->sr_entry;

	/* 
	 * First perform a quick scan for an attribute to cloak
	 */
	for ( ci = (cloak_info_t *)sc->sc_private; ci; ci = ci->ci_next ) {
		Attribute *a;

		if ( ci->ci_oc != NULL &&
		     !is_entry_objectclass_or_sub( e, ci->ci_oc ) )
			continue;

		for ( a = e->e_attrs; a; a = a->a_next )
			if ( a->a_desc == ci->ci_ad )
				break;

		if ( a != NULL )
			break;
	}

	/*
	 * Nothing found to cloak
	 */
	if ( ci == NULL )
		return ( SLAP_CB_CONTINUE );

	/*
	 * We are now committed to cloak an attribute.
	 */
	rs_entry2modifiable( op, rs, (slap_overinst *) op->o_bd->bd_info );
	me = rs->sr_entry;
		
	for ( ci = (cloak_info_t *)sc->sc_private; ci; ci = ci->ci_next ) {
		Attribute *a;
		Attribute *pa;

		for ( pa = NULL, a = me->e_attrs;
		      a; 
		      pa = a, a = a->a_next ) {

			if ( a->a_desc != ci->ci_ad )
				continue;

			Debug( LDAP_DEBUG_TRACE, "cloak_search_response_cb: cloak %s\n", 
			       a->a_desc->ad_cname.bv_val,
			       0, 0 );

			if ( pa != NULL ) 
				pa->a_next = a->a_next;
			else
				me->e_attrs = a->a_next;

			attr_clean( a );
		}

	}

	return ( SLAP_CB_CONTINUE );
}