1191783Srmacklem/*	$NetBSD$	*/
2191783Srmacklem
3191783Srmacklem/* OpenLDAP: pkg/ldap/servers/slapd/back-sql/compare.c,v 1.24.2.7 2010/04/13 20:23:42 kurt Exp */
4191783Srmacklem/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5191783Srmacklem *
6191783Srmacklem * Copyright 1999-2010 The OpenLDAP Foundation.
7191783Srmacklem * Portions Copyright 1999 Dmitry Kovalev.
8191783Srmacklem * Portions Copyright 2002 Pierangelo Masarati.
9191783Srmacklem * All rights reserved.
10191783Srmacklem *
11191783Srmacklem * Redistribution and use in source and binary forms, with or without
12191783Srmacklem * modification, are permitted only as authorized by the OpenLDAP
13191783Srmacklem * Public License.
14191783Srmacklem *
15191783Srmacklem * A copy of this license is available in the file LICENSE in the
16191783Srmacklem * top-level directory of the distribution or, alternatively, at
17191783Srmacklem * <http://www.OpenLDAP.org/license.html>.
18191783Srmacklem */
19191783Srmacklem/* ACKNOWLEDGEMENTS:
20191783Srmacklem * This work was initially developed by Dmitry Kovalev for inclusion
21191783Srmacklem * by OpenLDAP Software.  Additional significant contributors include
22191783Srmacklem * Pierangelo Masarati.
23191783Srmacklem */
24191783Srmacklem
25191783Srmacklem#include "portable.h"
26191783Srmacklem
27191783Srmacklem#include <stdio.h>
28191783Srmacklem#include <sys/types.h>
29191783Srmacklem
30191783Srmacklem#include "slap.h"
31191783Srmacklem#include "proto-sql.h"
32191783Srmacklem
33191783Srmacklemint
34191783Srmacklembacksql_compare( Operation *op, SlapReply *rs )
35191783Srmacklem{
36191783Srmacklem	SQLHDBC			dbh = SQL_NULL_HDBC;
37191783Srmacklem	Entry			e = { 0 };
38191783Srmacklem	Attribute		*a = NULL;
39191783Srmacklem	backsql_srch_info	bsi = { 0 };
40191783Srmacklem	int			rc;
41191783Srmacklem	int			manageDSAit = get_manageDSAit( op );
42191783Srmacklem	AttributeName		anlist[2];
43191783Srmacklem
44214255Srmacklem 	Debug( LDAP_DEBUG_TRACE, "==>backsql_compare()\n", 0, 0, 0 );
45191783Srmacklem
46192503Srmacklem	rs->sr_err = backsql_get_db_conn( op, &dbh );
47192503Srmacklem	if ( rs->sr_err != LDAP_SUCCESS ) {
48191783Srmacklem     		Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
49219028Snetchild			"could not get connection handle - exiting\n",
50219028Snetchild			0, 0, 0 );
51191783Srmacklem
52191783Srmacklem		rs->sr_text = ( rs->sr_err == LDAP_OTHER )
53191783Srmacklem			? "SQL-backend error" : NULL;
54191783Srmacklem		goto return_results;
55191783Srmacklem	}
56191783Srmacklem
57220530Srmacklem	anlist[ 0 ].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
58191783Srmacklem	anlist[ 0 ].an_desc = op->oq_compare.rs_ava->aa_desc;
59191783Srmacklem	BER_BVZERO( &anlist[ 1 ].an_name );
60191783Srmacklem
61191783Srmacklem	/*
62191783Srmacklem	 * Get the entry
63191783Srmacklem	 */
64217432Srmacklem	bsi.bsi_e = &e;
65217432Srmacklem	rc = backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE,
66217432Srmacklem			(time_t)(-1), NULL, dbh, op, rs, anlist,
67217432Srmacklem			( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) );
68192503Srmacklem	switch ( rc ) {
69191783Srmacklem	case LDAP_SUCCESS:
70192255Srmacklem		break;
71192255Srmacklem
72191783Srmacklem	case LDAP_REFERRAL:
73220645Srmacklem		if ( manageDSAit && !BER_BVISNULL( &bsi.bsi_e->e_nname ) &&
74191783Srmacklem				dn_match( &op->o_req_ndn, &bsi.bsi_e->e_nname ) )
75191783Srmacklem		{
76191783Srmacklem			rs->sr_err = LDAP_SUCCESS;
77192255Srmacklem			rs->sr_text = NULL;
78192255Srmacklem			rs->sr_matched = NULL;
79221615Srmacklem			if ( rs->sr_ref ) {
80221615Srmacklem				ber_bvarray_free( rs->sr_ref );
81220645Srmacklem				rs->sr_ref = NULL;
82221615Srmacklem			}
83192255Srmacklem			break;
84221615Srmacklem		}
85192255Srmacklem		/* fallthru */
86221615Srmacklem
87192255Srmacklem	default:
88221615Srmacklem		Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
89192255Srmacklem			"could not retrieve compareDN ID - no such entry\n",
90191783Srmacklem			0, 0, 0 );
91191783Srmacklem		goto return_results;
92191783Srmacklem	}
93191783Srmacklem
94191783Srmacklem	if ( get_assert( op ) &&
95191783Srmacklem			( test_filter( op, &e, get_assertion( op ) )
96191783Srmacklem			  != LDAP_COMPARE_TRUE ) )
97191783Srmacklem	{
98191783Srmacklem		rs->sr_err = LDAP_ASSERTION_FAILED;
99191783Srmacklem		goto return_results;
100191783Srmacklem	}
101191783Srmacklem
102191783Srmacklem	if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
103191783Srmacklem		SlapReply	nrs = { 0 };
104191783Srmacklem		Attribute	**ap;
105191783Srmacklem
106191783Srmacklem		for ( ap = &e.e_attrs; *ap; ap = &(*ap)->a_next )
107191783Srmacklem			;
108191783Srmacklem
109216693Srmacklem		nrs.sr_attrs = anlist;
110191783Srmacklem		nrs.sr_entry = &e;
111191783Srmacklem		nrs.sr_attr_flags = SLAP_OPATTRS_NO;
112191783Srmacklem		nrs.sr_operational_attrs = NULL;
113216693Srmacklem
114216693Srmacklem		rs->sr_err = backsql_operational( op, &nrs );
115216693Srmacklem		if ( rs->sr_err != LDAP_SUCCESS ) {
116216693Srmacklem			goto return_results;
117216693Srmacklem		}
118216693Srmacklem
119216693Srmacklem		*ap = nrs.sr_operational_attrs;
120216693Srmacklem	}
121216693Srmacklem
122216693Srmacklem	if ( ! access_allowed( op, &e, op->oq_compare.rs_ava->aa_desc,
123191783Srmacklem				&op->oq_compare.rs_ava->aa_value,
124191783Srmacklem				ACL_COMPARE, NULL ) )
125216693Srmacklem	{
126216693Srmacklem		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
127191783Srmacklem		goto return_results;
128191783Srmacklem	}
129191783Srmacklem
130191783Srmacklem	rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;
131191783Srmacklem	for ( a = attrs_find( e.e_attrs, op->oq_compare.rs_ava->aa_desc );
132191783Srmacklem			a != NULL;
133191783Srmacklem			a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
134191783Srmacklem	{
135191783Srmacklem		rs->sr_err = LDAP_COMPARE_FALSE;
136191783Srmacklem		if ( attr_valfind( a,
137191783Srmacklem					SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
138191783Srmacklem					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
139191783Srmacklem					&op->oq_compare.rs_ava->aa_value, NULL,
140191783Srmacklem					op->o_tmpmemctx ) == 0 )
141191783Srmacklem		{
142191783Srmacklem			rs->sr_err = LDAP_COMPARE_TRUE;
143191783Srmacklem			break;
144191783Srmacklem		}
145191783Srmacklem	}
146191783Srmacklem
147200999Srmacklemreturn_results:;
148200999Srmacklem	switch ( rs->sr_err ) {
149200999Srmacklem	case LDAP_COMPARE_TRUE:
150191783Srmacklem	case LDAP_COMPARE_FALSE:
151191783Srmacklem		break;
152191783Srmacklem
153191783Srmacklem	default:
154191783Srmacklem		if ( !BER_BVISNULL( &e.e_nname ) &&
155200999Srmacklem				! access_allowed( op, &e,
156200999Srmacklem					slap_schema.si_ad_entry, NULL,
157200999Srmacklem					ACL_DISCLOSE, NULL ) )
158191783Srmacklem		{
159191783Srmacklem			rs->sr_err = LDAP_NO_SUCH_OBJECT;
160191783Srmacklem			rs->sr_text = NULL;
161191783Srmacklem		}
162216893Srmacklem		break;
163216893Srmacklem	}
164216893Srmacklem
165216893Srmacklem	send_ldap_result( op, rs );
166191783Srmacklem
167191783Srmacklem	if ( rs->sr_matched ) {
168191783Srmacklem		rs->sr_matched = NULL;
169191783Srmacklem	}
170191783Srmacklem
171191783Srmacklem	if ( rs->sr_ref ) {
172191783Srmacklem		ber_bvarray_free( rs->sr_ref );
173191783Srmacklem		rs->sr_ref = NULL;
174200999Srmacklem	}
175191783Srmacklem
176191783Srmacklem	if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
177191783Srmacklem		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
178191783Srmacklem	}
179216893Srmacklem
180191783Srmacklem	if ( !BER_BVISNULL( &e.e_nname ) ) {
181191783Srmacklem		backsql_entry_clean( op, &e );
182191783Srmacklem	}
183191783Srmacklem
184191783Srmacklem	if ( bsi.bsi_attrs != NULL ) {
185191783Srmacklem		op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
186191783Srmacklem	}
187191783Srmacklem
188191783Srmacklem	Debug(LDAP_DEBUG_TRACE,"<==backsql_compare()\n",0,0,0);
189216893Srmacklem	switch ( rs->sr_err ) {
190216893Srmacklem	case LDAP_COMPARE_TRUE:
191191783Srmacklem	case LDAP_COMPARE_FALSE:
192216893Srmacklem		return LDAP_SUCCESS;
193216893Srmacklem
194216893Srmacklem	default:
195216893Srmacklem		return rs->sr_err;
196216893Srmacklem	}
197191783Srmacklem}
198191783Srmacklem
199191783Srmacklem