Home | History | Annotate | Line # | Download | only in libldap
      1 /*	$NetBSD: compare.c,v 1.4 2025/09/05 21:16:21 christos Exp $	*/
      2 
      3 /* $OpenLDAP$ */
      4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      5  *
      6  * Copyright 1998-2024 The OpenLDAP Foundation.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted only as authorized by the OpenLDAP
     11  * Public License.
     12  *
     13  * A copy of this license is available in the file LICENSE in the
     14  * top-level directory of the distribution or, alternatively, at
     15  * <http://www.OpenLDAP.org/license.html>.
     16  */
     17 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
     18  * All rights reserved.
     19  */
     20 
     21 #include <sys/cdefs.h>
     22 __RCSID("$NetBSD: compare.c,v 1.4 2025/09/05 21:16:21 christos Exp $");
     23 
     24 #include "portable.h"
     25 
     26 #include <stdio.h>
     27 
     28 #include <ac/socket.h>
     29 #include <ac/string.h>
     30 #include <ac/time.h>
     31 
     32 #include "ldap-int.h"
     33 #include "ldap_log.h"
     34 
     35 /* The compare request looks like this:
     36  *	CompareRequest ::= SEQUENCE {
     37  *		entry	DistinguishedName,
     38  *		ava	SEQUENCE {
     39  *			type	AttributeType,
     40  *			value	AttributeValue
     41  *		}
     42  *	}
     43  */
     44 
     45 BerElement *
     46 ldap_build_compare_req(
     47 	LDAP *ld,
     48 	LDAP_CONST char *dn,
     49 	LDAP_CONST char *attr,
     50 	struct berval *bvalue,
     51 	LDAPControl **sctrls,
     52 	LDAPControl **cctrls,
     53 	int	*msgidp )
     54 {
     55 	BerElement	*ber;
     56 	int rc;
     57 
     58 	/* create a message to send */
     59 	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
     60 		return( NULL );
     61 	}
     62 
     63 	LDAP_NEXT_MSGID(ld, *msgidp);
     64 	rc = ber_printf( ber, "{it{s{sON}N}", /* '}' */
     65 		*msgidp,
     66 		LDAP_REQ_COMPARE, dn, attr, bvalue );
     67 	if ( rc == -1 )
     68 	{
     69 		ld->ld_errno = LDAP_ENCODING_ERROR;
     70 		ber_free( ber, 1 );
     71 		return( NULL );
     72 	}
     73 
     74 	/* Put Server Controls */
     75 	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
     76 		ber_free( ber, 1 );
     77 		return( NULL );
     78 	}
     79 
     80 	if( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
     81 		ld->ld_errno = LDAP_ENCODING_ERROR;
     82 		ber_free( ber, 1 );
     83 		return( NULL );
     84 	}
     85 
     86 	return( ber );
     87 }
     88 
     89 /*
     90  * ldap_compare_ext - perform an ldap extended compare operation.  The dn
     91  * of the entry to compare to and the attribute and value to compare (in
     92  * attr and value) are supplied.  The msgid of the response is returned.
     93  *
     94  * Example:
     95  *	struct berval bvalue = { "secret", sizeof("secret")-1 };
     96  *	rc = ldap_compare( ld, "c=us@cn=bob",
     97  *		"userPassword", &bvalue,
     98  *		sctrl, cctrl, &msgid )
     99  */
    100 int
    101 ldap_compare_ext(
    102 	LDAP *ld,
    103 	LDAP_CONST char *dn,
    104 	LDAP_CONST char *attr,
    105 	struct berval *bvalue,
    106 	LDAPControl **sctrls,
    107 	LDAPControl **cctrls,
    108 	int	*msgidp )
    109 {
    110 	int rc;
    111 	BerElement	*ber;
    112 	ber_int_t	id;
    113 
    114 	Debug0( LDAP_DEBUG_TRACE, "ldap_compare\n" );
    115 
    116 	assert( ld != NULL );
    117 	assert( LDAP_VALID( ld ) );
    118 	assert( dn != NULL );
    119 	assert( attr != NULL );
    120 	assert( msgidp != NULL );
    121 
    122 	/* check client controls */
    123 	rc = ldap_int_client_controls( ld, cctrls );
    124 	if( rc != LDAP_SUCCESS ) return rc;
    125 
    126 	ber = ldap_build_compare_req(
    127 		ld, dn, attr, bvalue, sctrls, cctrls, &id );
    128 	if( !ber )
    129 		return ld->ld_errno;
    130 
    131 	/* send the message */
    132 	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_COMPARE, dn, ber, id );
    133 	return ( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
    134 }
    135 
    136 /*
    137  * ldap_compare_ext - perform an ldap extended compare operation.  The dn
    138  * of the entry to compare to and the attribute and value to compare (in
    139  * attr and value) are supplied.  The msgid of the response is returned.
    140  *
    141  * Example:
    142  *	msgid = ldap_compare( ld, "c=us@cn=bob", "userPassword", "secret" )
    143  */
    144 int
    145 ldap_compare(
    146 	LDAP *ld,
    147 	LDAP_CONST char *dn,
    148 	LDAP_CONST char *attr,
    149 	LDAP_CONST char *value )
    150 {
    151 	int msgid;
    152 	struct berval bvalue;
    153 
    154 	assert( value != NULL );
    155 
    156 	bvalue.bv_val = (char *) value;
    157 	bvalue.bv_len = (value == NULL) ? 0 : strlen( value );
    158 
    159 	return ldap_compare_ext( ld, dn, attr, &bvalue, NULL, NULL, &msgid ) == LDAP_SUCCESS
    160 		? msgid : -1;
    161 }
    162 
    163 int
    164 ldap_compare_ext_s(
    165 	LDAP *ld,
    166 	LDAP_CONST char *dn,
    167 	LDAP_CONST char *attr,
    168 	struct berval *bvalue,
    169 	LDAPControl **sctrl,
    170 	LDAPControl **cctrl )
    171 {
    172 	int		rc;
    173 	int		msgid;
    174 	LDAPMessage	*res;
    175 
    176 	rc = ldap_compare_ext( ld, dn, attr, bvalue, sctrl, cctrl, &msgid );
    177 
    178 	if (  rc != LDAP_SUCCESS )
    179 		return( rc );
    180 
    181 	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
    182 		return( ld->ld_errno );
    183 
    184 	return( ldap_result2error( ld, res, 1 ) );
    185 }
    186 
    187 int
    188 ldap_compare_s(
    189 	LDAP *ld,
    190 	LDAP_CONST char *dn,
    191 	LDAP_CONST char *attr,
    192 	LDAP_CONST char *value )
    193 {
    194 	struct berval bvalue;
    195 
    196 	assert( value != NULL );
    197 
    198 	bvalue.bv_val = (char *) value;
    199 	bvalue.bv_len = (value == NULL) ? 0 : strlen( value );
    200 
    201 	return ldap_compare_ext_s( ld, dn, attr, &bvalue, NULL, NULL );
    202 }
    203