1 /*
2 * The contents of this file are subject to the Netscape Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/NPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is Mozilla Communicator client code, released
13 * March 31, 1998.
14 *
15 * The Initial Developer of the Original Code is Netscape
16 * Communications Corporation. Portions created by Netscape are
17 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
18 * Rights Reserved.
19 *
20 * Contributor(s):
21 */
22 /*
23 * Copyright (c) 1990 Regents of the University of Michigan.
24 * All rights reserved.
25 */
26 /*
27 * compare.c
28 */
29
30 #if 0
31 #ifndef lint
32 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
33 #endif
34 #endif
35
36 #include "ldap-int.h"
37
38 /*
39 * ldap_compare - perform an ldap compare operation. The dn
40 * of the entry to compare to and the attribute and value to compare (in
41 * attr and value) are supplied. The msgid of the response is returned.
42 *
43 * Example:
44 * ldap_compare( ld, "c=us@cn=bob", "userPassword", "secret" )
45 */
46 int
47 LDAP_CALL
ldap_compare(LDAP * ld,const char * dn,const char * attr,const char * value)48 ldap_compare( LDAP *ld, const char *dn, const char *attr, const char *value )
49 {
50 int msgid;
51 struct berval bv;
52
53 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );
54
55 bv.bv_val = (char *)value;
56 bv.bv_len = ( value == NULL ) ? 0 : strlen( value );
57
58 if ( ldap_compare_ext( ld, dn, attr, &bv, NULL, NULL, &msgid )
59 == LDAP_SUCCESS ) {
60 return( msgid );
61 } else {
62 return( -1 ); /* error is in ld handle */
63 }
64 }
65
66 int
67 LDAP_CALL
ldap_compare_ext(LDAP * ld,const char * dn,const char * attr,const struct berval * bvalue,LDAPControl ** serverctrls,LDAPControl ** clientctrls,int * msgidp)68 ldap_compare_ext( LDAP *ld, const char *dn, const char *attr,
69 const struct berval *bvalue, LDAPControl **serverctrls,
70 LDAPControl **clientctrls, int *msgidp )
71 {
72 BerElement *ber;
73 int rc, lderr;
74
75 /* The compare request looks like this:
76 * CompareRequest ::= SEQUENCE {
77 * entry DistinguishedName,
78 * ava SEQUENCE {
79 * type AttributeType,
80 * value AttributeValue
81 * }
82 * }
83 * and must be wrapped in an LDAPMessage.
84 */
85
86 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_compare_ext\n", 0, 0, 0 );
87
88 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
89 return( LDAP_PARAM_ERROR );
90 }
91 if ( attr == NULL || bvalue == NULL || bvalue->bv_len == 0
92 || msgidp == NULL ) {
93 lderr = LDAP_PARAM_ERROR;
94 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
95 return( lderr );
96 }
97
98 if ( dn == NULL ) {
99 dn = "";
100 }
101
102 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
103 *msgidp = ++ld->ld_msgid;
104 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
105
106 /* check the cache */
107 if ( ld->ld_cache_on && ld->ld_cache_compare != NULL ) {
108 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
109 if ( (rc = (ld->ld_cache_compare)( ld, *msgidp,
110 LDAP_REQ_COMPARE, dn, attr, bvalue )) != 0 ) {
111 *msgidp = rc;
112 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
113 return( LDAP_SUCCESS );
114 }
115 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
116 }
117
118 /* create a message to send */
119 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
120 != LDAP_SUCCESS ) {
121 return( lderr );
122 }
123
124 if ( ber_printf( ber, "{it{s{so}}", *msgidp, LDAP_REQ_COMPARE, dn,
125 attr, bvalue->bv_val, (int)bvalue->bv_len /* XXX lossy cast */ )
126 == -1 ) {
127 lderr = LDAP_ENCODING_ERROR;
128 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
129 ber_free( ber, 1 );
130 return( lderr );
131 }
132
133 if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
134 != LDAP_SUCCESS ) {
135 ber_free( ber, 1 );
136 return( lderr );
137 }
138
139 /* send the message */
140 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_COMPARE,
141 (char *)dn, ber );
142 *msgidp = rc;
143 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
144 }
145
146 int
147 LDAP_CALL
ldap_compare_s(LDAP * ld,const char * dn,const char * attr,const char * value)148 ldap_compare_s( LDAP *ld, const char *dn, const char *attr,
149 const char *value )
150 {
151 struct berval bv;
152
153 bv.bv_val = (char *)value;
154 bv.bv_len = ( value == NULL ) ? 0 : strlen( value );
155
156 return( ldap_compare_ext_s( ld, dn, attr, &bv, NULL, NULL ));
157 }
158
159 int
160 LDAP_CALL
ldap_compare_ext_s(LDAP * ld,const char * dn,const char * attr,const struct berval * bvalue,LDAPControl ** serverctrls,LDAPControl ** clientctrls)161 ldap_compare_ext_s( LDAP *ld, const char *dn, const char *attr,
162 const struct berval *bvalue, LDAPControl **serverctrls,
163 LDAPControl **clientctrls )
164 {
165 int err, msgid;
166 LDAPMessage *res;
167
168 if (( err = ldap_compare_ext( ld, dn, attr, bvalue, serverctrls,
169 clientctrls, &msgid )) != LDAP_SUCCESS ) {
170 return( err );
171 }
172
173 if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res )
174 == -1 ) {
175 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
176 }
177
178 return( ldap_result2error( ld, res, 1 ) );
179 }
180