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