openldap/servers/slapd/back-ldbm/compare.c
Kurt Zeilenga 82fad7d0c8 First stable an implementing latest namedref specification.
Includes rewriting of URLs where the DN of the referral object
and the DN of the ref attribute attribute are not the same.
Also, always returns explicit DN and scope.
Currently, back-ldbm only.  Needs to be ported to back-bdb.
2001-10-26 02:05:14 +00:00

124 lines
2.5 KiB
C

/* compare.c - ldbm backend compare routine */
/* $OpenLDAP$ */
/*
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include "slap.h"
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
int
ldbm_back_compare(
Backend *be,
Connection *conn,
Operation *op,
const char *dn,
const char *ndn,
AttributeAssertion *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 = dn2entry_r( be, ndn, &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,
dn, LDAP_SCOPE_DEFAULT )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = referral_rewrite( default_referral,
NULL, dn, LDAP_SCOPE_DEFAULT );
}
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, 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, dn, LDAP_SCOPE_DEFAULT );
#ifdef NEW_LOGGING
LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
"ldbm_back_compare: entry (%s) is a referral.\n", e->e_dn ));
#else
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
#endif
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->aa_desc, ava->aa_value, ACL_COMPARE ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
rc = LDAP_NO_SUCH_ATTRIBUTE;
for(a = attrs_find( e->e_attrs, ava->aa_desc );
a != NULL;
a = attrs_find( a->a_next, ava->aa_desc ))
{
rc = LDAP_COMPARE_FALSE;
if ( value_find_ex( ava->aa_desc,
SLAP_MR_VALUE_IS_IN_MR_SYNTAX,
a->a_vals, ava->aa_value ) == 0 )
{
rc = LDAP_COMPARE_TRUE;
break;
}
}
send_ldap_result( conn, op, rc,
NULL, NULL, NULL, NULL );
if( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
rc = 0;
}
return_results:;
cache_return_entry_r( &li->li_cache, e );
return( rc );
}