2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
8 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
10 * The contents of this file are subject to the Netscape Public License
11 * Version 1.0 (the "NPL"); you may not use this file except in
12 * compliance with the NPL. You may obtain a copy of the NPL at
13 * http://www.mozilla.org/NPL/
15 * Software distributed under the NPL is distributed on an "AS IS" basis,
16 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
17 * for the specific language governing rights and limitations under the
20 * The Initial Developer of this code under the NPL is Netscape
21 * Communications Corporation. Portions created by Netscape are
22 * Copyright (C) 1998 Netscape Communications Corporation. All Rights
34 static struct ldaperror ldap_errlist
[] = {
36 { LDAP_OPERATIONS_ERROR
, 0 },
37 { LDAP_PROTOCOL_ERROR
, 0 },
38 { LDAP_TIMELIMIT_EXCEEDED
, 0 },
39 { LDAP_SIZELIMIT_EXCEEDED
, 0 },
40 { LDAP_COMPARE_FALSE
, 0 },
41 { LDAP_COMPARE_TRUE
, 0 },
42 { LDAP_STRONG_AUTH_NOT_SUPPORTED
, 0 },
43 { LDAP_STRONG_AUTH_REQUIRED
, 0 },
44 { LDAP_PARTIAL_RESULTS
, 0 },
46 { LDAP_ADMINLIMIT_EXCEEDED
, 0 },
47 { LDAP_UNAVAILABLE_CRITICAL_EXTENSION
, 0 },
48 { LDAP_CONFIDENTIALITY_REQUIRED
, 0 },
49 { LDAP_SASL_BIND_IN_PROGRESS
, 0 },
51 { LDAP_NO_SUCH_ATTRIBUTE
, 0 },
52 { LDAP_UNDEFINED_TYPE
, 0 },
53 { LDAP_INAPPROPRIATE_MATCHING
, 0 },
54 { LDAP_CONSTRAINT_VIOLATION
, 0 },
55 { LDAP_TYPE_OR_VALUE_EXISTS
, 0 },
56 { LDAP_INVALID_SYNTAX
, 0 },
58 { LDAP_NO_SUCH_OBJECT
, 0 },
59 { LDAP_ALIAS_PROBLEM
, 0 },
60 { LDAP_INVALID_DN_SYNTAX
, 0 },
62 { LDAP_ALIAS_DEREF_PROBLEM
, 0 },
64 { LDAP_INAPPROPRIATE_AUTH
, 0 },
65 { LDAP_INVALID_CREDENTIALS
, 0 },
66 { LDAP_INSUFFICIENT_ACCESS
, 0 },
68 { LDAP_UNAVAILABLE
, 0 },
69 { LDAP_UNWILLING_TO_PERFORM
, 0 },
70 { LDAP_LOOP_DETECT
, 0 },
71 { LDAP_SORT_CONTROL_MISSING
, 0 },
72 { LDAP_INDEX_RANGE_ERROR
, 0 },
74 { LDAP_NAMING_VIOLATION
, 0 },
75 { LDAP_OBJECT_CLASS_VIOLATION
, 0 },
76 { LDAP_NOT_ALLOWED_ON_NONLEAF
, 0 },
77 { LDAP_NOT_ALLOWED_ON_RDN
, 0 },
78 { LDAP_ALREADY_EXISTS
, 0 },
79 { LDAP_NO_OBJECT_CLASS_MODS
, 0 },
80 { LDAP_RESULTS_TOO_LARGE
, 0 },
81 { LDAP_AFFECTS_MULTIPLE_DSAS
, 0 },
84 { LDAP_SERVER_DOWN
, 0 },
85 { LDAP_LOCAL_ERROR
, 0 },
86 { LDAP_ENCODING_ERROR
, 0 },
87 { LDAP_DECODING_ERROR
, 0 },
89 { LDAP_AUTH_UNKNOWN
, 0 },
90 { LDAP_FILTER_ERROR
, 0 },
91 { LDAP_USER_CANCELLED
, 0 },
92 { LDAP_PARAM_ERROR
, 0 },
93 { LDAP_NO_MEMORY
, 0 },
94 { LDAP_CONNECT_ERROR
, 0 },
95 { LDAP_NOT_SUPPORTED
, 0 },
96 { LDAP_CONTROL_NOT_FOUND
, 0 },
97 { LDAP_NO_RESULTS_RETURNED
, 0 },
98 { LDAP_MORE_RESULTS_TO_RETURN
, 0 },
99 { LDAP_CLIENT_LOOP
, 0 },
100 { LDAP_REFERRAL_LIMIT_EXCEEDED
, 0 },
103 const int last_index
= sizeof(ldap_errlist
)/sizeof(ldap_errlist
[0]) - 2;
105 static struct ldaperror ldap_errlist
[] = {
106 { LDAP_SUCCESS
, "Success" },
107 { LDAP_OPERATIONS_ERROR
, "Operations error" },
108 { LDAP_PROTOCOL_ERROR
, "Protocol error" },
109 { LDAP_TIMELIMIT_EXCEEDED
, "Timelimit exceeded" },
110 { LDAP_SIZELIMIT_EXCEEDED
, "Sizelimit exceeded" },
111 { LDAP_COMPARE_FALSE
, "Compare false" },
112 { LDAP_COMPARE_TRUE
, "Compare true" },
113 { LDAP_STRONG_AUTH_NOT_SUPPORTED
, "Authentication method not supported" },
114 { LDAP_STRONG_AUTH_REQUIRED
, "Strong authentication required" },
115 { LDAP_PARTIAL_RESULTS
, "Partial results and referral received" },
116 { LDAP_REFERRAL
, "Referral received" },
117 { LDAP_ADMINLIMIT_EXCEEDED
, "Administrative limit exceeded" },
118 { LDAP_UNAVAILABLE_CRITICAL_EXTENSION
, "Unavailable critical extension" },
119 { LDAP_CONFIDENTIALITY_REQUIRED
, "Confidentiality required" },
120 { LDAP_SASL_BIND_IN_PROGRESS
, "SASL bind in progress" },
122 { LDAP_NO_SUCH_ATTRIBUTE
, "No such attribute" },
123 { LDAP_UNDEFINED_TYPE
, "Undefined attribute type" },
124 { LDAP_INAPPROPRIATE_MATCHING
, "Inappropriate matching" },
125 { LDAP_CONSTRAINT_VIOLATION
, "Constraint violation" },
126 { LDAP_TYPE_OR_VALUE_EXISTS
, "Type or value exists" },
127 { LDAP_INVALID_SYNTAX
, "Invalid syntax" },
129 { LDAP_NO_SUCH_OBJECT
, "No such object" },
130 { LDAP_ALIAS_PROBLEM
, "Alias problem" },
131 { LDAP_INVALID_DN_SYNTAX
, "Invalid DN syntax" },
132 { LDAP_IS_LEAF
, "Object is a leaf" },
133 { LDAP_ALIAS_DEREF_PROBLEM
, "Alias dereferencing problem" },
135 { LDAP_INAPPROPRIATE_AUTH
, "Inappropriate authentication" },
136 { LDAP_INVALID_CREDENTIALS
, "Invalid credentials" },
137 { LDAP_INSUFFICIENT_ACCESS
, "Insufficient access" },
138 { LDAP_BUSY
, "DSA is busy" },
139 { LDAP_UNAVAILABLE
, "DSA is unavailable" },
140 { LDAP_UNWILLING_TO_PERFORM
, "DSA is unwilling to perform" },
141 { LDAP_LOOP_DETECT
, "Loop detected" },
142 { LDAP_SORT_CONTROL_MISSING
, "Sort Control is missing" },
143 { LDAP_INDEX_RANGE_ERROR
, "Search results exceed the range specified by the offsets" },
145 { LDAP_NAMING_VIOLATION
, "Naming violation" },
146 { LDAP_OBJECT_CLASS_VIOLATION
, "Object class violation" },
147 { LDAP_NOT_ALLOWED_ON_NONLEAF
, "Operation not allowed on nonleaf" },
148 { LDAP_NOT_ALLOWED_ON_RDN
, "Operation not allowed on RDN" },
149 { LDAP_ALREADY_EXISTS
, "Already exists" },
150 { LDAP_NO_OBJECT_CLASS_MODS
, "Cannot modify object class" },
151 { LDAP_RESULTS_TOO_LARGE
, "Results too large" },
152 { LDAP_AFFECTS_MULTIPLE_DSAS
, "Affects multiple servers" },
154 { LDAP_OTHER
, "Unknown error" },
155 { LDAP_SERVER_DOWN
, "Can't contact LDAP server" },
156 { LDAP_LOCAL_ERROR
, "Local error" },
157 { LDAP_ENCODING_ERROR
, "Encoding error" },
158 { LDAP_DECODING_ERROR
, "Decoding error" },
159 { LDAP_TIMEOUT
, "Timed out" },
160 { LDAP_AUTH_UNKNOWN
, "Unknown authentication method" },
161 { LDAP_FILTER_ERROR
, "Bad search filter" },
162 { LDAP_USER_CANCELLED
, "User cancelled operation" },
163 { LDAP_PARAM_ERROR
, "Bad parameter to an ldap routine" },
164 { LDAP_NO_MEMORY
, "Out of memory" },
165 { LDAP_CONNECT_ERROR
, "Can't connect to the LDAP server" },
166 { LDAP_NOT_SUPPORTED
, "Not supported by this version of the LDAP protocol" },
167 { LDAP_CONTROL_NOT_FOUND
, "Requested LDAP control not found" },
168 { LDAP_NO_RESULTS_RETURNED
, "No results returned" },
169 { LDAP_MORE_RESULTS_TO_RETURN
, "More results to return" },
170 { LDAP_CLIENT_LOOP
, "Client detected loop" },
171 { LDAP_REFERRAL_LIMIT_EXCEEDED
, "Referral hop limit exceeded" },
177 static mutex_t err_mutex
= DEFAULTMUTEX
;
179 static void fill_ldap_errlist()
182 mutex_lock(&err_mutex
);
184 LDAPDebug(LDAP_DEBUG_TRACE
, "fill_ldap_errlist\n", 0, 0, 0 );
186 if (ldap_errlist
[last_index
].e_reason
!= NULL
) {
187 mutex_unlock(&err_mutex
);
191 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Success");
192 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Operations error");
193 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Protocol error");
194 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
195 "Timelimit exceeded");
196 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
197 "Sizelimit exceeded");
198 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Compare false");
199 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Compare true");
200 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
201 "Authentication method not supported");
202 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
203 "Strong authentication required");
204 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
205 "Partial results and referral received");
206 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
207 "Referral received");
208 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
209 "Administrative limit exceeded");
210 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
211 "Unavailable critical extension");
212 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
213 "Confidentiality required");
214 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
215 "SASL bind in progress");
217 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
218 "No such attribute");
219 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
220 "Undefined attribute type");
221 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
222 "Inappropriate matching");
223 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
224 "Constraint violation");
225 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
226 "Type or value exists");
227 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Invalid syntax");
229 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "No such object");
230 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Alias problem");
231 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
232 "Invalid DN syntax");
233 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Object is a leaf");
234 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
235 "Alias dereferencing problem");
237 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
238 "Inappropriate authentication");
239 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
240 "Invalid credentials");
241 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
242 "Insufficient access");
243 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "DSA is busy");
244 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
245 "DSA is unavailable");
246 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
247 "DSA is unwilling to perform");
248 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Loop detected");
249 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
250 "Sort Control is missing");
251 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
252 "Search results exceed the range specified by the offsets");
254 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Naming violation");
255 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
256 "Object class violation");
257 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
258 "Operation not allowed on nonleaf");
259 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
260 "Operation not allowed on RDN");
261 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Already exists");
262 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
263 "Cannot modify object class");
264 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
265 "Results too large");
266 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
267 "Affects multiple servers");
269 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Unknown error");
270 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
271 "Can't contact LDAP server");
272 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Local error");
273 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Encoding error");
274 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Decoding error");
275 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Timed out");
276 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
277 "Unknown authentication method");
278 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
279 "Bad search filter");
280 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
281 "User cancelled operation");
282 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
283 "Bad parameter to an ldap routine");
284 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
, "Out of memory");
285 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
286 "Can't connect to the LDAP server");
287 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
288 "Not supported by this version of the LDAP protocol");
289 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
290 "Requested LDAP control not found");
291 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
292 "No results returned");
293 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
294 "More results to return");
295 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
296 "Client detected loop");
297 ldap_errlist
[i
++].e_reason
= dgettext(TEXT_DOMAIN
,
298 "Referral hop limit exceeded");
299 mutex_unlock(&err_mutex
);
305 ldap_err2string( int err
)
309 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_err2string\n", 0, 0, 0 );
312 /* Make sure errlist is initialized before referencing err string */
313 if (ldap_errlist
[last_index
].e_reason
== NULL
)
317 for ( i
= 0; ldap_errlist
[i
].e_code
!= -1; i
++ ) {
318 if ( err
== ldap_errlist
[i
].e_code
)
319 return( ldap_errlist
[i
].e_reason
);
322 return( dgettext(TEXT_DOMAIN
, "Unknown error") );
327 nsldapi_safe_strerror( int e
)
331 if (( s
= strerror( e
)) == NULL
) {
332 s
= dgettext(TEXT_DOMAIN
, "unknown error");
341 ldap_perror( LDAP
*ld
, const char *s
)
344 char *matched
, *errmsg
, *separator
;
347 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_perror\n", 0, 0, 0 );
350 /* Make sure errlist is initialized before referencing err string */
351 if (ldap_errlist
[last_index
].e_reason
== NULL
)
362 sprintf( msg
, "%s%s%s", s
, separator
,
363 nsldapi_safe_strerror( errno
) );
364 ber_err_print( msg
);
368 LDAP_MUTEX_LOCK( ld
, LDAP_ERR_LOCK
);
369 err
= LDAP_GET_LDERRNO( ld
, &matched
, &errmsg
);
370 for ( i
= 0; ldap_errlist
[i
].e_code
!= -1; i
++ ) {
371 if ( err
== ldap_errlist
[i
].e_code
) {
372 sprintf( msg
, "%s%s%s", s
, separator
,
373 ldap_errlist
[i
].e_reason
);
374 ber_err_print( msg
);
375 if ( err
== LDAP_CONNECT_ERROR
) {
376 ber_err_print( " - " );
377 ber_err_print( nsldapi_safe_strerror(
378 LDAP_GET_ERRNO( ld
)));
380 ber_err_print( "\n" );
381 if ( matched
!= NULL
&& *matched
!= '\0' ) {
382 sprintf( msg
, dgettext(TEXT_DOMAIN
,
383 "%s%smatched: %s\n"),
384 s
, separator
, matched
);
385 ber_err_print( msg
);
387 if ( errmsg
!= NULL
&& *errmsg
!= '\0' ) {
388 sprintf( msg
, dgettext(TEXT_DOMAIN
,
389 "%s%sadditional info: %s\n"),
390 s
, separator
, errmsg
);
391 ber_err_print( msg
);
393 LDAP_MUTEX_UNLOCK( ld
, LDAP_ERR_LOCK
);
397 sprintf( msg
, dgettext(TEXT_DOMAIN
, "%s%sNot an LDAP errno %d\n"),
399 ber_err_print( msg
);
400 LDAP_MUTEX_UNLOCK( ld
, LDAP_ERR_LOCK
);
405 ldap_result2error( LDAP
*ld
, LDAPMessage
*r
, int freeit
)
407 int lderr_parse
, lderr
;
409 lderr_parse
= ldap_parse_result( ld
, r
, &lderr
, NULL
, NULL
, NULL
,
412 if ( lderr_parse
!= LDAP_SUCCESS
) {
413 return( lderr_parse
);
421 ldap_get_lderrno( LDAP
*ld
, char **m
, char **s
)
423 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
424 return( LDAP_PARAM_ERROR
); /* punt */
427 if ( ld
->ld_get_lderrno_fn
== NULL
) {
434 return( ld
->ld_errno
);
436 return( ld
->ld_get_lderrno_fn( m
, s
, ld
->ld_lderrno_arg
) );
442 * Note: there is no need for callers of ldap_set_lderrno() to lock the
443 * ld mutex. If applications intend to share an LDAP session handle
444 * between threads they *must* perform their own locking around the
445 * session handle or they must install a "set lderrno" thread callback
451 ldap_set_lderrno( LDAP
*ld
, int e
, char *m
, char *s
)
453 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
454 return( LDAP_PARAM_ERROR
);
457 if ( ld
->ld_set_lderrno_fn
!= NULL
) {
458 ld
->ld_set_lderrno_fn( e
, m
, s
, ld
->ld_lderrno_arg
);
460 LDAP_MUTEX_LOCK( ld
, LDAP_ERR_LOCK
);
462 if ( ld
->ld_matched
) {
463 NSLDAPI_FREE( ld
->ld_matched
);
466 if ( ld
->ld_error
) {
467 NSLDAPI_FREE( ld
->ld_error
);
470 LDAP_MUTEX_UNLOCK( ld
, LDAP_ERR_LOCK
);
473 return( LDAP_SUCCESS
);
478 * Returns an LDAP error that says whether parse succeeded. The error code
479 * from the LDAP result itself is returned in the errcodep result parameter.
480 * If any of the result params. (errcodep, matchednp, errmsgp, referralsp,
481 * or serverctrlsp) are NULL we don't return that info.
485 ldap_parse_result( LDAP
*ld
, LDAPMessage
*res
, int *errcodep
, char **matchednp
,
486 char **errmsgp
, char ***referralsp
, LDAPControl
***serverctrlsp
,
493 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_parse_result\n", 0, 0, 0 );
495 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
) ||
496 !NSLDAPI_VALID_LDAPMESSAGE_POINTER( res
)) {
497 return( LDAP_PARAM_ERROR
);
500 /* skip over entries and references to find next result in this chain */
501 for ( lm
= res
; lm
!= NULL
; lm
= lm
->lm_chain
) {
502 if ( lm
->lm_msgtype
!= LDAP_RES_SEARCH_ENTRY
&&
503 lm
->lm_msgtype
!= LDAP_RES_SEARCH_REFERENCE
) {
509 err
= LDAP_NO_RESULTS_RETURNED
;
510 LDAP_SET_LDERRNO( ld
, err
, NULL
, NULL
);
514 err
= nsldapi_parse_result( ld
, lm
->lm_msgtype
, lm
->lm_ber
, &errcode
,
515 &m
, &e
, referralsp
, serverctrlsp
);
517 if ( err
== LDAP_SUCCESS
) {
518 if ( errcodep
!= NULL
) {
521 if ( matchednp
!= NULL
) {
522 *matchednp
= nsldapi_strdup( m
);
524 if ( errmsgp
!= NULL
) {
525 *errmsgp
= nsldapi_strdup( e
);
529 * if there are more result messages in the chain, arrange to
530 * return the special LDAP_MORE_RESULTS_TO_RETURN "error" code.
532 for ( lm
= lm
->lm_chain
; lm
!= NULL
; lm
= lm
->lm_chain
) {
533 if ( lm
->lm_msgtype
!= LDAP_RES_SEARCH_ENTRY
&&
534 lm
->lm_msgtype
!= LDAP_RES_SEARCH_REFERENCE
) {
535 err
= LDAP_MORE_RESULTS_TO_RETURN
;
547 LDAP_SET_LDERRNO( ld
, ( err
== LDAP_SUCCESS
) ? errcode
: err
, m
, e
);
554 * returns an LDAP error code indicating success or failure of parsing
555 * does NOT set any error information inside "ld"
558 nsldapi_parse_result( LDAP
*ld
, int msgtype
, BerElement
*rber
, int *errcodep
,
559 char **matchednp
, char **errmsgp
, char ***referralsp
,
560 LDAPControl
***serverctrlsp
)
564 int berrc
, err
, errcode
;
569 * Parse the result message. LDAPv3 result messages look like this:
571 * LDAPResult ::= SEQUENCE {
572 * resultCode ENUMERATED { ... },
574 * errorMessage LDAPString,
575 * referral [3] Referral OPTIONAL
576 * opSpecificStuff OPTIONAL
579 * all wrapped up in an LDAPMessage sequence which looks like this:
580 * LDAPMessage ::= SEQUENCE {
581 * messageID MessageID,
582 * LDAPResult CHOICE { ... }, // message type
583 * controls [0] Controls OPTIONAL
586 * LDAPv2 messages don't include referrals or controls.
587 * LDAPv1 messages don't include matchedDN, referrals, or controls.
589 * ldap_result() pulls out the message id, so by the time a result
590 * message gets here we are sitting at the start of the LDAPResult.
593 err
= LDAP_SUCCESS
; /* optimistic */
595 if ( matchednp
!= NULL
) {
598 if ( errmsgp
!= NULL
) {
601 if ( referralsp
!= NULL
) {
604 if ( serverctrlsp
!= NULL
) {
605 *serverctrlsp
= NULL
;
607 ber
= *rber
; /* struct copy */
609 if ( NSLDAPI_LDAP_VERSION( ld
) < LDAP_VERSION2
) {
610 berrc
= ber_scanf( &ber
, "{ia}", &along
, &e
);
611 errcode
= (int)along
; /* XXX lossy cast */
613 if (( berrc
= ber_scanf( &ber
, "{iaa", &along
, &m
, &e
))
615 errcode
= (int)along
; /* XXX lossy cast */
616 /* check for optional referrals */
617 if ( ber_peek_tag( &ber
, &len
) == LDAP_TAG_REFERRAL
) {
618 if ( referralsp
== NULL
) {
620 berrc
= ber_scanf( &ber
, "x" );
622 /* suck out referrals */
623 berrc
= ber_scanf( &ber
, "v",
626 } else if ( referralsp
!= NULL
) {
631 if ( berrc
!= LBER_ERROR
) {
633 * skip past optional operation-specific elements:
634 * bind results - serverSASLcreds
635 * extendedop results - OID plus value
637 if ( msgtype
== LDAP_RES_BIND
) {
638 if ( ber_peek_tag( &ber
, &len
) ==
639 LDAP_TAG_SASL_RES_CREDS
) {
640 berrc
= ber_scanf( &ber
, "x" );
642 } else if ( msgtype
== LDAP_RES_EXTENDED
) {
643 if ( ber_peek_tag( &ber
, &len
) ==
644 LDAP_TAG_EXOP_RES_OID
) {
645 berrc
= ber_scanf( &ber
, "x" );
647 if ( berrc
!= LBER_ERROR
&&
648 ber_peek_tag( &ber
, &len
) ==
649 LDAP_TAG_EXOP_RES_VALUE
) {
650 berrc
= ber_scanf( &ber
, "x" );
655 /* pull out controls (if requested and any are present) */
656 if ( berrc
!= LBER_ERROR
&& serverctrlsp
!= NULL
&&
657 ( berrc
= ber_scanf( &ber
, "}" )) != LBER_ERROR
) {
658 err
= nsldapi_get_controls( &ber
, serverctrlsp
);
662 if ( berrc
== LBER_ERROR
&& err
== LDAP_SUCCESS
) {
663 err
= LDAP_DECODING_ERROR
;
666 if ( errcodep
!= NULL
) {
669 if ( matchednp
!= NULL
) {
671 } else if ( m
!= NULL
) {
674 if ( errmsgp
!= NULL
) {
676 } else if ( e
!= NULL
) {