summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/compare.c
diff options
context:
space:
mode:
authorcvsadm <cvsadm>2005-01-21 00:44:34 +0000
committercvsadm <cvsadm>2005-01-21 00:44:34 +0000
commitb2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch)
treecf58939393a9032182c4fbc4441164a9456e82f8 /ldap/servers/slapd/compare.c
downloadds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'ldap/servers/slapd/compare.c')
-rw-r--r--ldap/servers/slapd/compare.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c
new file mode 100644
index 00000000..8030871b
--- /dev/null
+++ b/ldap/servers/slapd/compare.c
@@ -0,0 +1,153 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ * Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#endif
+#include "slap.h"
+#include "pratom.h"
+
+
+void
+do_compare( Slapi_PBlock *pb )
+{
+ BerElement *ber = pb->pb_op->o_ber;
+ char *dn;
+ struct ava ava;
+ Slapi_Backend *be = NULL;
+ int err;
+ char ebuf[ BUFSIZ ];
+ Slapi_DN sdn;
+ Slapi_Entry *referral;
+ char errorbuf[BUFSIZ];
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 );
+
+ /* count the compare request */
+ PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsCompareOps);
+
+ /*
+ * Parse the compare request. It looks like this:
+ *
+ * CompareRequest := [APPLICATION 14] SEQUENCE {
+ * entry DistinguishedName,
+ * ava SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue
+ * }
+ * }
+ */
+
+
+ if ( ber_scanf( ber, "{a{ao}}", &dn, &ava.ava_type,
+ &ava.ava_value ) == LBER_ERROR ) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "ber_scanf failed (op=Compare; params=DN,Type,Value)\n",
+ 0, 0, 0 );
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
+ NULL );
+ return;
+ }
+ /*
+ * in LDAPv3 there can be optional control extensions on
+ * the end of an LDAPMessage. we need to read them in and
+ * pass them to the backend.
+ */
+ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) {
+ send_ldap_result( pb, err, NULL, NULL, 0, NULL );
+ goto free_and_return;
+ }
+ slapi_sdn_init_dn_passin(&sdn,dn);
+
+ /* target spec is used to decide which plugins are applicable for the operation */
+ operation_set_target_spec (pb->pb_op, &sdn);
+
+ LDAPDebug( LDAP_DEBUG_ARGS, "do_compare: dn (%s) attr (%s)\n",
+ dn, ava.ava_type, 0 );
+
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%d op=%d CMP dn=\"%s\" attr=\"%s\"\n",
+ pb->pb_conn->c_connid, pb->pb_op->o_opid,
+ escape_string( dn, ebuf ), ava.ava_type );
+
+ /*
+ * We could be serving multiple database backends. Select the
+ * appropriate one.
+ */
+ if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf)) != LDAP_SUCCESS) {
+ send_ldap_result(pb, err, NULL, errorbuf, 0, NULL);
+ be = NULL;
+ goto free_and_return;
+ }
+
+ if (referral)
+ {
+ int managedsait;
+
+ slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
+ if (managedsait)
+ {
+ send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+ "cannot compare referral", 0, NULL);
+ slapi_entry_free(referral);
+ goto free_and_return;
+ }
+
+ send_referrals_from_entry(pb,referral);
+ slapi_entry_free(referral);
+ goto free_and_return;
+ }
+
+ if ( be->be_compare != NULL ) {
+ int isroot;
+
+ slapi_pblock_set( pb, SLAPI_BACKEND, be );
+ isroot = pb->pb_op->o_isroot;
+
+ slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
+ slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void*)slapi_sdn_get_ndn(&sdn) );
+ slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, ava.ava_type);
+ slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, &ava.ava_value );
+ /*
+ * call the pre-compare plugins. if they succeed, call
+ * the backend compare function. then call the
+ * post-compare plugins.
+ */
+ if ( plugin_call_plugins( pb,
+ SLAPI_PLUGIN_PRE_COMPARE_FN ) == 0 ) {
+ int rc;
+
+ slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database );
+ set_db_default_result_handlers(pb);
+ rc = (*be->be_compare)( pb );
+
+ slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc );
+ plugin_call_plugins( pb, SLAPI_PLUGIN_POST_COMPARE_FN );
+ }
+ } else {
+ send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+ "Function not implemented", 0, NULL );
+ }
+
+free_and_return:;
+ if (be)
+ slapi_be_Unlock(be);
+ slapi_sdn_done(&sdn);
+ ava_done( &ava );
+}