1 /* compare.c - bdb backend compare routine */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-bdb/compare.c,v 1.51.2.5 2008/02/11 23:26:45 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
20 #include <ac/string.h>
25 bdb_compare( Operation
*op
, SlapReply
*rs
)
27 struct bdb_info
*bdb
= (struct bdb_info
*) op
->o_bd
->be_private
;
31 int manageDSAit
= get_manageDSAit( op
);
36 rs
->sr_err
= LOCK_ID(bdb
->bi_dbenv
, &locker
);
41 send_ldap_error( op
, rs
, LDAP_OTHER
, "internal error" );
47 rs
->sr_err
= bdb_dn2entry( op
, NULL
, &op
->o_req_ndn
, &ei
, 1,
50 switch( rs
->sr_err
) {
55 rs
->sr_text
= "ldap server busy";
57 case DB_LOCK_DEADLOCK
:
58 case DB_LOCK_NOTGRANTED
:
61 rs
->sr_err
= LDAP_OTHER
;
62 rs
->sr_text
= "internal error";
67 if ( rs
->sr_err
== DB_NOTFOUND
) {
69 /* return referral only if "disclose" is granted on the object */
70 if ( ! access_allowed( op
, e
, slap_schema
.si_ad_entry
,
71 NULL
, ACL_DISCLOSE
, NULL
) )
73 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
76 rs
->sr_matched
= ch_strdup( e
->e_dn
);
77 rs
->sr_ref
= is_entry_referral( e
)
78 ? get_entry_referrals( op
, e
)
80 rs
->sr_err
= LDAP_REFERRAL
;
83 bdb_cache_return_entry_r( bdb
, e
, &lock
);
87 rs
->sr_ref
= referral_rewrite( default_referral
,
88 NULL
, &op
->o_req_dn
, LDAP_SCOPE_DEFAULT
);
89 rs
->sr_err
= rs
->sr_ref
? LDAP_REFERRAL
: LDAP_NO_SUCH_OBJECT
;
92 send_ldap_result( op
, rs
);
94 ber_bvarray_free( rs
->sr_ref
);
95 free( (char *)rs
->sr_matched
);
97 rs
->sr_matched
= NULL
;
102 if (!manageDSAit
&& is_entry_referral( e
) ) {
103 /* return referral only if "disclose" is granted on the object */
104 if ( !access_allowed( op
, e
, slap_schema
.si_ad_entry
,
105 NULL
, ACL_DISCLOSE
, NULL
) )
107 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
109 /* entry is a referral, don't allow compare */
110 rs
->sr_ref
= get_entry_referrals( op
, e
);
111 rs
->sr_err
= LDAP_REFERRAL
;
112 rs
->sr_matched
= e
->e_name
.bv_val
;
115 Debug( LDAP_DEBUG_TRACE
, "entry is referral\n", 0, 0, 0 );
117 send_ldap_result( op
, rs
);
119 ber_bvarray_free( rs
->sr_ref
);
121 rs
->sr_matched
= NULL
;
125 if ( get_assert( op
) &&
126 ( test_filter( op
, e
, get_assertion( op
)) != LDAP_COMPARE_TRUE
))
128 if ( !access_allowed( op
, e
, slap_schema
.si_ad_entry
,
129 NULL
, ACL_DISCLOSE
, NULL
) )
131 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
133 rs
->sr_err
= LDAP_ASSERTION_FAILED
;
138 if ( !access_allowed( op
, e
, op
->oq_compare
.rs_ava
->aa_desc
,
139 &op
->oq_compare
.rs_ava
->aa_value
, ACL_COMPARE
, NULL
) )
141 /* return error only if "disclose"
142 * is granted on the object */
143 if ( !access_allowed( op
, e
, slap_schema
.si_ad_entry
,
144 NULL
, ACL_DISCLOSE
, NULL
) )
146 rs
->sr_err
= LDAP_NO_SUCH_OBJECT
;
148 rs
->sr_err
= LDAP_INSUFFICIENT_ACCESS
;
153 rs
->sr_err
= LDAP_NO_SUCH_ATTRIBUTE
;
155 for ( a
= attrs_find( e
->e_attrs
, op
->oq_compare
.rs_ava
->aa_desc
);
157 a
= attrs_find( a
->a_next
, op
->oq_compare
.rs_ava
->aa_desc
) )
159 rs
->sr_err
= LDAP_COMPARE_FALSE
;
161 if ( attr_valfind( a
,
162 SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH
|
163 SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH
,
164 &op
->oq_compare
.rs_ava
->aa_value
, NULL
,
165 op
->o_tmpmemctx
) == 0 )
167 rs
->sr_err
= LDAP_COMPARE_TRUE
;
173 send_ldap_result( op
, rs
);
175 switch ( rs
->sr_err
) {
176 case LDAP_COMPARE_FALSE
:
177 case LDAP_COMPARE_TRUE
:
178 rs
->sr_err
= LDAP_SUCCESS
;
185 bdb_cache_return_entry_r( bdb
, e
, &lock
);
188 LOCK_ID_FREE ( bdb
->bi_dbenv
, locker
);