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