1/*
2 * Portions Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6#pragma ident	"%Z%%M%	%I%	%E% SMI"
7
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h> /* free() for Solaris */
11#ifdef MACOS
12#include <stdlib.h>
13#else /* MACOS */
14#if defined( DOS ) || defined( _WIN32 )
15#include <malloc.h>
16#include "msdos.h"
17#else /* DOS */
18#include <sys/types.h>
19#include <sys/socket.h>
20#endif /* DOS */
21#endif /* MACOS */
22#include "lber.h"
23#include "ldap.h"
24#include "ldap-private.h"
25#include "ldap-int.h"
26
27struct ldaperror {
28	int	e_code;
29	char	*e_reason;
30};
31
32static struct ldaperror ldap_errlist[] = {
33#ifdef SUN
34	LDAP_SUCCESS, 			0,
35	LDAP_OPERATIONS_ERROR, 		0,
36	LDAP_PROTOCOL_ERROR, 		0,
37	LDAP_TIMELIMIT_EXCEEDED,	0,
38	LDAP_SIZELIMIT_EXCEEDED, 	0,
39	LDAP_COMPARE_FALSE, 		0,
40	LDAP_COMPARE_TRUE, 		0,
41	LDAP_AUTH_METHOD_NOT_SUPPORTED, 0,
42	LDAP_STRONG_AUTH_REQUIRED, 	0,
43	LDAP_PARTIAL_RESULTS, 		0,
44/* new with ldapv3 */
45	LDAP_REFERRAL,			0,
46	LDAP_ADMINLIMIT_EXCEEDED,	0,
47	LDAP_UNAVAILABLE_CRITICAL_EXTENSION, 	0,
48	LDAP_CONFIDENTIALITY_REQUIRED,	0,
49/* end of new */
50	LDAP_NO_SUCH_ATTRIBUTE, 	0,
51	LDAP_UNDEFINED_TYPE, 		0,
52	LDAP_INAPPROPRIATE_MATCHING, 	0,
53	LDAP_CONSTRAINT_VIOLATION, 	0,
54	LDAP_TYPE_OR_VALUE_EXISTS, 	0,
55	LDAP_INVALID_SYNTAX, 		0,
56	LDAP_NO_SUCH_OBJECT, 		0,
57	LDAP_ALIAS_PROBLEM, 		0,
58	LDAP_INVALID_DN_SYNTAX,		0,
59	LDAP_IS_LEAF, 			0,
60	LDAP_ALIAS_DEREF_PROBLEM, 	0,
61	LDAP_INAPPROPRIATE_AUTH, 	0,
62	LDAP_INVALID_CREDENTIALS, 	0,
63	LDAP_INSUFFICIENT_ACCESS, 	0,
64	LDAP_BUSY, 			0,
65	LDAP_UNAVAILABLE, 		0,
66	LDAP_UNWILLING_TO_PERFORM, 	0,
67	LDAP_LOOP_DETECT, 		0,
68	LDAP_NAMING_VIOLATION, 		0,
69	LDAP_OBJECT_CLASS_VIOLATION, 	0,
70	LDAP_NOT_ALLOWED_ON_NONLEAF, 	0,
71	LDAP_NOT_ALLOWED_ON_RDN, 	0,
72	LDAP_ALREADY_EXISTS, 		0,
73	LDAP_NO_OBJECT_CLASS_MODS, 	0,
74	LDAP_RESULTS_TOO_LARGE,		0,
75/* new with ldapv3 */
76	LDAP_AFFECTS_MULTIPLE_DSAS, 0,
77/* end of new */
78	LDAP_OTHER, 			0,
79	LDAP_SERVER_DOWN,		0,
80	LDAP_LOCAL_ERROR,		0,
81	LDAP_ENCODING_ERROR,		0,
82	LDAP_DECODING_ERROR,		0,
83	LDAP_TIMEOUT,			0,
84	LDAP_AUTH_UNKNOWN,		0,
85	LDAP_FILTER_ERROR,		0,
86	LDAP_USER_CANCELLED,		0,
87	LDAP_PARAM_ERROR,		0,
88	LDAP_NO_MEMORY,			0,
89/* new with ldapv3 */
90	LDAP_CONNECT_ERROR,		0,
91	LDAP_NOT_SUPPORTED,		0,
92	LDAP_CONTROL_NOT_FOUND,	0,
93	LDAP_NO_RESULTS_RETURNED,	0,
94	LDAP_MORE_RESULTS_TO_RETURN,	0,
95	LDAP_CLIENT_LOOP,		0,
96	LDAP_REFERRAL_LIMIT_EXCEEDED,	0,
97/* end of new */
98#else
99	LDAP_SUCCESS, 			"Success",
100	LDAP_OPERATIONS_ERROR, 		"Operations error",
101	LDAP_PROTOCOL_ERROR, 		"Protocol error",
102	LDAP_TIMELIMIT_EXCEEDED,	"Timelimit exceeded",
103	LDAP_SIZELIMIT_EXCEEDED, 	"Sizelimit exceeded",
104	LDAP_COMPARE_FALSE, 		"Compare false",
105	LDAP_COMPARE_TRUE, 		"Compare true",
106	LDAP_AUTH_METHOD_NOT_SUPPORTED, "Authentication method not supported",
107	LDAP_STRONG_AUTH_REQUIRED, 	"Strong authentication required",
108	LDAP_PARTIAL_RESULTS, 		"Partial results and referral received",
109/* new with ldapv3 */
110	LDAP_REFERRAL,			"Referral received",
111	LDAP_ADMINLIMIT_EXCEEDED,	"Admin. limit exceeded",
112	LDAP_UNAVAILABLE_CRITICAL_EXTENSION, 	"Unavailable critical extension",
113	LDAP_CONFIDENTIALITY_REQUIRED,	"Confidentiality required",
114/* end of new */
115	LDAP_NO_SUCH_ATTRIBUTE, 	"No such attribute",
116	LDAP_UNDEFINED_TYPE, 		"Undefined attribute type",
117	LDAP_INAPPROPRIATE_MATCHING, 	"Inappropriate matching",
118	LDAP_CONSTRAINT_VIOLATION, 	"Constraint violation",
119	LDAP_TYPE_OR_VALUE_EXISTS, 	"Type or value exists",
120	LDAP_INVALID_SYNTAX, 		"Invalid syntax",
121	LDAP_NO_SUCH_OBJECT, 		"No such object",
122	LDAP_ALIAS_PROBLEM, 		"Alias problem",
123	LDAP_INVALID_DN_SYNTAX,		"Invalid DN syntax",
124	LDAP_IS_LEAF, 			"Object is a leaf",
125	LDAP_ALIAS_DEREF_PROBLEM, 	"Alias dereferencing problem",
126	LDAP_INAPPROPRIATE_AUTH, 	"Inappropriate authentication",
127	LDAP_INVALID_CREDENTIALS, 	"Invalid credentials",
128	LDAP_INSUFFICIENT_ACCESS, 	"Insufficient access",
129	LDAP_BUSY, 			"DSA is busy",
130	LDAP_UNAVAILABLE, 		"DSA is unavailable",
131	LDAP_UNWILLING_TO_PERFORM, 	"DSA is unwilling to perform",
132	LDAP_LOOP_DETECT, 		"Loop detected",
133	LDAP_NAMING_VIOLATION, 		"Naming violation",
134	LDAP_OBJECT_CLASS_VIOLATION, 	"Object class violation",
135	LDAP_NOT_ALLOWED_ON_NONLEAF, 	"Operation not allowed on nonleaf",
136	LDAP_NOT_ALLOWED_ON_RDN, 	"Operation not allowed on RDN",
137	LDAP_ALREADY_EXISTS, 		"Already exists",
138	LDAP_NO_OBJECT_CLASS_MODS, 	"Cannot modify object class",
139	LDAP_RESULTS_TOO_LARGE,		"Results too large",
140/* new with ldapv3 */
141	LDAP_AFFECTS_MULTIPLE_DSAS, "Affects multiple DSAs",
142/* end of new */
143	LDAP_OTHER, 			"Unknown error",
144	LDAP_SERVER_DOWN,		"Can't contact LDAP server",
145	LDAP_LOCAL_ERROR,		"Local error",
146	LDAP_ENCODING_ERROR,		"Encoding error",
147	LDAP_DECODING_ERROR,		"Decoding error",
148	LDAP_TIMEOUT,			"Timed out",
149	LDAP_AUTH_UNKNOWN,		"Unknown authentication method",
150	LDAP_FILTER_ERROR,		"Bad search filter",
151	LDAP_USER_CANCELLED,		"User cancelled operation",
152	LDAP_PARAM_ERROR,		"Bad parameter to an ldap routine",
153	LDAP_NO_MEMORY,			"Out of memory",
154/* new with ldapv3 */
155	LDAP_CONNECT_ERROR,		"Connection error",
156	LDAP_NOT_SUPPORTED,		"Not supported",
157	LDAP_CONTROL_NOT_FOUND,	"Control not found",
158	LDAP_NO_RESULTS_RETURNED,	"No results have been returned",
159	LDAP_MORE_RESULTS_TO_RETURN,	"More results to return",
160	LDAP_CLIENT_LOOP,		"Loop detected in referrals",
161	LDAP_REFERRAL_LIMIT_EXCEEDED,	"Too many referrals followed",
162/* end of new */
163#endif
164	-1, 0
165};
166
167#ifdef SUN
168#pragma init	(fill_ldap_errlist)
169
170static void fill_ldap_errlist()
171{
172	int i=0;
173	Debug(LDAP_DEBUG_TRACE, "fill_ldap_errlist\n", 0, 0, 0 );
174	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 130, "Success");
175	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 131, "Operations error");
176	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 132, "Protocol error");
177	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 133, "Timelimit exceeded");
178	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 134, "Sizelimit exceeded");
179	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 135, "Compare false");
180	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 136, "Compare true");
181	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 137, "Strong authentication not supported");
182	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 138, "Strong authentication required");
183	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 139, "Partial results and referral received");
184/* new with ldapv3 */
185	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1262, "Referral received");
186	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1263, "Admin. limit exceeded");
187	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1264, "Unavailable critical extension");
188	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1265, "Confidentiality required");
189/* end of new */
190	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 140, "No such attribute");
191	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 141, "Undefined attribute type");
192	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 142, "Inappropriate matching");
193	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 143, "Constraint violation");
194	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 144, "Type or value exists");
195	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 145, "Invalid syntax");
196	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 146, "No such object");
197	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 147, "Alias problem");
198	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 148, "Invalid DN syntax");
199	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 149, "Object is a leaf");
200	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 150, "Alias dereferencing problem");
201	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 151, "Inappropriate authentication");
202	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 152, "Invalid credentials");
203	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 153, "Insufficient access");
204	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 154, "DSA is busy");
205	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 155, "DSA is unavailable");
206	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 156, "DSA is unwilling to perform");
207	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 157, "Loop detected");
208	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 158, "Naming violation");
209	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 159, "Object class violation");
210	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 160, "Operation not allowed on nonleaf");
211	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 161, "Operation not allowed on RDN");
212	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 162, "Already exists");
213	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 163, "Cannot modify object class");
214	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 164, "Results too large");
215/* new with ldapv3 */
216	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1266, "Affects multiple DSAs");
217/* end of new */
218	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 165, "Unknown error");
219	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 166, "Can't contact LDAP server");
220	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 167, "Local error");
221	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 168, "Encoding error");
222	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 169, "Decoding error");
223	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 170, "Timed out");
224	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 171, "Unknown authentication method");
225	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 172, "Bad search filter");
226	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 173, "User cancelled operation");
227	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 174, "Bad parameter to an ldap routine");
228	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 175, "Out of memory");
229
230	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1267, "Connection error");
231	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1268, "Not supported");
232	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1269, "Control not found");
233	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1270, "No results have been returned");
234	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1271, "More results to return");
235	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1272, "Loop detected in referrals");
236	ldap_errlist[i++].e_reason = catgets(slapdcat, 1, 1273, "Too many referrals followed");
237}
238#endif
239
240char *
241ldap_err2string( int err )
242{
243	int	i;
244
245	Debug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
246
247	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
248		if ( err == ldap_errlist[i].e_code )
249			return( ldap_errlist[i].e_reason );
250	}
251
252	return( catgets(slapdcat, 1 , 165, "Unknown error") );
253}
254
255#ifndef NO_USERINTERFACE
256void
257ldap_perror( LDAP *ld, char *s )
258{
259	int	i;
260
261	Debug( LDAP_DEBUG_TRACE, "ldap_perror\n", 0, 0, 0 );
262
263	if ( ld == NULL ) {
264		perror( s );
265		return;
266	}
267#ifdef SUN
268	/* for I18N */
269	if ( ldap_errlist[0].e_reason == NULL ) {
270		fill_ldap_errlist();
271	} /* end if */
272#endif
273
274	for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
275		if ( ld->ld_errno == ldap_errlist[i].e_code ) {
276			(void) fprintf( stderr, "%s: %s\n", s,
277			    ldap_errlist[i].e_reason );
278			if ( ld->ld_matched != NULL && *ld->ld_matched != '\0' )
279				(void) fprintf( stderr, catgets(slapdcat, 1, 176, "%1$s: matched: %2$s\n"), s,
280				    ld->ld_matched );
281			if ( ld->ld_error != NULL && *ld->ld_error != '\0' )
282				(void) fprintf( stderr, catgets(slapdcat, 1, 177, "%1$s: additional info: %2$s\n"),
283				    s, ld->ld_error );
284			(void) fflush( stderr );
285			return;
286		}
287	}
288
289	(void) fprintf( stderr, catgets(slapdcat, 1, 178, "%1$s: Not an LDAP errno %2$d\n"), s, ld->ld_errno );
290	(void) fflush( stderr );
291}
292
293#else
294
295void
296ldap_perror( LDAP *ld, char *s )
297{
298}
299
300#endif /* NO_USERINTERFACE */
301
302
303int
304ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
305{
306	LDAPMessage	*lm;
307	BerElement	ber;
308	int		along;
309	int		rc;
310
311	Debug( LDAP_DEBUG_TRACE, "ldap_result2error\n", 0, 0, 0 );
312
313	if ( r == NULLMSG )
314		return( LDAP_PARAM_ERROR );
315
316	for ( lm = r; lm->lm_chain != NULL; lm = lm->lm_chain )
317		;	/* NULL */
318
319	if ( ld->ld_error ) {
320		free( ld->ld_error );
321		ld->ld_error = NULL;
322	}
323	if ( ld->ld_matched ) {
324		free( ld->ld_matched );
325		ld->ld_matched = NULL;
326	}
327
328	ber = *(lm->lm_ber);
329	if ( ld->ld_version == LDAP_VERSION2 ) {
330		rc = ber_scanf( &ber, "{iaa}", &along, &ld->ld_matched,
331		    &ld->ld_error );
332	} else {
333		rc = ber_scanf( &ber, "{ia}", &along, &ld->ld_error );
334	}
335	if ( rc == LBER_ERROR ) {
336		ld->ld_errno = LDAP_DECODING_ERROR;
337	} else {
338		ld->ld_errno = along;
339	}
340
341	if ( freeit )
342		ldap_msgfree( r );
343
344	return( ld->ld_errno );
345}
346