xref: /onnv-gate/usr/src/lib/libldap5/sources/ldap/common/error.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate 
6*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
9*0Sstevel@tonic-gate  *
10*0Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public License
11*0Sstevel@tonic-gate  * Version 1.0 (the "NPL"); you may not use this file except in
12*0Sstevel@tonic-gate  * compliance with the NPL.  You may obtain a copy of the NPL at
13*0Sstevel@tonic-gate  * http://www.mozilla.org/NPL/
14*0Sstevel@tonic-gate  *
15*0Sstevel@tonic-gate  * Software distributed under the NPL is distributed on an "AS IS" basis,
16*0Sstevel@tonic-gate  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
17*0Sstevel@tonic-gate  * for the specific language governing rights and limitations under the
18*0Sstevel@tonic-gate  * NPL.
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * The Initial Developer of this code under the NPL is Netscape
21*0Sstevel@tonic-gate  * Communications Corporation.  Portions created by Netscape are
22*0Sstevel@tonic-gate  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
23*0Sstevel@tonic-gate  * Reserved.
24*0Sstevel@tonic-gate  */
25*0Sstevel@tonic-gate #include "ldap-int.h"
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate struct ldaperror {
28*0Sstevel@tonic-gate 	int	e_code;
29*0Sstevel@tonic-gate 	char	*e_reason;
30*0Sstevel@tonic-gate };
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
33*0Sstevel@tonic-gate #include <synch.h>
34*0Sstevel@tonic-gate static struct ldaperror ldap_errlist[] = {
35*0Sstevel@tonic-gate 	{ LDAP_SUCCESS, 			0 },
36*0Sstevel@tonic-gate 	{ LDAP_OPERATIONS_ERROR, 		0 },
37*0Sstevel@tonic-gate 	{ LDAP_PROTOCOL_ERROR, 			0 },
38*0Sstevel@tonic-gate 	{ LDAP_TIMELIMIT_EXCEEDED,		0 },
39*0Sstevel@tonic-gate 	{ LDAP_SIZELIMIT_EXCEEDED, 		0 },
40*0Sstevel@tonic-gate 	{ LDAP_COMPARE_FALSE, 			0 },
41*0Sstevel@tonic-gate 	{ LDAP_COMPARE_TRUE, 			0 },
42*0Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_NOT_SUPPORTED,	0 },
43*0Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_REQUIRED, 		0 },
44*0Sstevel@tonic-gate 	{ LDAP_PARTIAL_RESULTS, 		0 },
45*0Sstevel@tonic-gate 	{ LDAP_REFERRAL, 			0 },
46*0Sstevel@tonic-gate 	{ LDAP_ADMINLIMIT_EXCEEDED,		0 },
47*0Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE_CRITICAL_EXTENSION,	0 },
48*0Sstevel@tonic-gate 	{ LDAP_CONFIDENTIALITY_REQUIRED,	0 },
49*0Sstevel@tonic-gate 	{ LDAP_SASL_BIND_IN_PROGRESS,		0 },
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate 	{ LDAP_NO_SUCH_ATTRIBUTE, 		0 },
52*0Sstevel@tonic-gate 	{ LDAP_UNDEFINED_TYPE, 			0 },
53*0Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_MATCHING, 		0 },
54*0Sstevel@tonic-gate 	{ LDAP_CONSTRAINT_VIOLATION, 		0 },
55*0Sstevel@tonic-gate 	{ LDAP_TYPE_OR_VALUE_EXISTS, 		0 },
56*0Sstevel@tonic-gate 	{ LDAP_INVALID_SYNTAX, 			0 },
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate 	{ LDAP_NO_SUCH_OBJECT, 			0 },
59*0Sstevel@tonic-gate 	{ LDAP_ALIAS_PROBLEM, 			0 },
60*0Sstevel@tonic-gate 	{ LDAP_INVALID_DN_SYNTAX,		0 },
61*0Sstevel@tonic-gate 	{ LDAP_IS_LEAF, 			0 },
62*0Sstevel@tonic-gate 	{ LDAP_ALIAS_DEREF_PROBLEM, 		0 },
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_AUTH, 		0 },
65*0Sstevel@tonic-gate 	{ LDAP_INVALID_CREDENTIALS, 		0 },
66*0Sstevel@tonic-gate 	{ LDAP_INSUFFICIENT_ACCESS, 		0 },
67*0Sstevel@tonic-gate 	{ LDAP_BUSY, 				0 },
68*0Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE, 			0 },
69*0Sstevel@tonic-gate 	{ LDAP_UNWILLING_TO_PERFORM, 		0 },
70*0Sstevel@tonic-gate 	{ LDAP_LOOP_DETECT, 			0 },
71*0Sstevel@tonic-gate 	{ LDAP_SORT_CONTROL_MISSING,    	0 },
72*0Sstevel@tonic-gate 	{ LDAP_INDEX_RANGE_ERROR,		0 },
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	{ LDAP_NAMING_VIOLATION, 		0 },
75*0Sstevel@tonic-gate 	{ LDAP_OBJECT_CLASS_VIOLATION, 		0 },
76*0Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_NONLEAF, 		0 },
77*0Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_RDN, 		0 },
78*0Sstevel@tonic-gate 	{ LDAP_ALREADY_EXISTS, 			0 },
79*0Sstevel@tonic-gate 	{ LDAP_NO_OBJECT_CLASS_MODS, 		0 },
80*0Sstevel@tonic-gate 	{ LDAP_RESULTS_TOO_LARGE,		0 },
81*0Sstevel@tonic-gate 	{ LDAP_AFFECTS_MULTIPLE_DSAS,		0 },
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 	{ LDAP_OTHER, 				0 },
84*0Sstevel@tonic-gate 	{ LDAP_SERVER_DOWN,			0 },
85*0Sstevel@tonic-gate 	{ LDAP_LOCAL_ERROR,			0 },
86*0Sstevel@tonic-gate 	{ LDAP_ENCODING_ERROR,			0 },
87*0Sstevel@tonic-gate 	{ LDAP_DECODING_ERROR,			0 },
88*0Sstevel@tonic-gate 	{ LDAP_TIMEOUT,				0 },
89*0Sstevel@tonic-gate 	{ LDAP_AUTH_UNKNOWN,			0 },
90*0Sstevel@tonic-gate 	{ LDAP_FILTER_ERROR,			0 },
91*0Sstevel@tonic-gate 	{ LDAP_USER_CANCELLED,			0 },
92*0Sstevel@tonic-gate 	{ LDAP_PARAM_ERROR,			0 },
93*0Sstevel@tonic-gate 	{ LDAP_NO_MEMORY,			0 },
94*0Sstevel@tonic-gate 	{ LDAP_CONNECT_ERROR,			0 },
95*0Sstevel@tonic-gate 	{ LDAP_NOT_SUPPORTED,			0 },
96*0Sstevel@tonic-gate 	{ LDAP_CONTROL_NOT_FOUND,		0 },
97*0Sstevel@tonic-gate 	{ LDAP_NO_RESULTS_RETURNED,		0 },
98*0Sstevel@tonic-gate 	{ LDAP_MORE_RESULTS_TO_RETURN,		0 },
99*0Sstevel@tonic-gate 	{ LDAP_CLIENT_LOOP,			0 },
100*0Sstevel@tonic-gate 	{ LDAP_REFERRAL_LIMIT_EXCEEDED,		0 },
101*0Sstevel@tonic-gate 	{ -1, 0 }
102*0Sstevel@tonic-gate };
103*0Sstevel@tonic-gate const int last_index = sizeof(ldap_errlist)/sizeof(ldap_errlist[0]) - 2;
104*0Sstevel@tonic-gate #else
105*0Sstevel@tonic-gate static struct ldaperror ldap_errlist[] = {
106*0Sstevel@tonic-gate 	{ LDAP_SUCCESS, 			"Success" },
107*0Sstevel@tonic-gate 	{ LDAP_OPERATIONS_ERROR, 		"Operations error" },
108*0Sstevel@tonic-gate 	{ LDAP_PROTOCOL_ERROR, 			"Protocol error" },
109*0Sstevel@tonic-gate 	{ LDAP_TIMELIMIT_EXCEEDED,		"Timelimit exceeded" },
110*0Sstevel@tonic-gate 	{ LDAP_SIZELIMIT_EXCEEDED, 		"Sizelimit exceeded" },
111*0Sstevel@tonic-gate 	{ LDAP_COMPARE_FALSE, 			"Compare false" },
112*0Sstevel@tonic-gate 	{ LDAP_COMPARE_TRUE, 			"Compare true" },
113*0Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_NOT_SUPPORTED,	"Authentication method not supported" },
114*0Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_REQUIRED, 		"Strong authentication required" },
115*0Sstevel@tonic-gate 	{ LDAP_PARTIAL_RESULTS, 		"Partial results and referral received" },
116*0Sstevel@tonic-gate 	{ LDAP_REFERRAL, 			"Referral received" },
117*0Sstevel@tonic-gate 	{ LDAP_ADMINLIMIT_EXCEEDED,		"Administrative limit exceeded" },
118*0Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE_CRITICAL_EXTENSION,	"Unavailable critical extension" },
119*0Sstevel@tonic-gate 	{ LDAP_CONFIDENTIALITY_REQUIRED,	"Confidentiality required" },
120*0Sstevel@tonic-gate 	{ LDAP_SASL_BIND_IN_PROGRESS,		"SASL bind in progress" },
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	{ LDAP_NO_SUCH_ATTRIBUTE, 		"No such attribute" },
123*0Sstevel@tonic-gate 	{ LDAP_UNDEFINED_TYPE, 			"Undefined attribute type" },
124*0Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_MATCHING, 		"Inappropriate matching" },
125*0Sstevel@tonic-gate 	{ LDAP_CONSTRAINT_VIOLATION, 		"Constraint violation" },
126*0Sstevel@tonic-gate 	{ LDAP_TYPE_OR_VALUE_EXISTS, 		"Type or value exists" },
127*0Sstevel@tonic-gate 	{ LDAP_INVALID_SYNTAX, 			"Invalid syntax" },
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 	{ LDAP_NO_SUCH_OBJECT, 			"No such object" },
130*0Sstevel@tonic-gate 	{ LDAP_ALIAS_PROBLEM, 			"Alias problem" },
131*0Sstevel@tonic-gate 	{ LDAP_INVALID_DN_SYNTAX,		"Invalid DN syntax" },
132*0Sstevel@tonic-gate 	{ LDAP_IS_LEAF, 			"Object is a leaf" },
133*0Sstevel@tonic-gate 	{ LDAP_ALIAS_DEREF_PROBLEM, 		"Alias dereferencing problem" },
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_AUTH, 		"Inappropriate authentication" },
136*0Sstevel@tonic-gate 	{ LDAP_INVALID_CREDENTIALS, 		"Invalid credentials" },
137*0Sstevel@tonic-gate 	{ LDAP_INSUFFICIENT_ACCESS, 		"Insufficient access" },
138*0Sstevel@tonic-gate 	{ LDAP_BUSY, 				"DSA is busy" },
139*0Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE, 			"DSA is unavailable" },
140*0Sstevel@tonic-gate 	{ LDAP_UNWILLING_TO_PERFORM, 		"DSA is unwilling to perform" },
141*0Sstevel@tonic-gate 	{ LDAP_LOOP_DETECT, 			"Loop detected" },
142*0Sstevel@tonic-gate     { LDAP_SORT_CONTROL_MISSING,    "Sort Control is missing"  },
143*0Sstevel@tonic-gate     { LDAP_INDEX_RANGE_ERROR,              "Search results exceed the range specified by the offsets" },
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate     { LDAP_NAMING_VIOLATION, 		"Naming violation" },
146*0Sstevel@tonic-gate 	{ LDAP_OBJECT_CLASS_VIOLATION, 		"Object class violation" },
147*0Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_NONLEAF, 		"Operation not allowed on nonleaf" },
148*0Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_RDN, 		"Operation not allowed on RDN" },
149*0Sstevel@tonic-gate 	{ LDAP_ALREADY_EXISTS, 			"Already exists" },
150*0Sstevel@tonic-gate 	{ LDAP_NO_OBJECT_CLASS_MODS, 		"Cannot modify object class" },
151*0Sstevel@tonic-gate 	{ LDAP_RESULTS_TOO_LARGE,		"Results too large" },
152*0Sstevel@tonic-gate 	{ LDAP_AFFECTS_MULTIPLE_DSAS,		"Affects multiple servers" },
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate 	{ LDAP_OTHER, 				"Unknown error" },
155*0Sstevel@tonic-gate 	{ LDAP_SERVER_DOWN,			"Can't contact LDAP server" },
156*0Sstevel@tonic-gate 	{ LDAP_LOCAL_ERROR,			"Local error" },
157*0Sstevel@tonic-gate 	{ LDAP_ENCODING_ERROR,			"Encoding error" },
158*0Sstevel@tonic-gate 	{ LDAP_DECODING_ERROR,			"Decoding error" },
159*0Sstevel@tonic-gate 	{ LDAP_TIMEOUT,				"Timed out" },
160*0Sstevel@tonic-gate 	{ LDAP_AUTH_UNKNOWN,			"Unknown authentication method" },
161*0Sstevel@tonic-gate 	{ LDAP_FILTER_ERROR,			"Bad search filter" },
162*0Sstevel@tonic-gate 	{ LDAP_USER_CANCELLED,			"User cancelled operation" },
163*0Sstevel@tonic-gate 	{ LDAP_PARAM_ERROR,			"Bad parameter to an ldap routine" },
164*0Sstevel@tonic-gate 	{ LDAP_NO_MEMORY,			"Out of memory" },
165*0Sstevel@tonic-gate 	{ LDAP_CONNECT_ERROR,			"Can't connect to the LDAP server" },
166*0Sstevel@tonic-gate 	{ LDAP_NOT_SUPPORTED,			"Not supported by this version of the LDAP protocol" },
167*0Sstevel@tonic-gate 	{ LDAP_CONTROL_NOT_FOUND,		"Requested LDAP control not found" },
168*0Sstevel@tonic-gate 	{ LDAP_NO_RESULTS_RETURNED,		"No results returned" },
169*0Sstevel@tonic-gate 	{ LDAP_MORE_RESULTS_TO_RETURN,		"More results to return" },
170*0Sstevel@tonic-gate 	{ LDAP_CLIENT_LOOP,			"Client detected loop" },
171*0Sstevel@tonic-gate 	{ LDAP_REFERRAL_LIMIT_EXCEEDED,		"Referral hop limit exceeded" },
172*0Sstevel@tonic-gate 	{ -1, 0 }
173*0Sstevel@tonic-gate };
174*0Sstevel@tonic-gate #endif
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
177*0Sstevel@tonic-gate static mutex_t		err_mutex = DEFAULTMUTEX;
178*0Sstevel@tonic-gate 
fill_ldap_errlist()179*0Sstevel@tonic-gate static void fill_ldap_errlist()
180*0Sstevel@tonic-gate {
181*0Sstevel@tonic-gate 	int i=0;
182*0Sstevel@tonic-gate 	mutex_lock(&err_mutex);
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate 	LDAPDebug(LDAP_DEBUG_TRACE, "fill_ldap_errlist\n", 0, 0, 0 );
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason != NULL) {
187*0Sstevel@tonic-gate 		mutex_unlock(&err_mutex);
188*0Sstevel@tonic-gate 		return;
189*0Sstevel@tonic-gate 	}
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Success");
192*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Operations error");
193*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Protocol error");
194*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
195*0Sstevel@tonic-gate 				"Timelimit exceeded");
196*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
197*0Sstevel@tonic-gate 				"Sizelimit exceeded");
198*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Compare false");
199*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Compare true");
200*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
201*0Sstevel@tonic-gate 				"Authentication method not supported");
202*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
203*0Sstevel@tonic-gate 				"Strong authentication required");
204*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
205*0Sstevel@tonic-gate 				"Partial results and referral received");
206*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
207*0Sstevel@tonic-gate 				"Referral received");
208*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
209*0Sstevel@tonic-gate 				"Administrative limit exceeded");
210*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
211*0Sstevel@tonic-gate 				"Unavailable critical extension");
212*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
213*0Sstevel@tonic-gate 				"Confidentiality required");
214*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
215*0Sstevel@tonic-gate 				"SASL bind in progress");
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
218*0Sstevel@tonic-gate 				"No such attribute");
219*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
220*0Sstevel@tonic-gate 				"Undefined attribute type");
221*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
222*0Sstevel@tonic-gate 				"Inappropriate matching");
223*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
224*0Sstevel@tonic-gate 				"Constraint violation");
225*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
226*0Sstevel@tonic-gate 				"Type or value exists");
227*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Invalid syntax");
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "No such object");
230*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Alias problem");
231*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
232*0Sstevel@tonic-gate 				"Invalid DN syntax");
233*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Object is a leaf");
234*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
235*0Sstevel@tonic-gate 				"Alias dereferencing problem");
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
238*0Sstevel@tonic-gate 				"Inappropriate authentication");
239*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
240*0Sstevel@tonic-gate 				"Invalid credentials");
241*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
242*0Sstevel@tonic-gate 				"Insufficient access");
243*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "DSA is busy");
244*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
245*0Sstevel@tonic-gate 				"DSA is unavailable");
246*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
247*0Sstevel@tonic-gate 				"DSA is unwilling to perform");
248*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Loop detected");
249*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
250*0Sstevel@tonic-gate 				"Sort Control is missing");
251*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
252*0Sstevel@tonic-gate 		"Search results exceed the range specified by the offsets");
253*0Sstevel@tonic-gate 
254*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Naming violation");
255*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
256*0Sstevel@tonic-gate 				"Object class violation");
257*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
258*0Sstevel@tonic-gate 				"Operation not allowed on nonleaf");
259*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
260*0Sstevel@tonic-gate 				"Operation not allowed on RDN");
261*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Already exists");
262*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
263*0Sstevel@tonic-gate 				"Cannot modify object class");
264*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
265*0Sstevel@tonic-gate 				"Results too large");
266*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
267*0Sstevel@tonic-gate 				"Affects multiple servers");
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Unknown error");
270*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
271*0Sstevel@tonic-gate 				"Can't contact LDAP server");
272*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Local error");
273*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Encoding error");
274*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Decoding error");
275*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Timed out");
276*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
277*0Sstevel@tonic-gate 				"Unknown authentication method");
278*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
279*0Sstevel@tonic-gate 				"Bad search filter");
280*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
281*0Sstevel@tonic-gate 				"User cancelled operation");
282*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
283*0Sstevel@tonic-gate 				"Bad parameter to an ldap routine");
284*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Out of memory");
285*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
286*0Sstevel@tonic-gate 				"Can't connect to the LDAP server");
287*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
288*0Sstevel@tonic-gate 			"Not supported by this version of the LDAP protocol");
289*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
290*0Sstevel@tonic-gate 				"Requested LDAP control not found");
291*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
292*0Sstevel@tonic-gate 				"No results returned");
293*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
294*0Sstevel@tonic-gate 				"More results to return");
295*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
296*0Sstevel@tonic-gate 				"Client detected loop");
297*0Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
298*0Sstevel@tonic-gate 				"Referral hop limit exceeded");
299*0Sstevel@tonic-gate 	mutex_unlock(&err_mutex);
300*0Sstevel@tonic-gate }
301*0Sstevel@tonic-gate #endif
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate char *
304*0Sstevel@tonic-gate LDAP_CALL
ldap_err2string(int err)305*0Sstevel@tonic-gate ldap_err2string( int err )
306*0Sstevel@tonic-gate {
307*0Sstevel@tonic-gate 	int	i;
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
312*0Sstevel@tonic-gate 	/* Make sure errlist is initialized before referencing err string */
313*0Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason == NULL)
314*0Sstevel@tonic-gate 		fill_ldap_errlist();
315*0Sstevel@tonic-gate #endif
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
318*0Sstevel@tonic-gate 		if ( err == ldap_errlist[i].e_code )
319*0Sstevel@tonic-gate 			return( ldap_errlist[i].e_reason );
320*0Sstevel@tonic-gate 	}
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate 	return( dgettext(TEXT_DOMAIN, "Unknown error") );
323*0Sstevel@tonic-gate }
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate static char *
nsldapi_safe_strerror(int e)327*0Sstevel@tonic-gate nsldapi_safe_strerror( int e )
328*0Sstevel@tonic-gate {
329*0Sstevel@tonic-gate 	char *s;
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate 	if (( s = strerror( e )) == NULL ) {
332*0Sstevel@tonic-gate 		s = dgettext(TEXT_DOMAIN, "unknown error");
333*0Sstevel@tonic-gate 	}
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate 	return( s );
336*0Sstevel@tonic-gate }
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate void
340*0Sstevel@tonic-gate LDAP_CALL
ldap_perror(LDAP * ld,const char * s)341*0Sstevel@tonic-gate ldap_perror( LDAP *ld, const char *s )
342*0Sstevel@tonic-gate {
343*0Sstevel@tonic-gate 	int	i, err;
344*0Sstevel@tonic-gate 	char	*matched, *errmsg, *separator;
345*0Sstevel@tonic-gate 	char    msg[1024];
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_perror\n", 0, 0, 0 );
348*0Sstevel@tonic-gate 
349*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
350*0Sstevel@tonic-gate 	/* Make sure errlist is initialized before referencing err string */
351*0Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason == NULL)
352*0Sstevel@tonic-gate 		fill_ldap_errlist();
353*0Sstevel@tonic-gate #endif
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate 	if ( s == NULL ) {
356*0Sstevel@tonic-gate 		s = separator = "";
357*0Sstevel@tonic-gate 	} else {
358*0Sstevel@tonic-gate 		separator = ": ";
359*0Sstevel@tonic-gate 	}
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 	if ( ld == NULL ) {
362*0Sstevel@tonic-gate 		sprintf( msg, "%s%s%s", s, separator,
363*0Sstevel@tonic-gate 		    nsldapi_safe_strerror( errno ) );
364*0Sstevel@tonic-gate 		ber_err_print( msg );
365*0Sstevel@tonic-gate 		return;
366*0Sstevel@tonic-gate 	}
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 	LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
369*0Sstevel@tonic-gate 	err = LDAP_GET_LDERRNO( ld, &matched, &errmsg );
370*0Sstevel@tonic-gate 	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
371*0Sstevel@tonic-gate 		if ( err == ldap_errlist[i].e_code ) {
372*0Sstevel@tonic-gate 			sprintf( msg, "%s%s%s", s, separator,
373*0Sstevel@tonic-gate 				    ldap_errlist[i].e_reason );
374*0Sstevel@tonic-gate 			ber_err_print( msg );
375*0Sstevel@tonic-gate 			if ( err == LDAP_CONNECT_ERROR ) {
376*0Sstevel@tonic-gate 				ber_err_print( " - " );
377*0Sstevel@tonic-gate 				ber_err_print( nsldapi_safe_strerror(
378*0Sstevel@tonic-gate 				    LDAP_GET_ERRNO( ld )));
379*0Sstevel@tonic-gate 			}
380*0Sstevel@tonic-gate 			ber_err_print( "\n" );
381*0Sstevel@tonic-gate 			if ( matched != NULL && *matched != '\0' ) {
382*0Sstevel@tonic-gate 				sprintf( msg, dgettext(TEXT_DOMAIN,
383*0Sstevel@tonic-gate 					"%s%smatched: %s\n"),
384*0Sstevel@tonic-gate 				    s, separator, matched );
385*0Sstevel@tonic-gate 				ber_err_print( msg );
386*0Sstevel@tonic-gate 			}
387*0Sstevel@tonic-gate 			if ( errmsg != NULL && *errmsg != '\0' ) {
388*0Sstevel@tonic-gate 				sprintf( msg, dgettext(TEXT_DOMAIN,
389*0Sstevel@tonic-gate 					"%s%sadditional info: %s\n"),
390*0Sstevel@tonic-gate 				    s, separator, errmsg );
391*0Sstevel@tonic-gate 				ber_err_print( msg );
392*0Sstevel@tonic-gate 			}
393*0Sstevel@tonic-gate 			LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
394*0Sstevel@tonic-gate 			return;
395*0Sstevel@tonic-gate 		}
396*0Sstevel@tonic-gate 	}
397*0Sstevel@tonic-gate 	sprintf( msg, dgettext(TEXT_DOMAIN, "%s%sNot an LDAP errno %d\n"),
398*0Sstevel@tonic-gate 		s, separator, err );
399*0Sstevel@tonic-gate 	ber_err_print( msg );
400*0Sstevel@tonic-gate 	LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
401*0Sstevel@tonic-gate }
402*0Sstevel@tonic-gate 
403*0Sstevel@tonic-gate int
404*0Sstevel@tonic-gate LDAP_CALL
ldap_result2error(LDAP * ld,LDAPMessage * r,int freeit)405*0Sstevel@tonic-gate ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
406*0Sstevel@tonic-gate {
407*0Sstevel@tonic-gate 	int	lderr_parse, lderr;
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 	lderr_parse = ldap_parse_result( ld, r, &lderr, NULL, NULL, NULL,
410*0Sstevel@tonic-gate 	    NULL, freeit );
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 	if ( lderr_parse != LDAP_SUCCESS ) {
413*0Sstevel@tonic-gate 		return( lderr_parse );
414*0Sstevel@tonic-gate 	}
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate 	return( lderr );
417*0Sstevel@tonic-gate }
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate int
420*0Sstevel@tonic-gate LDAP_CALL
ldap_get_lderrno(LDAP * ld,char ** m,char ** s)421*0Sstevel@tonic-gate ldap_get_lderrno( LDAP *ld, char **m, char **s )
422*0Sstevel@tonic-gate {
423*0Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
424*0Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );	/* punt */
425*0Sstevel@tonic-gate 	}
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 	if ( ld->ld_get_lderrno_fn == NULL ) {
428*0Sstevel@tonic-gate 		if ( m != NULL ) {
429*0Sstevel@tonic-gate 			*m = ld->ld_matched;
430*0Sstevel@tonic-gate 		}
431*0Sstevel@tonic-gate 		if ( s != NULL ) {
432*0Sstevel@tonic-gate 			*s = ld->ld_error;
433*0Sstevel@tonic-gate 		}
434*0Sstevel@tonic-gate 		return( ld->ld_errno );
435*0Sstevel@tonic-gate 	} else {
436*0Sstevel@tonic-gate 		return( ld->ld_get_lderrno_fn( m, s, ld->ld_lderrno_arg ) );
437*0Sstevel@tonic-gate 	}
438*0Sstevel@tonic-gate }
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate /*
442*0Sstevel@tonic-gate  * Note: there is no need for callers of ldap_set_lderrno() to lock the
443*0Sstevel@tonic-gate  * ld mutex.  If applications intend to share an LDAP session handle
444*0Sstevel@tonic-gate  * between threads they *must* perform their own locking around the
445*0Sstevel@tonic-gate  * session handle or they must install a "set lderrno" thread callback
446*0Sstevel@tonic-gate  * function.
447*0Sstevel@tonic-gate  *
448*0Sstevel@tonic-gate  */
449*0Sstevel@tonic-gate int
450*0Sstevel@tonic-gate LDAP_CALL
ldap_set_lderrno(LDAP * ld,int e,char * m,char * s)451*0Sstevel@tonic-gate ldap_set_lderrno( LDAP *ld, int e, char *m, char *s )
452*0Sstevel@tonic-gate {
453*0Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
454*0Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );
455*0Sstevel@tonic-gate 	}
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	if ( ld->ld_set_lderrno_fn != NULL ) {
458*0Sstevel@tonic-gate 		ld->ld_set_lderrno_fn( e, m, s, ld->ld_lderrno_arg );
459*0Sstevel@tonic-gate 	} else {
460*0Sstevel@tonic-gate         LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
461*0Sstevel@tonic-gate 		ld->ld_errno = e;
462*0Sstevel@tonic-gate 		if ( ld->ld_matched ) {
463*0Sstevel@tonic-gate 			NSLDAPI_FREE( ld->ld_matched );
464*0Sstevel@tonic-gate 		}
465*0Sstevel@tonic-gate 		ld->ld_matched = m;
466*0Sstevel@tonic-gate 		if ( ld->ld_error ) {
467*0Sstevel@tonic-gate 			NSLDAPI_FREE( ld->ld_error );
468*0Sstevel@tonic-gate 		}
469*0Sstevel@tonic-gate 		ld->ld_error = s;
470*0Sstevel@tonic-gate         LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
471*0Sstevel@tonic-gate 	}
472*0Sstevel@tonic-gate 
473*0Sstevel@tonic-gate 	return( LDAP_SUCCESS );
474*0Sstevel@tonic-gate }
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate /*
478*0Sstevel@tonic-gate  * Returns an LDAP error that says whether parse succeeded.  The error code
479*0Sstevel@tonic-gate  * from the LDAP result itself is returned in the errcodep result parameter.
480*0Sstevel@tonic-gate  * If any of the result params. (errcodep, matchednp, errmsgp, referralsp,
481*0Sstevel@tonic-gate  * or serverctrlsp) are NULL we don't return that info.
482*0Sstevel@tonic-gate  */
483*0Sstevel@tonic-gate int
484*0Sstevel@tonic-gate LDAP_CALL
ldap_parse_result(LDAP * ld,LDAPMessage * res,int * errcodep,char ** matchednp,char ** errmsgp,char *** referralsp,LDAPControl *** serverctrlsp,int freeit)485*0Sstevel@tonic-gate ldap_parse_result( LDAP *ld, LDAPMessage *res, int *errcodep, char **matchednp,
486*0Sstevel@tonic-gate 	char **errmsgp, char ***referralsp, LDAPControl ***serverctrlsp,
487*0Sstevel@tonic-gate 	int freeit )
488*0Sstevel@tonic-gate {
489*0Sstevel@tonic-gate 	LDAPMessage		*lm;
490*0Sstevel@tonic-gate 	int			err, errcode;
491*0Sstevel@tonic-gate 	char			*m, *e;
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );
494*0Sstevel@tonic-gate 
495*0Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
496*0Sstevel@tonic-gate 	    !NSLDAPI_VALID_LDAPMESSAGE_POINTER( res )) {
497*0Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );
498*0Sstevel@tonic-gate 	}
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate 	/* skip over entries and references to find next result in this chain */
501*0Sstevel@tonic-gate 	for ( lm = res; lm != NULL; lm = lm->lm_chain ) {
502*0Sstevel@tonic-gate 		if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
503*0Sstevel@tonic-gate 		    lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
504*0Sstevel@tonic-gate 			break;
505*0Sstevel@tonic-gate 		}
506*0Sstevel@tonic-gate 	}
507*0Sstevel@tonic-gate 
508*0Sstevel@tonic-gate 	if ( lm == NULL ) {
509*0Sstevel@tonic-gate 		err = LDAP_NO_RESULTS_RETURNED;
510*0Sstevel@tonic-gate 		LDAP_SET_LDERRNO( ld, err, NULL, NULL );
511*0Sstevel@tonic-gate 		return( err );
512*0Sstevel@tonic-gate 	}
513*0Sstevel@tonic-gate 
514*0Sstevel@tonic-gate 	err = nsldapi_parse_result( ld, lm->lm_msgtype, lm->lm_ber, &errcode,
515*0Sstevel@tonic-gate 	    &m, &e, referralsp, serverctrlsp );
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate 	if ( err == LDAP_SUCCESS ) {
518*0Sstevel@tonic-gate 		if ( errcodep != NULL ) {
519*0Sstevel@tonic-gate 			*errcodep = errcode;
520*0Sstevel@tonic-gate 		}
521*0Sstevel@tonic-gate 		if ( matchednp != NULL ) {
522*0Sstevel@tonic-gate 			*matchednp = nsldapi_strdup( m );
523*0Sstevel@tonic-gate 		}
524*0Sstevel@tonic-gate 		if ( errmsgp != NULL ) {
525*0Sstevel@tonic-gate 			*errmsgp = nsldapi_strdup( e );
526*0Sstevel@tonic-gate 		}
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 		/*
529*0Sstevel@tonic-gate 		 * if there are more result messages in the chain, arrange to
530*0Sstevel@tonic-gate 		 * return the special LDAP_MORE_RESULTS_TO_RETURN "error" code.
531*0Sstevel@tonic-gate 		 */
532*0Sstevel@tonic-gate 		for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
533*0Sstevel@tonic-gate 			if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
534*0Sstevel@tonic-gate 			    lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
535*0Sstevel@tonic-gate 				err = LDAP_MORE_RESULTS_TO_RETURN;
536*0Sstevel@tonic-gate 				break;
537*0Sstevel@tonic-gate 			}
538*0Sstevel@tonic-gate 		}
539*0Sstevel@tonic-gate 	} else {
540*0Sstevel@tonic-gate 		m = e = NULL;
541*0Sstevel@tonic-gate 	}
542*0Sstevel@tonic-gate 
543*0Sstevel@tonic-gate 	if ( freeit ) {
544*0Sstevel@tonic-gate 		ldap_msgfree( res );
545*0Sstevel@tonic-gate 	}
546*0Sstevel@tonic-gate 
547*0Sstevel@tonic-gate 	LDAP_SET_LDERRNO( ld, ( err == LDAP_SUCCESS ) ? errcode : err, m, e );
548*0Sstevel@tonic-gate 
549*0Sstevel@tonic-gate 	return( err );
550*0Sstevel@tonic-gate }
551*0Sstevel@tonic-gate 
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate /*
554*0Sstevel@tonic-gate  * returns an LDAP error code indicating success or failure of parsing
555*0Sstevel@tonic-gate  * does NOT set any error information inside "ld"
556*0Sstevel@tonic-gate  */
557*0Sstevel@tonic-gate int
nsldapi_parse_result(LDAP * ld,int msgtype,BerElement * rber,int * errcodep,char ** matchednp,char ** errmsgp,char *** referralsp,LDAPControl *** serverctrlsp)558*0Sstevel@tonic-gate nsldapi_parse_result( LDAP *ld, int msgtype, BerElement *rber, int *errcodep,
559*0Sstevel@tonic-gate     char **matchednp, char **errmsgp, char ***referralsp,
560*0Sstevel@tonic-gate     LDAPControl ***serverctrlsp )
561*0Sstevel@tonic-gate {
562*0Sstevel@tonic-gate 	BerElement	ber;
563*0Sstevel@tonic-gate 	ber_len_t	len;
564*0Sstevel@tonic-gate 	int		berrc, err, errcode;
565*0Sstevel@tonic-gate 	ber_int_t	along;
566*0Sstevel@tonic-gate 	char		*m, *e;
567*0Sstevel@tonic-gate 
568*0Sstevel@tonic-gate 	/*
569*0Sstevel@tonic-gate 	 * Parse the result message.  LDAPv3 result messages look like this:
570*0Sstevel@tonic-gate 	 *
571*0Sstevel@tonic-gate 	 *	LDAPResult ::= SEQUENCE {
572*0Sstevel@tonic-gate 	 *		resultCode	ENUMERATED { ... },
573*0Sstevel@tonic-gate 	 *		matchedDN	LDAPDN,
574*0Sstevel@tonic-gate 	 *		errorMessage	LDAPString,
575*0Sstevel@tonic-gate 	 *		referral	[3] Referral OPTIONAL
576*0Sstevel@tonic-gate 	 *		opSpecificStuff	OPTIONAL
577*0Sstevel@tonic-gate 	 *	}
578*0Sstevel@tonic-gate 	 *
579*0Sstevel@tonic-gate 	 * all wrapped up in an LDAPMessage sequence which looks like this:
580*0Sstevel@tonic-gate 	 *	LDAPMessage ::= SEQUENCE {
581*0Sstevel@tonic-gate 	 *		messageID	MessageID,
582*0Sstevel@tonic-gate 	 *		LDAPResult	CHOICE { ... },	// message type
583*0Sstevel@tonic-gate 	 *		controls	[0] Controls OPTIONAL
584*0Sstevel@tonic-gate 	 *	}
585*0Sstevel@tonic-gate 	 *
586*0Sstevel@tonic-gate 	 * LDAPv2 messages don't include referrals or controls.
587*0Sstevel@tonic-gate 	 * LDAPv1 messages don't include matchedDN, referrals, or controls.
588*0Sstevel@tonic-gate 	 *
589*0Sstevel@tonic-gate 	 * ldap_result() pulls out the message id, so by the time a result
590*0Sstevel@tonic-gate 	 * message gets here we are sitting at the start of the LDAPResult.
591*0Sstevel@tonic-gate 	 */
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate 	err = LDAP_SUCCESS;	/* optimistic */
594*0Sstevel@tonic-gate 	m = e = NULL;
595*0Sstevel@tonic-gate 	if ( matchednp != NULL ) {
596*0Sstevel@tonic-gate 		*matchednp = NULL;
597*0Sstevel@tonic-gate 	}
598*0Sstevel@tonic-gate 	if ( errmsgp != NULL ) {
599*0Sstevel@tonic-gate 		*errmsgp = NULL;
600*0Sstevel@tonic-gate 	}
601*0Sstevel@tonic-gate 	if ( referralsp != NULL ) {
602*0Sstevel@tonic-gate 		*referralsp = NULL;
603*0Sstevel@tonic-gate 	}
604*0Sstevel@tonic-gate 	if ( serverctrlsp != NULL ) {
605*0Sstevel@tonic-gate 		*serverctrlsp = NULL;
606*0Sstevel@tonic-gate 	}
607*0Sstevel@tonic-gate 	ber = *rber;		/* struct copy */
608*0Sstevel@tonic-gate 
609*0Sstevel@tonic-gate 	if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION2 ) {
610*0Sstevel@tonic-gate 		berrc = ber_scanf( &ber, "{ia}", &along, &e );
611*0Sstevel@tonic-gate 		errcode = (int)along;	/* XXX lossy cast */
612*0Sstevel@tonic-gate 	} else {
613*0Sstevel@tonic-gate 		if (( berrc = ber_scanf( &ber, "{iaa", &along, &m, &e ))
614*0Sstevel@tonic-gate 		    != LBER_ERROR ) {
615*0Sstevel@tonic-gate 			errcode = (int)along;	/* XXX lossy cast */
616*0Sstevel@tonic-gate 			/* check for optional referrals */
617*0Sstevel@tonic-gate 			if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_REFERRAL ) {
618*0Sstevel@tonic-gate 				if ( referralsp == NULL ) {
619*0Sstevel@tonic-gate 					/* skip referrals */
620*0Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
621*0Sstevel@tonic-gate 				} else {
622*0Sstevel@tonic-gate 					/* suck out referrals */
623*0Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "v",
624*0Sstevel@tonic-gate 					    referralsp );
625*0Sstevel@tonic-gate 				}
626*0Sstevel@tonic-gate 			} else if ( referralsp != NULL ) {
627*0Sstevel@tonic-gate 				*referralsp = NULL;
628*0Sstevel@tonic-gate 			}
629*0Sstevel@tonic-gate 		}
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 		if ( berrc != LBER_ERROR ) {
632*0Sstevel@tonic-gate 			/*
633*0Sstevel@tonic-gate 			 * skip past optional operation-specific elements:
634*0Sstevel@tonic-gate 			 *   bind results - serverSASLcreds
635*0Sstevel@tonic-gate 			 *   extendedop results -  OID plus value
636*0Sstevel@tonic-gate 			 */
637*0Sstevel@tonic-gate 			if ( msgtype == LDAP_RES_BIND ) {
638*0Sstevel@tonic-gate 				if ( ber_peek_tag( &ber, &len ) ==
639*0Sstevel@tonic-gate 				    LDAP_TAG_SASL_RES_CREDS ) {
640*0Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
641*0Sstevel@tonic-gate 				}
642*0Sstevel@tonic-gate 			} else if ( msgtype == LDAP_RES_EXTENDED ) {
643*0Sstevel@tonic-gate 				if ( ber_peek_tag( &ber, &len ) ==
644*0Sstevel@tonic-gate 				    LDAP_TAG_EXOP_RES_OID ) {
645*0Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
646*0Sstevel@tonic-gate 				}
647*0Sstevel@tonic-gate 				if ( berrc != LBER_ERROR &&
648*0Sstevel@tonic-gate 				    ber_peek_tag( &ber, &len ) ==
649*0Sstevel@tonic-gate 				    LDAP_TAG_EXOP_RES_VALUE ) {
650*0Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
651*0Sstevel@tonic-gate 				}
652*0Sstevel@tonic-gate 			}
653*0Sstevel@tonic-gate 		}
654*0Sstevel@tonic-gate 
655*0Sstevel@tonic-gate 		/* pull out controls (if requested and any are present) */
656*0Sstevel@tonic-gate 		if ( berrc != LBER_ERROR && serverctrlsp != NULL &&
657*0Sstevel@tonic-gate 		    ( berrc = ber_scanf( &ber, "}" )) != LBER_ERROR ) {
658*0Sstevel@tonic-gate 			err = nsldapi_get_controls( &ber, serverctrlsp );
659*0Sstevel@tonic-gate 		}
660*0Sstevel@tonic-gate 	}
661*0Sstevel@tonic-gate 
662*0Sstevel@tonic-gate 	if ( berrc == LBER_ERROR && err == LDAP_SUCCESS ) {
663*0Sstevel@tonic-gate 		err = LDAP_DECODING_ERROR;
664*0Sstevel@tonic-gate 	}
665*0Sstevel@tonic-gate 
666*0Sstevel@tonic-gate 	if ( errcodep != NULL ) {
667*0Sstevel@tonic-gate 		*errcodep = errcode;
668*0Sstevel@tonic-gate 	}
669*0Sstevel@tonic-gate 	if ( matchednp != NULL ) {
670*0Sstevel@tonic-gate 		*matchednp = m;
671*0Sstevel@tonic-gate 	} else if ( m != NULL ) {
672*0Sstevel@tonic-gate 		NSLDAPI_FREE( m );
673*0Sstevel@tonic-gate 	}
674*0Sstevel@tonic-gate 	if ( errmsgp != NULL ) {
675*0Sstevel@tonic-gate 		*errmsgp = e;
676*0Sstevel@tonic-gate 	} else if ( e != NULL ) {
677*0Sstevel@tonic-gate 		NSLDAPI_FREE( e );
678*0Sstevel@tonic-gate 	}
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate 	return( err );
681*0Sstevel@tonic-gate }
682