]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb2/compare.c
Fix maxDeref directive
[openldap] / servers / slapd / back-bdb2 / compare.c
1 /* compare.c - bdb2 backend compare routine */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/socket.h>
8 #include <ac/string.h>
9
10 #include "slap.h"
11 #include "back-bdb2.h"
12 #include "proto-back-bdb2.h"
13
14 static int
15 bdb2i_back_compare_internal(
16     BackendDB   *be,
17     Connection  *conn,
18     Operation   *op,
19     char        *dn,
20     Ava         *ava
21 )
22 {
23         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
24         Entry           *matched;
25         Entry           *e;
26         Attribute       *a;
27         int             rc;
28         int             manageDSAit = get_manageDSAit( op );
29
30         /* get entry with reader lock */
31         if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
32                 char *matched_dn = NULL;
33                 struct berval **refs = NULL;
34
35                 if ( matched != NULL ) {
36                         matched_dn = ch_strdup( matched->e_dn );
37                         refs = is_entry_referral( matched )
38                                 ? get_entry_referrals( be, conn, op, matched )
39                                 : NULL;
40                         bdb2i_cache_return_entry_r( &li->li_cache, matched );
41                 } else {
42                         refs = default_referral;
43                 }
44
45                 send_ldap_result( conn, op, LDAP_REFERRAL,
46                         matched_dn, NULL, refs, NULL );
47
48                 if( matched != NULL ) {
49                         ber_bvecfree( refs );
50                         free( matched_dn );
51                 }
52
53                 return( 1 );
54         }
55
56         if (!manageDSAit && is_entry_referral( e ) ) {
57                 /* entry is a referral, don't allow add */
58                 struct berval **refs = get_entry_referrals( be,
59                         conn, op, e );
60
61                 Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
62                         0, 0 );
63
64                 send_ldap_result( conn, op, LDAP_REFERRAL,
65                         e->e_dn, NULL, refs, NULL );
66
67                 ber_bvecfree( refs );
68
69                 rc = 1;
70                 goto return_results;
71         }
72
73         if ( ! access_allowed( be, conn, op, e,
74                 ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
75         {
76                 send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
77                         NULL, NULL, NULL, NULL );
78                 rc = 1;
79                 goto return_results;
80         }
81
82         if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
83                 send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
84                         NULL, NULL, NULL, NULL );
85                 rc = 1;
86                 goto return_results;
87         }
88
89         if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) 
90                 send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
91                         NULL, NULL, NULL, NULL );
92         else
93                 send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
94                         NULL, NULL, NULL, NULL );
95
96         rc = 0;
97
98 return_results:;
99         bdb2i_cache_return_entry_r( &li->li_cache, e );
100         return( rc );
101 }
102
103
104 int
105 bdb2_back_compare(
106     BackendDB   *be,
107     Connection  *conn,
108     Operation   *op,
109     char        *dn,
110     Ava         *ava
111 )
112 {
113         DB_LOCK         lock;
114         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
115         struct timeval  time1;
116         int             ret;
117
118         bdb2i_start_timing( be->bd_info, &time1 );
119
120         if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
121
122                 send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
123                         NULL, NULL, NULL, NULL );
124                 return( 1 );
125
126         }
127
128         ret = bdb2i_back_compare_internal( be, conn, op, dn, ava );
129         (void) bdb2i_leave_backend_r( lock );
130         bdb2i_stop_timing( be->bd_info, time1, "CMP", conn, op );
131
132         return( ret );
133 }
134
135