mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
73276e84ae
Includes support for update referral for each replicated backend. Reworked replication test to use update referral. Includes major rewrite of response encoding codes (result.c). Includes reworked alias support and eliminates old suffix alias codes (can be emulated using named alias). Includes (untested) support for the Manage DSA IT control. Works in LDAPv2 world. Still testing in LDAPv3 world. Added default referral (test009) test.
136 lines
2.8 KiB
C
136 lines
2.8 KiB
C
/* compare.c - bdb2 backend compare routine */
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/socket.h>
|
|
#include <ac/string.h>
|
|
|
|
#include "slap.h"
|
|
#include "back-bdb2.h"
|
|
#include "proto-back-bdb2.h"
|
|
|
|
static int
|
|
bdb2i_back_compare_internal(
|
|
BackendDB *be,
|
|
Connection *conn,
|
|
Operation *op,
|
|
char *dn,
|
|
Ava *ava
|
|
)
|
|
{
|
|
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
Entry *matched;
|
|
Entry *e;
|
|
Attribute *a;
|
|
int rc;
|
|
int manageDSAit = get_manageDSAit( op );
|
|
|
|
/* get entry with reader lock */
|
|
if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
|
|
char *matched_dn = NULL;
|
|
struct berval **refs = NULL;
|
|
|
|
if ( matched != NULL ) {
|
|
matched_dn = ch_strdup( matched->e_dn );
|
|
refs = is_entry_referral( matched )
|
|
? get_entry_referrals( be, conn, op, matched )
|
|
: NULL;
|
|
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
} else {
|
|
refs = default_referral;
|
|
}
|
|
|
|
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
matched_dn, NULL, refs, NULL );
|
|
|
|
if( matched != NULL ) {
|
|
ber_bvecfree( refs );
|
|
free( matched_dn );
|
|
}
|
|
|
|
return( 1 );
|
|
}
|
|
|
|
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
/* entry is a referral, don't allow add */
|
|
struct berval **refs = get_entry_referrals( be,
|
|
conn, op, e );
|
|
|
|
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
0, 0 );
|
|
|
|
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
e->e_dn, NULL, refs, NULL );
|
|
|
|
ber_bvecfree( refs );
|
|
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
|
|
if ( ! access_allowed( be, conn, op, e,
|
|
ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
|
|
{
|
|
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
NULL, NULL, NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
|
|
if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
|
|
send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
|
|
NULL, NULL, NULL, NULL );
|
|
rc = 1;
|
|
goto return_results;
|
|
}
|
|
|
|
if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 )
|
|
send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
|
|
NULL, NULL, NULL, NULL );
|
|
else
|
|
send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
|
|
NULL, NULL, NULL, NULL );
|
|
|
|
rc = 0;
|
|
|
|
return_results:;
|
|
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
return( rc );
|
|
}
|
|
|
|
|
|
int
|
|
bdb2_back_compare(
|
|
BackendDB *be,
|
|
Connection *conn,
|
|
Operation *op,
|
|
char *dn,
|
|
Ava *ava
|
|
)
|
|
{
|
|
DB_LOCK lock;
|
|
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
struct timeval time1;
|
|
int ret;
|
|
|
|
bdb2i_start_timing( be->bd_info, &time1 );
|
|
|
|
if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
|
|
|
|
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
NULL, NULL, NULL, NULL );
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
ret = bdb2i_back_compare_internal( be, conn, op, dn, ava );
|
|
(void) bdb2i_leave_backend_r( lock );
|
|
bdb2i_stop_timing( be->bd_info, time1, "CMP", conn, op );
|
|
|
|
return( ret );
|
|
}
|
|
|
|
|