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