1 /* $NetBSD: compare.c,v 1.3 2021/08/14 16:15:01 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1999-2021 The OpenLDAP Foundation.
7 * Portions Copyright 1999 Dmitry Kovalev.
8 * Portions Copyright 2002 Pierangelo Masarati.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted only as authorized by the OpenLDAP
13 * Public License.
14 *
15 * A copy of this license is available in the file LICENSE in the
16 * top-level directory of the distribution or, alternatively, at
17 * <http://www.OpenLDAP.org/license.html>.
18 */
19 /* ACKNOWLEDGEMENTS:
20 * This work was initially developed by Dmitry Kovalev for inclusion
21 * by OpenLDAP Software. Additional significant contributors include
22 * Pierangelo Masarati.
23 */
24
25 #include <sys/cdefs.h>
26 __RCSID("$NetBSD: compare.c,v 1.3 2021/08/14 16:15:01 christos Exp $");
27
28 #include "portable.h"
29
30 #include <stdio.h>
31 #include <sys/types.h>
32
33 #include "slap.h"
34 #include "proto-sql.h"
35
36 int
backsql_compare(Operation * op,SlapReply * rs)37 backsql_compare( Operation *op, SlapReply *rs )
38 {
39 SQLHDBC dbh = SQL_NULL_HDBC;
40 Entry e = { 0 };
41 Attribute *a = NULL;
42 backsql_srch_info bsi = { 0 };
43 int rc;
44 int manageDSAit = get_manageDSAit( op );
45 AttributeName anlist[2];
46
47 Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n" );
48
49 rs->sr_err = backsql_get_db_conn( op, &dbh );
50 if ( rs->sr_err != LDAP_SUCCESS ) {
51 Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
52 "could not get connection handle - exiting\n" );
53
54 rs->sr_text = ( rs->sr_err == LDAP_OTHER )
55 ? "SQL-backend error" : NULL;
56 goto return_results;
57 }
58
59 anlist[ 0 ].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
60 anlist[ 0 ].an_desc = op->oq_compare.rs_ava->aa_desc;
61 BER_BVZERO( &anlist[ 1 ].an_name );
62
63 /*
64 * Get the entry
65 */
66 bsi.bsi_e = &e;
67 rc = backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE,
68 (time_t)(-1), NULL, dbh, op, rs, anlist,
69 ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
70 switch ( rc ) {
71 case LDAP_SUCCESS:
72 break;
73
74 case LDAP_REFERRAL:
75 if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&
76 dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname ) )
77 {
78 rs->sr_err = LDAP_SUCCESS;
79 rs->sr_text = NULL;
80 rs->sr_matched = NULL;
81 if ( rs->sr_ref ) {
82 ber_bvarray_free( rs->sr_ref );
83 rs->sr_ref = NULL;
84 }
85 break;
86 }
87 /* fallthru */
88
89 default:
90 Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
91 "could not retrieve compareDN ID - no such entry\n" );
92 goto return_results;
93 }
94
95 if ( get_assert( op ) &&
96 ( test_filter( op, &e, get_assertion( op ) )
97 != LDAP_COMPARE_TRUE ) )
98 {
99 rs->sr_err = LDAP_ASSERTION_FAILED;
100 goto return_results;
101 }
102
103 if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
104 SlapReply nrs = { REP_SEARCH };
105 Attribute **ap;
106
107 for ( ap = &e.e_attrs; *ap; ap = &(*ap)->a_next )
108 ;
109
110 nrs.sr_attrs = anlist;
111 nrs.sr_entry = &e;
112 nrs.sr_attr_flags = SLAP_OPATTRS_NO;
113 nrs.sr_operational_attrs = NULL;
114
115 rs->sr_err = backsql_operational( op, &nrs );
116 if ( rs->sr_err != LDAP_SUCCESS ) {
117 goto return_results;
118 }
119
120 *ap = nrs.sr_operational_attrs;
121 }
122
123 if ( ! access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc,
124 &op->oq_compare.rs_ava->aa_value,
125 ACL_COMPARE, NULL ) )
126 {
127 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
128 goto return_results;
129 }
130
131 rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
132 for ( a = attrs_find( e.e_attrs, op->oq_compare.rs_ava->aa_desc );
133 a != NULL;
134 a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
135 {
136 rs->sr_err = LDAP_COMPARE_FALSE;
137 if ( attr_valfind( a,
138 SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
139 SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
140 &op->oq_compare.rs_ava->aa_value, NULL,
141 op->o_tmpmemctx ) == 0 )
142 {
143 rs->sr_err = LDAP_COMPARE_TRUE;
144 break;
145 }
146 }
147
148 return_results:;
149 switch ( rs->sr_err ) {
150 case LDAP_COMPARE_TRUE:
151 case LDAP_COMPARE_FALSE:
152 break;
153
154 default:
155 if ( !BER_BVISNULL( &e.e_nname ) &&
156 ! access_allowed( op, &e,
157 slap_schema.si_ad_entry, NULL,
158 ACL_DISCLOSE, NULL ) )
159 {
160 rs->sr_err = LDAP_NO_SUCH_OBJECT;
161 rs->sr_text = NULL;
162 }
163 break;
164 }
165
166 send_ldap_result( op, rs );
167
168 if ( rs->sr_matched ) {
169 rs->sr_matched = NULL;
170 }
171
172 if ( rs->sr_ref ) {
173 ber_bvarray_free( rs->sr_ref );
174 rs->sr_ref = NULL;
175 }
176
177 if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
178 (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
179 }
180
181 if ( !BER_BVISNULL( &e.e_nname ) ) {
182 backsql_entry_clean( op, &e );
183 }
184
185 if ( bsi.bsi_attrs != NULL ) {
186 op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
187 }
188
189 Debug(LDAP_DEBUG_TRACE,"<==backsql_compare()\n" );
190 switch ( rs->sr_err ) {
191 case LDAP_COMPARE_TRUE:
192 case LDAP_COMPARE_FALSE:
193 return LDAP_SUCCESS;
194
195 default:
196 return rs->sr_err;
197 }
198 }
199
200