17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public License
97c478bd9Sstevel@tonic-gate  * Version 1.0 (the "NPL"); you may not use this file except in
107c478bd9Sstevel@tonic-gate  * compliance with the NPL.  You may obtain a copy of the NPL at
117c478bd9Sstevel@tonic-gate  * http://www.mozilla.org/NPL/
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Software distributed under the NPL is distributed on an "AS IS" basis,
147c478bd9Sstevel@tonic-gate  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
157c478bd9Sstevel@tonic-gate  * for the specific language governing rights and limitations under the
167c478bd9Sstevel@tonic-gate  * NPL.
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * The Initial Developer of this code under the NPL is Netscape
197c478bd9Sstevel@tonic-gate  * Communications Corporation.  Portions created by Netscape are
207c478bd9Sstevel@tonic-gate  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
217c478bd9Sstevel@tonic-gate  * Reserved.
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate #include "ldap-int.h"
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate struct ldaperror {
267c478bd9Sstevel@tonic-gate 	int	e_code;
277c478bd9Sstevel@tonic-gate 	char	*e_reason;
287c478bd9Sstevel@tonic-gate };
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
317c478bd9Sstevel@tonic-gate #include <synch.h>
327c478bd9Sstevel@tonic-gate static struct ldaperror ldap_errlist[] = {
337c478bd9Sstevel@tonic-gate 	{ LDAP_SUCCESS, 			0 },
347c478bd9Sstevel@tonic-gate 	{ LDAP_OPERATIONS_ERROR, 		0 },
357c478bd9Sstevel@tonic-gate 	{ LDAP_PROTOCOL_ERROR, 			0 },
367c478bd9Sstevel@tonic-gate 	{ LDAP_TIMELIMIT_EXCEEDED,		0 },
377c478bd9Sstevel@tonic-gate 	{ LDAP_SIZELIMIT_EXCEEDED, 		0 },
387c478bd9Sstevel@tonic-gate 	{ LDAP_COMPARE_FALSE, 			0 },
397c478bd9Sstevel@tonic-gate 	{ LDAP_COMPARE_TRUE, 			0 },
407c478bd9Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_NOT_SUPPORTED,	0 },
417c478bd9Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_REQUIRED, 		0 },
427c478bd9Sstevel@tonic-gate 	{ LDAP_PARTIAL_RESULTS, 		0 },
437c478bd9Sstevel@tonic-gate 	{ LDAP_REFERRAL, 			0 },
447c478bd9Sstevel@tonic-gate 	{ LDAP_ADMINLIMIT_EXCEEDED,		0 },
457c478bd9Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE_CRITICAL_EXTENSION,	0 },
467c478bd9Sstevel@tonic-gate 	{ LDAP_CONFIDENTIALITY_REQUIRED,	0 },
477c478bd9Sstevel@tonic-gate 	{ LDAP_SASL_BIND_IN_PROGRESS,		0 },
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 	{ LDAP_NO_SUCH_ATTRIBUTE, 		0 },
507c478bd9Sstevel@tonic-gate 	{ LDAP_UNDEFINED_TYPE, 			0 },
517c478bd9Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_MATCHING, 		0 },
527c478bd9Sstevel@tonic-gate 	{ LDAP_CONSTRAINT_VIOLATION, 		0 },
537c478bd9Sstevel@tonic-gate 	{ LDAP_TYPE_OR_VALUE_EXISTS, 		0 },
547c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_SYNTAX, 			0 },
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate 	{ LDAP_NO_SUCH_OBJECT, 			0 },
577c478bd9Sstevel@tonic-gate 	{ LDAP_ALIAS_PROBLEM, 			0 },
587c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_DN_SYNTAX,		0 },
597c478bd9Sstevel@tonic-gate 	{ LDAP_IS_LEAF, 			0 },
607c478bd9Sstevel@tonic-gate 	{ LDAP_ALIAS_DEREF_PROBLEM, 		0 },
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_AUTH, 		0 },
637c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_CREDENTIALS, 		0 },
647c478bd9Sstevel@tonic-gate 	{ LDAP_INSUFFICIENT_ACCESS, 		0 },
657c478bd9Sstevel@tonic-gate 	{ LDAP_BUSY, 				0 },
667c478bd9Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE, 			0 },
677c478bd9Sstevel@tonic-gate 	{ LDAP_UNWILLING_TO_PERFORM, 		0 },
687c478bd9Sstevel@tonic-gate 	{ LDAP_LOOP_DETECT, 			0 },
697c478bd9Sstevel@tonic-gate 	{ LDAP_SORT_CONTROL_MISSING,    	0 },
70*1da57d55SToomas Soome 	{ LDAP_INDEX_RANGE_ERROR,		0 },
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	{ LDAP_NAMING_VIOLATION, 		0 },
737c478bd9Sstevel@tonic-gate 	{ LDAP_OBJECT_CLASS_VIOLATION, 		0 },
747c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_NONLEAF, 		0 },
757c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_RDN, 		0 },
767c478bd9Sstevel@tonic-gate 	{ LDAP_ALREADY_EXISTS, 			0 },
777c478bd9Sstevel@tonic-gate 	{ LDAP_NO_OBJECT_CLASS_MODS, 		0 },
787c478bd9Sstevel@tonic-gate 	{ LDAP_RESULTS_TOO_LARGE,		0 },
797c478bd9Sstevel@tonic-gate 	{ LDAP_AFFECTS_MULTIPLE_DSAS,		0 },
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	{ LDAP_OTHER, 				0 },
827c478bd9Sstevel@tonic-gate 	{ LDAP_SERVER_DOWN,			0 },
837c478bd9Sstevel@tonic-gate 	{ LDAP_LOCAL_ERROR,			0 },
847c478bd9Sstevel@tonic-gate 	{ LDAP_ENCODING_ERROR,			0 },
857c478bd9Sstevel@tonic-gate 	{ LDAP_DECODING_ERROR,			0 },
867c478bd9Sstevel@tonic-gate 	{ LDAP_TIMEOUT,				0 },
877c478bd9Sstevel@tonic-gate 	{ LDAP_AUTH_UNKNOWN,			0 },
887c478bd9Sstevel@tonic-gate 	{ LDAP_FILTER_ERROR,			0 },
897c478bd9Sstevel@tonic-gate 	{ LDAP_USER_CANCELLED,			0 },
907c478bd9Sstevel@tonic-gate 	{ LDAP_PARAM_ERROR,			0 },
917c478bd9Sstevel@tonic-gate 	{ LDAP_NO_MEMORY,			0 },
927c478bd9Sstevel@tonic-gate 	{ LDAP_CONNECT_ERROR,			0 },
937c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_SUPPORTED,			0 },
947c478bd9Sstevel@tonic-gate 	{ LDAP_CONTROL_NOT_FOUND,		0 },
957c478bd9Sstevel@tonic-gate 	{ LDAP_NO_RESULTS_RETURNED,		0 },
967c478bd9Sstevel@tonic-gate 	{ LDAP_MORE_RESULTS_TO_RETURN,		0 },
977c478bd9Sstevel@tonic-gate 	{ LDAP_CLIENT_LOOP,			0 },
987c478bd9Sstevel@tonic-gate 	{ LDAP_REFERRAL_LIMIT_EXCEEDED,		0 },
997c478bd9Sstevel@tonic-gate 	{ -1, 0 }
1007c478bd9Sstevel@tonic-gate };
1017c478bd9Sstevel@tonic-gate const int last_index = sizeof(ldap_errlist)/sizeof(ldap_errlist[0]) - 2;
1027c478bd9Sstevel@tonic-gate #else
1037c478bd9Sstevel@tonic-gate static struct ldaperror ldap_errlist[] = {
1047c478bd9Sstevel@tonic-gate 	{ LDAP_SUCCESS, 			"Success" },
1057c478bd9Sstevel@tonic-gate 	{ LDAP_OPERATIONS_ERROR, 		"Operations error" },
1067c478bd9Sstevel@tonic-gate 	{ LDAP_PROTOCOL_ERROR, 			"Protocol error" },
1077c478bd9Sstevel@tonic-gate 	{ LDAP_TIMELIMIT_EXCEEDED,		"Timelimit exceeded" },
1087c478bd9Sstevel@tonic-gate 	{ LDAP_SIZELIMIT_EXCEEDED, 		"Sizelimit exceeded" },
1097c478bd9Sstevel@tonic-gate 	{ LDAP_COMPARE_FALSE, 			"Compare false" },
1107c478bd9Sstevel@tonic-gate 	{ LDAP_COMPARE_TRUE, 			"Compare true" },
1117c478bd9Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_NOT_SUPPORTED,	"Authentication method not supported" },
1127c478bd9Sstevel@tonic-gate 	{ LDAP_STRONG_AUTH_REQUIRED, 		"Strong authentication required" },
1137c478bd9Sstevel@tonic-gate 	{ LDAP_PARTIAL_RESULTS, 		"Partial results and referral received" },
1147c478bd9Sstevel@tonic-gate 	{ LDAP_REFERRAL, 			"Referral received" },
1157c478bd9Sstevel@tonic-gate 	{ LDAP_ADMINLIMIT_EXCEEDED,		"Administrative limit exceeded" },
1167c478bd9Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE_CRITICAL_EXTENSION,	"Unavailable critical extension" },
1177c478bd9Sstevel@tonic-gate 	{ LDAP_CONFIDENTIALITY_REQUIRED,	"Confidentiality required" },
1187c478bd9Sstevel@tonic-gate 	{ LDAP_SASL_BIND_IN_PROGRESS,		"SASL bind in progress" },
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	{ LDAP_NO_SUCH_ATTRIBUTE, 		"No such attribute" },
1217c478bd9Sstevel@tonic-gate 	{ LDAP_UNDEFINED_TYPE, 			"Undefined attribute type" },
1227c478bd9Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_MATCHING, 		"Inappropriate matching" },
1237c478bd9Sstevel@tonic-gate 	{ LDAP_CONSTRAINT_VIOLATION, 		"Constraint violation" },
1247c478bd9Sstevel@tonic-gate 	{ LDAP_TYPE_OR_VALUE_EXISTS, 		"Type or value exists" },
1257c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_SYNTAX, 			"Invalid syntax" },
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	{ LDAP_NO_SUCH_OBJECT, 			"No such object" },
1287c478bd9Sstevel@tonic-gate 	{ LDAP_ALIAS_PROBLEM, 			"Alias problem" },
1297c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_DN_SYNTAX,		"Invalid DN syntax" },
1307c478bd9Sstevel@tonic-gate 	{ LDAP_IS_LEAF, 			"Object is a leaf" },
1317c478bd9Sstevel@tonic-gate 	{ LDAP_ALIAS_DEREF_PROBLEM, 		"Alias dereferencing problem" },
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	{ LDAP_INAPPROPRIATE_AUTH, 		"Inappropriate authentication" },
1347c478bd9Sstevel@tonic-gate 	{ LDAP_INVALID_CREDENTIALS, 		"Invalid credentials" },
1357c478bd9Sstevel@tonic-gate 	{ LDAP_INSUFFICIENT_ACCESS, 		"Insufficient access" },
1367c478bd9Sstevel@tonic-gate 	{ LDAP_BUSY, 				"DSA is busy" },
1377c478bd9Sstevel@tonic-gate 	{ LDAP_UNAVAILABLE, 			"DSA is unavailable" },
1387c478bd9Sstevel@tonic-gate 	{ LDAP_UNWILLING_TO_PERFORM, 		"DSA is unwilling to perform" },
1397c478bd9Sstevel@tonic-gate 	{ LDAP_LOOP_DETECT, 			"Loop detected" },
1407c478bd9Sstevel@tonic-gate     { LDAP_SORT_CONTROL_MISSING,    "Sort Control is missing"  },
141*1da57d55SToomas Soome     { LDAP_INDEX_RANGE_ERROR,              "Search results exceed the range specified by the offsets" },
142*1da57d55SToomas Soome 
1437c478bd9Sstevel@tonic-gate     { LDAP_NAMING_VIOLATION, 		"Naming violation" },
1447c478bd9Sstevel@tonic-gate 	{ LDAP_OBJECT_CLASS_VIOLATION, 		"Object class violation" },
1457c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_NONLEAF, 		"Operation not allowed on nonleaf" },
1467c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_ALLOWED_ON_RDN, 		"Operation not allowed on RDN" },
1477c478bd9Sstevel@tonic-gate 	{ LDAP_ALREADY_EXISTS, 			"Already exists" },
1487c478bd9Sstevel@tonic-gate 	{ LDAP_NO_OBJECT_CLASS_MODS, 		"Cannot modify object class" },
1497c478bd9Sstevel@tonic-gate 	{ LDAP_RESULTS_TOO_LARGE,		"Results too large" },
1507c478bd9Sstevel@tonic-gate 	{ LDAP_AFFECTS_MULTIPLE_DSAS,		"Affects multiple servers" },
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	{ LDAP_OTHER, 				"Unknown error" },
1537c478bd9Sstevel@tonic-gate 	{ LDAP_SERVER_DOWN,			"Can't contact LDAP server" },
1547c478bd9Sstevel@tonic-gate 	{ LDAP_LOCAL_ERROR,			"Local error" },
1557c478bd9Sstevel@tonic-gate 	{ LDAP_ENCODING_ERROR,			"Encoding error" },
1567c478bd9Sstevel@tonic-gate 	{ LDAP_DECODING_ERROR,			"Decoding error" },
1577c478bd9Sstevel@tonic-gate 	{ LDAP_TIMEOUT,				"Timed out" },
1587c478bd9Sstevel@tonic-gate 	{ LDAP_AUTH_UNKNOWN,			"Unknown authentication method" },
1597c478bd9Sstevel@tonic-gate 	{ LDAP_FILTER_ERROR,			"Bad search filter" },
1607c478bd9Sstevel@tonic-gate 	{ LDAP_USER_CANCELLED,			"User cancelled operation" },
1617c478bd9Sstevel@tonic-gate 	{ LDAP_PARAM_ERROR,			"Bad parameter to an ldap routine" },
1627c478bd9Sstevel@tonic-gate 	{ LDAP_NO_MEMORY,			"Out of memory" },
1637c478bd9Sstevel@tonic-gate 	{ LDAP_CONNECT_ERROR,			"Can't connect to the LDAP server" },
1647c478bd9Sstevel@tonic-gate 	{ LDAP_NOT_SUPPORTED,			"Not supported by this version of the LDAP protocol" },
1657c478bd9Sstevel@tonic-gate 	{ LDAP_CONTROL_NOT_FOUND,		"Requested LDAP control not found" },
1667c478bd9Sstevel@tonic-gate 	{ LDAP_NO_RESULTS_RETURNED,		"No results returned" },
1677c478bd9Sstevel@tonic-gate 	{ LDAP_MORE_RESULTS_TO_RETURN,		"More results to return" },
1687c478bd9Sstevel@tonic-gate 	{ LDAP_CLIENT_LOOP,			"Client detected loop" },
1697c478bd9Sstevel@tonic-gate 	{ LDAP_REFERRAL_LIMIT_EXCEEDED,		"Referral hop limit exceeded" },
1707c478bd9Sstevel@tonic-gate 	{ -1, 0 }
1717c478bd9Sstevel@tonic-gate };
1727c478bd9Sstevel@tonic-gate #endif
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
1757c478bd9Sstevel@tonic-gate static mutex_t		err_mutex = DEFAULTMUTEX;
1767c478bd9Sstevel@tonic-gate 
fill_ldap_errlist()1777c478bd9Sstevel@tonic-gate static void fill_ldap_errlist()
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate 	int i=0;
1807c478bd9Sstevel@tonic-gate 	mutex_lock(&err_mutex);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	LDAPDebug(LDAP_DEBUG_TRACE, "fill_ldap_errlist\n", 0, 0, 0 );
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason != NULL) {
1857c478bd9Sstevel@tonic-gate 		mutex_unlock(&err_mutex);
1867c478bd9Sstevel@tonic-gate 		return;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Success");
1907c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Operations error");
1917c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Protocol error");
1927c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
1937c478bd9Sstevel@tonic-gate 				"Timelimit exceeded");
1947c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
1957c478bd9Sstevel@tonic-gate 				"Sizelimit exceeded");
1967c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Compare false");
1977c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Compare true");
1987c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
1997c478bd9Sstevel@tonic-gate 				"Authentication method not supported");
2007c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2017c478bd9Sstevel@tonic-gate 				"Strong authentication required");
2027c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2037c478bd9Sstevel@tonic-gate 				"Partial results and referral received");
2047c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2057c478bd9Sstevel@tonic-gate 				"Referral received");
2067c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2077c478bd9Sstevel@tonic-gate 				"Administrative limit exceeded");
2087c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2097c478bd9Sstevel@tonic-gate 				"Unavailable critical extension");
2107c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2117c478bd9Sstevel@tonic-gate 				"Confidentiality required");
2127c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2137c478bd9Sstevel@tonic-gate 				"SASL bind in progress");
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2167c478bd9Sstevel@tonic-gate 				"No such attribute");
2177c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2187c478bd9Sstevel@tonic-gate 				"Undefined attribute type");
2197c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2207c478bd9Sstevel@tonic-gate 				"Inappropriate matching");
2217c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2227c478bd9Sstevel@tonic-gate 				"Constraint violation");
2237c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2247c478bd9Sstevel@tonic-gate 				"Type or value exists");
2257c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Invalid syntax");
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "No such object");
2287c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Alias problem");
2297c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2307c478bd9Sstevel@tonic-gate 				"Invalid DN syntax");
2317c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Object is a leaf");
2327c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2337c478bd9Sstevel@tonic-gate 				"Alias dereferencing problem");
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2367c478bd9Sstevel@tonic-gate 				"Inappropriate authentication");
2377c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2387c478bd9Sstevel@tonic-gate 				"Invalid credentials");
2397c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2407c478bd9Sstevel@tonic-gate 				"Insufficient access");
2417c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "DSA is busy");
2427c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2437c478bd9Sstevel@tonic-gate 				"DSA is unavailable");
2447c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2457c478bd9Sstevel@tonic-gate 				"DSA is unwilling to perform");
2467c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Loop detected");
2477c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2487c478bd9Sstevel@tonic-gate 				"Sort Control is missing");
2497c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2507c478bd9Sstevel@tonic-gate 		"Search results exceed the range specified by the offsets");
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Naming violation");
2537c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2547c478bd9Sstevel@tonic-gate 				"Object class violation");
2557c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2567c478bd9Sstevel@tonic-gate 				"Operation not allowed on nonleaf");
2577c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2587c478bd9Sstevel@tonic-gate 				"Operation not allowed on RDN");
2597c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Already exists");
2607c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2617c478bd9Sstevel@tonic-gate 				"Cannot modify object class");
2627c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2637c478bd9Sstevel@tonic-gate 				"Results too large");
2647c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2657c478bd9Sstevel@tonic-gate 				"Affects multiple servers");
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Unknown error");
2687c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2697c478bd9Sstevel@tonic-gate 				"Can't contact LDAP server");
2707c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Local error");
2717c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Encoding error");
2727c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Decoding error");
2737c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Timed out");
2747c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2757c478bd9Sstevel@tonic-gate 				"Unknown authentication method");
2767c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2777c478bd9Sstevel@tonic-gate 				"Bad search filter");
2787c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2797c478bd9Sstevel@tonic-gate 				"User cancelled operation");
2807c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2817c478bd9Sstevel@tonic-gate 				"Bad parameter to an ldap routine");
2827c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN, "Out of memory");
2837c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2847c478bd9Sstevel@tonic-gate 				"Can't connect to the LDAP server");
2857c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2867c478bd9Sstevel@tonic-gate 			"Not supported by this version of the LDAP protocol");
2877c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2887c478bd9Sstevel@tonic-gate 				"Requested LDAP control not found");
2897c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2907c478bd9Sstevel@tonic-gate 				"No results returned");
2917c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2927c478bd9Sstevel@tonic-gate 				"More results to return");
2937c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2947c478bd9Sstevel@tonic-gate 				"Client detected loop");
2957c478bd9Sstevel@tonic-gate 	ldap_errlist[i++].e_reason = dgettext(TEXT_DOMAIN,
2967c478bd9Sstevel@tonic-gate 				"Referral hop limit exceeded");
2977c478bd9Sstevel@tonic-gate 	mutex_unlock(&err_mutex);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate #endif
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate char *
3027c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_err2string(int err)3037c478bd9Sstevel@tonic-gate ldap_err2string( int err )
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 	int	i;
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
3107c478bd9Sstevel@tonic-gate 	/* Make sure errlist is initialized before referencing err string */
3117c478bd9Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason == NULL)
3127c478bd9Sstevel@tonic-gate 		fill_ldap_errlist();
3137c478bd9Sstevel@tonic-gate #endif
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
3167c478bd9Sstevel@tonic-gate 		if ( err == ldap_errlist[i].e_code )
3177c478bd9Sstevel@tonic-gate 			return( ldap_errlist[i].e_reason );
3187c478bd9Sstevel@tonic-gate 	}
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	return( dgettext(TEXT_DOMAIN, "Unknown error") );
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate static char *
nsldapi_safe_strerror(int e)3257c478bd9Sstevel@tonic-gate nsldapi_safe_strerror( int e )
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate 	char *s;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	if (( s = strerror( e )) == NULL ) {
3307c478bd9Sstevel@tonic-gate 		s = dgettext(TEXT_DOMAIN, "unknown error");
3317c478bd9Sstevel@tonic-gate 	}
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	return( s );
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate void
3387c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_perror(LDAP * ld,const char * s)3397c478bd9Sstevel@tonic-gate ldap_perror( LDAP *ld, const char *s )
3407c478bd9Sstevel@tonic-gate {
3417c478bd9Sstevel@tonic-gate 	int	i, err;
3427c478bd9Sstevel@tonic-gate 	char	*matched, *errmsg, *separator;
3437c478bd9Sstevel@tonic-gate 	char    msg[1024];
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_perror\n", 0, 0, 0 );
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
3487c478bd9Sstevel@tonic-gate 	/* Make sure errlist is initialized before referencing err string */
3497c478bd9Sstevel@tonic-gate 	if (ldap_errlist[last_index].e_reason == NULL)
3507c478bd9Sstevel@tonic-gate 		fill_ldap_errlist();
3517c478bd9Sstevel@tonic-gate #endif
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	if ( s == NULL ) {
3547c478bd9Sstevel@tonic-gate 		s = separator = "";
3557c478bd9Sstevel@tonic-gate 	} else {
3567c478bd9Sstevel@tonic-gate 		separator = ": ";
3577c478bd9Sstevel@tonic-gate 	}
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	if ( ld == NULL ) {
3607c478bd9Sstevel@tonic-gate 		sprintf( msg, "%s%s%s", s, separator,
3617c478bd9Sstevel@tonic-gate 		    nsldapi_safe_strerror( errno ) );
3627c478bd9Sstevel@tonic-gate 		ber_err_print( msg );
3637c478bd9Sstevel@tonic-gate 		return;
3647c478bd9Sstevel@tonic-gate 	}
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 	LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
3677c478bd9Sstevel@tonic-gate 	err = LDAP_GET_LDERRNO( ld, &matched, &errmsg );
3687c478bd9Sstevel@tonic-gate 	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
3697c478bd9Sstevel@tonic-gate 		if ( err == ldap_errlist[i].e_code ) {
3707c478bd9Sstevel@tonic-gate 			sprintf( msg, "%s%s%s", s, separator,
3717c478bd9Sstevel@tonic-gate 				    ldap_errlist[i].e_reason );
3727c478bd9Sstevel@tonic-gate 			ber_err_print( msg );
3737c478bd9Sstevel@tonic-gate 			if ( err == LDAP_CONNECT_ERROR ) {
3747c478bd9Sstevel@tonic-gate 				ber_err_print( " - " );
3757c478bd9Sstevel@tonic-gate 				ber_err_print( nsldapi_safe_strerror(
3767c478bd9Sstevel@tonic-gate 				    LDAP_GET_ERRNO( ld )));
3777c478bd9Sstevel@tonic-gate 			}
3787c478bd9Sstevel@tonic-gate 			ber_err_print( "\n" );
3797c478bd9Sstevel@tonic-gate 			if ( matched != NULL && *matched != '\0' ) {
3807c478bd9Sstevel@tonic-gate 				sprintf( msg, dgettext(TEXT_DOMAIN,
3817c478bd9Sstevel@tonic-gate 					"%s%smatched: %s\n"),
3827c478bd9Sstevel@tonic-gate 				    s, separator, matched );
3837c478bd9Sstevel@tonic-gate 				ber_err_print( msg );
3847c478bd9Sstevel@tonic-gate 			}
3857c478bd9Sstevel@tonic-gate 			if ( errmsg != NULL && *errmsg != '\0' ) {
3867c478bd9Sstevel@tonic-gate 				sprintf( msg, dgettext(TEXT_DOMAIN,
3877c478bd9Sstevel@tonic-gate 					"%s%sadditional info: %s\n"),
3887c478bd9Sstevel@tonic-gate 				    s, separator, errmsg );
3897c478bd9Sstevel@tonic-gate 				ber_err_print( msg );
3907c478bd9Sstevel@tonic-gate 			}
3917c478bd9Sstevel@tonic-gate 			LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
3927c478bd9Sstevel@tonic-gate 			return;
3937c478bd9Sstevel@tonic-gate 		}
3947c478bd9Sstevel@tonic-gate 	}
3957c478bd9Sstevel@tonic-gate 	sprintf( msg, dgettext(TEXT_DOMAIN, "%s%sNot an LDAP errno %d\n"),
3967c478bd9Sstevel@tonic-gate 		s, separator, err );
3977c478bd9Sstevel@tonic-gate 	ber_err_print( msg );
3987c478bd9Sstevel@tonic-gate 	LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate int
4027c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_result2error(LDAP * ld,LDAPMessage * r,int freeit)4037c478bd9Sstevel@tonic-gate ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
4047c478bd9Sstevel@tonic-gate {
4057c478bd9Sstevel@tonic-gate 	int	lderr_parse, lderr;
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	lderr_parse = ldap_parse_result( ld, r, &lderr, NULL, NULL, NULL,
4087c478bd9Sstevel@tonic-gate 	    NULL, freeit );
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	if ( lderr_parse != LDAP_SUCCESS ) {
4117c478bd9Sstevel@tonic-gate 		return( lderr_parse );
4127c478bd9Sstevel@tonic-gate 	}
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	return( lderr );
4157c478bd9Sstevel@tonic-gate }
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate int
4187c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_get_lderrno(LDAP * ld,char ** m,char ** s)4197c478bd9Sstevel@tonic-gate ldap_get_lderrno( LDAP *ld, char **m, char **s )
4207c478bd9Sstevel@tonic-gate {
4217c478bd9Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
4227c478bd9Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );	/* punt */
4237c478bd9Sstevel@tonic-gate 	}
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	if ( ld->ld_get_lderrno_fn == NULL ) {
4267c478bd9Sstevel@tonic-gate 		if ( m != NULL ) {
4277c478bd9Sstevel@tonic-gate 			*m = ld->ld_matched;
4287c478bd9Sstevel@tonic-gate 		}
4297c478bd9Sstevel@tonic-gate 		if ( s != NULL ) {
4307c478bd9Sstevel@tonic-gate 			*s = ld->ld_error;
4317c478bd9Sstevel@tonic-gate 		}
4327c478bd9Sstevel@tonic-gate 		return( ld->ld_errno );
4337c478bd9Sstevel@tonic-gate 	} else {
4347c478bd9Sstevel@tonic-gate 		return( ld->ld_get_lderrno_fn( m, s, ld->ld_lderrno_arg ) );
4357c478bd9Sstevel@tonic-gate 	}
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate /*
4407c478bd9Sstevel@tonic-gate  * Note: there is no need for callers of ldap_set_lderrno() to lock the
4417c478bd9Sstevel@tonic-gate  * ld mutex.  If applications intend to share an LDAP session handle
4427c478bd9Sstevel@tonic-gate  * between threads they *must* perform their own locking around the
4437c478bd9Sstevel@tonic-gate  * session handle or they must install a "set lderrno" thread callback
4447c478bd9Sstevel@tonic-gate  * function.
445*1da57d55SToomas Soome  *
4467c478bd9Sstevel@tonic-gate  */
4477c478bd9Sstevel@tonic-gate int
4487c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_set_lderrno(LDAP * ld,int e,char * m,char * s)4497c478bd9Sstevel@tonic-gate ldap_set_lderrno( LDAP *ld, int e, char *m, char *s )
4507c478bd9Sstevel@tonic-gate {
4517c478bd9Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
4527c478bd9Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );
4537c478bd9Sstevel@tonic-gate 	}
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 	if ( ld->ld_set_lderrno_fn != NULL ) {
4567c478bd9Sstevel@tonic-gate 		ld->ld_set_lderrno_fn( e, m, s, ld->ld_lderrno_arg );
4577c478bd9Sstevel@tonic-gate 	} else {
4587c478bd9Sstevel@tonic-gate         LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
4597c478bd9Sstevel@tonic-gate 		ld->ld_errno = e;
4607c478bd9Sstevel@tonic-gate 		if ( ld->ld_matched ) {
4617c478bd9Sstevel@tonic-gate 			NSLDAPI_FREE( ld->ld_matched );
4627c478bd9Sstevel@tonic-gate 		}
4637c478bd9Sstevel@tonic-gate 		ld->ld_matched = m;
4647c478bd9Sstevel@tonic-gate 		if ( ld->ld_error ) {
4657c478bd9Sstevel@tonic-gate 			NSLDAPI_FREE( ld->ld_error );
4667c478bd9Sstevel@tonic-gate 		}
4677c478bd9Sstevel@tonic-gate 		ld->ld_error = s;
4687c478bd9Sstevel@tonic-gate         LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
4697c478bd9Sstevel@tonic-gate 	}
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 	return( LDAP_SUCCESS );
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate /*
4767c478bd9Sstevel@tonic-gate  * Returns an LDAP error that says whether parse succeeded.  The error code
4777c478bd9Sstevel@tonic-gate  * from the LDAP result itself is returned in the errcodep result parameter.
4787c478bd9Sstevel@tonic-gate  * If any of the result params. (errcodep, matchednp, errmsgp, referralsp,
4797c478bd9Sstevel@tonic-gate  * or serverctrlsp) are NULL we don't return that info.
4807c478bd9Sstevel@tonic-gate  */
4817c478bd9Sstevel@tonic-gate int
4827c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_parse_result(LDAP * ld,LDAPMessage * res,int * errcodep,char ** matchednp,char ** errmsgp,char *** referralsp,LDAPControl *** serverctrlsp,int freeit)4837c478bd9Sstevel@tonic-gate ldap_parse_result( LDAP *ld, LDAPMessage *res, int *errcodep, char **matchednp,
4847c478bd9Sstevel@tonic-gate 	char **errmsgp, char ***referralsp, LDAPControl ***serverctrlsp,
4857c478bd9Sstevel@tonic-gate 	int freeit )
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate 	LDAPMessage		*lm;
4887c478bd9Sstevel@tonic-gate 	int			err, errcode;
4897c478bd9Sstevel@tonic-gate 	char			*m, *e;
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
4947c478bd9Sstevel@tonic-gate 	    !NSLDAPI_VALID_LDAPMESSAGE_POINTER( res )) {
4957c478bd9Sstevel@tonic-gate 		return( LDAP_PARAM_ERROR );
4967c478bd9Sstevel@tonic-gate 	}
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	/* skip over entries and references to find next result in this chain */
499*1da57d55SToomas Soome 	for ( lm = res; lm != NULL; lm = lm->lm_chain ) {
5007c478bd9Sstevel@tonic-gate 		if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
5017c478bd9Sstevel@tonic-gate 		    lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
5027c478bd9Sstevel@tonic-gate 			break;
5037c478bd9Sstevel@tonic-gate 		}
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	if ( lm == NULL ) {
5077c478bd9Sstevel@tonic-gate 		err = LDAP_NO_RESULTS_RETURNED;
5087c478bd9Sstevel@tonic-gate 		LDAP_SET_LDERRNO( ld, err, NULL, NULL );
5097c478bd9Sstevel@tonic-gate 		return( err );
5107c478bd9Sstevel@tonic-gate 	}
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	err = nsldapi_parse_result( ld, lm->lm_msgtype, lm->lm_ber, &errcode,
5137c478bd9Sstevel@tonic-gate 	    &m, &e, referralsp, serverctrlsp );
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 	if ( err == LDAP_SUCCESS ) {
5167c478bd9Sstevel@tonic-gate 		if ( errcodep != NULL ) {
5177c478bd9Sstevel@tonic-gate 			*errcodep = errcode;
5187c478bd9Sstevel@tonic-gate 		}
5197c478bd9Sstevel@tonic-gate 		if ( matchednp != NULL ) {
5207c478bd9Sstevel@tonic-gate 			*matchednp = nsldapi_strdup( m );
5217c478bd9Sstevel@tonic-gate 		}
5227c478bd9Sstevel@tonic-gate 		if ( errmsgp != NULL ) {
5237c478bd9Sstevel@tonic-gate 			*errmsgp = nsldapi_strdup( e );
5247c478bd9Sstevel@tonic-gate 		}
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 		/*
5277c478bd9Sstevel@tonic-gate 		 * if there are more result messages in the chain, arrange to
5287c478bd9Sstevel@tonic-gate 		 * return the special LDAP_MORE_RESULTS_TO_RETURN "error" code.
5297c478bd9Sstevel@tonic-gate 		 */
530*1da57d55SToomas Soome 		for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
5317c478bd9Sstevel@tonic-gate 			if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
5327c478bd9Sstevel@tonic-gate 			    lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
5337c478bd9Sstevel@tonic-gate 				err = LDAP_MORE_RESULTS_TO_RETURN;
5347c478bd9Sstevel@tonic-gate 				break;
5357c478bd9Sstevel@tonic-gate 			}
5367c478bd9Sstevel@tonic-gate 		}
5377c478bd9Sstevel@tonic-gate 	} else {
5387c478bd9Sstevel@tonic-gate 		m = e = NULL;
5397c478bd9Sstevel@tonic-gate 	}
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate 	if ( freeit ) {
5427c478bd9Sstevel@tonic-gate 		ldap_msgfree( res );
5437c478bd9Sstevel@tonic-gate 	}
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	LDAP_SET_LDERRNO( ld, ( err == LDAP_SUCCESS ) ? errcode : err, m, e );
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	return( err );
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate  * returns an LDAP error code indicating success or failure of parsing
5537c478bd9Sstevel@tonic-gate  * does NOT set any error information inside "ld"
5547c478bd9Sstevel@tonic-gate  */
5557c478bd9Sstevel@tonic-gate int
nsldapi_parse_result(LDAP * ld,int msgtype,BerElement * rber,int * errcodep,char ** matchednp,char ** errmsgp,char *** referralsp,LDAPControl *** serverctrlsp)5567c478bd9Sstevel@tonic-gate nsldapi_parse_result( LDAP *ld, int msgtype, BerElement *rber, int *errcodep,
5577c478bd9Sstevel@tonic-gate     char **matchednp, char **errmsgp, char ***referralsp,
5587c478bd9Sstevel@tonic-gate     LDAPControl ***serverctrlsp )
5597c478bd9Sstevel@tonic-gate {
5607c478bd9Sstevel@tonic-gate 	BerElement	ber;
5617c478bd9Sstevel@tonic-gate 	ber_len_t	len;
5627c478bd9Sstevel@tonic-gate 	int		berrc, err, errcode;
5637c478bd9Sstevel@tonic-gate 	ber_int_t	along;
5647c478bd9Sstevel@tonic-gate 	char		*m, *e;
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate 	/*
5677c478bd9Sstevel@tonic-gate 	 * Parse the result message.  LDAPv3 result messages look like this:
5687c478bd9Sstevel@tonic-gate 	 *
5697c478bd9Sstevel@tonic-gate 	 *	LDAPResult ::= SEQUENCE {
5707c478bd9Sstevel@tonic-gate 	 *		resultCode	ENUMERATED { ... },
5717c478bd9Sstevel@tonic-gate 	 *		matchedDN	LDAPDN,
5727c478bd9Sstevel@tonic-gate 	 *		errorMessage	LDAPString,
5737c478bd9Sstevel@tonic-gate 	 *		referral	[3] Referral OPTIONAL
5747c478bd9Sstevel@tonic-gate 	 *		opSpecificStuff	OPTIONAL
5757c478bd9Sstevel@tonic-gate 	 *	}
5767c478bd9Sstevel@tonic-gate 	 *
5777c478bd9Sstevel@tonic-gate 	 * all wrapped up in an LDAPMessage sequence which looks like this:
5787c478bd9Sstevel@tonic-gate 	 *	LDAPMessage ::= SEQUENCE {
5797c478bd9Sstevel@tonic-gate 	 *		messageID	MessageID,
5807c478bd9Sstevel@tonic-gate 	 *		LDAPResult	CHOICE { ... },	// message type
5817c478bd9Sstevel@tonic-gate 	 *		controls	[0] Controls OPTIONAL
5827c478bd9Sstevel@tonic-gate 	 *	}
5837c478bd9Sstevel@tonic-gate 	 *
5847c478bd9Sstevel@tonic-gate 	 * LDAPv2 messages don't include referrals or controls.
5857c478bd9Sstevel@tonic-gate 	 * LDAPv1 messages don't include matchedDN, referrals, or controls.
5867c478bd9Sstevel@tonic-gate 	 *
5877c478bd9Sstevel@tonic-gate 	 * ldap_result() pulls out the message id, so by the time a result
5887c478bd9Sstevel@tonic-gate 	 * message gets here we are sitting at the start of the LDAPResult.
5897c478bd9Sstevel@tonic-gate 	 */
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	err = LDAP_SUCCESS;	/* optimistic */
5927c478bd9Sstevel@tonic-gate 	m = e = NULL;
5937c478bd9Sstevel@tonic-gate 	if ( matchednp != NULL ) {
5947c478bd9Sstevel@tonic-gate 		*matchednp = NULL;
5957c478bd9Sstevel@tonic-gate 	}
5967c478bd9Sstevel@tonic-gate 	if ( errmsgp != NULL ) {
5977c478bd9Sstevel@tonic-gate 		*errmsgp = NULL;
5987c478bd9Sstevel@tonic-gate 	}
5997c478bd9Sstevel@tonic-gate 	if ( referralsp != NULL ) {
6007c478bd9Sstevel@tonic-gate 		*referralsp = NULL;
6017c478bd9Sstevel@tonic-gate 	}
6027c478bd9Sstevel@tonic-gate 	if ( serverctrlsp != NULL ) {
6037c478bd9Sstevel@tonic-gate 		*serverctrlsp = NULL;
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 	ber = *rber;		/* struct copy */
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION2 ) {
6087c478bd9Sstevel@tonic-gate 		berrc = ber_scanf( &ber, "{ia}", &along, &e );
6097c478bd9Sstevel@tonic-gate 		errcode = (int)along;	/* XXX lossy cast */
6107c478bd9Sstevel@tonic-gate 	} else {
6117c478bd9Sstevel@tonic-gate 		if (( berrc = ber_scanf( &ber, "{iaa", &along, &m, &e ))
6127c478bd9Sstevel@tonic-gate 		    != LBER_ERROR ) {
6137c478bd9Sstevel@tonic-gate 			errcode = (int)along;	/* XXX lossy cast */
6147c478bd9Sstevel@tonic-gate 			/* check for optional referrals */
6157c478bd9Sstevel@tonic-gate 			if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_REFERRAL ) {
6167c478bd9Sstevel@tonic-gate 				if ( referralsp == NULL ) {
6177c478bd9Sstevel@tonic-gate 					/* skip referrals */
6187c478bd9Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
6197c478bd9Sstevel@tonic-gate 				} else {
6207c478bd9Sstevel@tonic-gate 					/* suck out referrals */
6217c478bd9Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "v",
6227c478bd9Sstevel@tonic-gate 					    referralsp );
6237c478bd9Sstevel@tonic-gate 				}
6247c478bd9Sstevel@tonic-gate 			} else if ( referralsp != NULL ) {
6257c478bd9Sstevel@tonic-gate 				*referralsp = NULL;
6267c478bd9Sstevel@tonic-gate 			}
6277c478bd9Sstevel@tonic-gate 		}
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 		if ( berrc != LBER_ERROR ) {
6307c478bd9Sstevel@tonic-gate 			/*
6317c478bd9Sstevel@tonic-gate 			 * skip past optional operation-specific elements:
6327c478bd9Sstevel@tonic-gate 			 *   bind results - serverSASLcreds
6337c478bd9Sstevel@tonic-gate 			 *   extendedop results -  OID plus value
6347c478bd9Sstevel@tonic-gate 			 */
6357c478bd9Sstevel@tonic-gate 			if ( msgtype == LDAP_RES_BIND ) {
636*1da57d55SToomas Soome 				if ( ber_peek_tag( &ber, &len ) ==
6377c478bd9Sstevel@tonic-gate 				    LDAP_TAG_SASL_RES_CREDS ) {
6387c478bd9Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
6397c478bd9Sstevel@tonic-gate 				}
6407c478bd9Sstevel@tonic-gate 			} else if ( msgtype == LDAP_RES_EXTENDED ) {
6417c478bd9Sstevel@tonic-gate 				if ( ber_peek_tag( &ber, &len ) ==
6427c478bd9Sstevel@tonic-gate 				    LDAP_TAG_EXOP_RES_OID ) {
6437c478bd9Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
6447c478bd9Sstevel@tonic-gate 				}
6457c478bd9Sstevel@tonic-gate 				if ( berrc != LBER_ERROR &&
6467c478bd9Sstevel@tonic-gate 				    ber_peek_tag( &ber, &len ) ==
6477c478bd9Sstevel@tonic-gate 				    LDAP_TAG_EXOP_RES_VALUE ) {
6487c478bd9Sstevel@tonic-gate 					berrc = ber_scanf( &ber, "x" );
6497c478bd9Sstevel@tonic-gate 				}
6507c478bd9Sstevel@tonic-gate 			}
6517c478bd9Sstevel@tonic-gate 		}
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 		/* pull out controls (if requested and any are present) */
6547c478bd9Sstevel@tonic-gate 		if ( berrc != LBER_ERROR && serverctrlsp != NULL &&
6557c478bd9Sstevel@tonic-gate 		    ( berrc = ber_scanf( &ber, "}" )) != LBER_ERROR ) {
6567c478bd9Sstevel@tonic-gate 			err = nsldapi_get_controls( &ber, serverctrlsp );
6577c478bd9Sstevel@tonic-gate 		}
6587c478bd9Sstevel@tonic-gate 	}
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	if ( berrc == LBER_ERROR && err == LDAP_SUCCESS ) {
6617c478bd9Sstevel@tonic-gate 		err = LDAP_DECODING_ERROR;
6627c478bd9Sstevel@tonic-gate 	}
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	if ( errcodep != NULL ) {
6657c478bd9Sstevel@tonic-gate 		*errcodep = errcode;
6667c478bd9Sstevel@tonic-gate 	}
6677c478bd9Sstevel@tonic-gate 	if ( matchednp != NULL ) {
6687c478bd9Sstevel@tonic-gate 		*matchednp = m;
6697c478bd9Sstevel@tonic-gate 	} else if ( m != NULL ) {
6707c478bd9Sstevel@tonic-gate 		NSLDAPI_FREE( m );
6717c478bd9Sstevel@tonic-gate 	}
6727c478bd9Sstevel@tonic-gate 	if ( errmsgp != NULL ) {
6737c478bd9Sstevel@tonic-gate 		*errmsgp = e;
6747c478bd9Sstevel@tonic-gate 	} else if ( e != NULL ) {
6757c478bd9Sstevel@tonic-gate 		NSLDAPI_FREE( e );
6767c478bd9Sstevel@tonic-gate 	}
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	return( err );
6797c478bd9Sstevel@tonic-gate }
680