1 /* $NetBSD: compare.c,v 1.3 2021/08/14 16:14:55 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2021 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.3 2021/08/14 16:14:55 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 *
ldap_build_compare_req(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * attr,struct berval * bvalue,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)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
ldap_compare_ext(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * attr,struct berval * bvalue,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)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
ldap_compare(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * attr,LDAP_CONST char * value)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
ldap_compare_ext_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * attr,struct berval * bvalue,LDAPControl ** sctrl,LDAPControl ** cctrl)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
ldap_compare_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * attr,LDAP_CONST char * value)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