1/*
2 * Copyright (c) 2001, 2003 Proofpoint, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 */
12
13#include <sm/gen.h>
14SM_RCSID("@(#)$Id: errstring.c,v 1.20 2013-11-22 20:51:42 ca Exp $")
15
16#include <errno.h>
17#include <stdio.h>	/* sys_errlist, on some platforms */
18
19#include <sm/io.h>	/* sm_snprintf */
20#include <sm/string.h>
21#include <sm/errstring.h>
22
23#if NAMED_BIND
24# include <netdb.h>
25#endif
26
27#if LDAPMAP
28# include <lber.h>
29# include <ldap.h>			/* for LDAP error codes */
30#endif
31
32/*
33**  Notice: this file is used by libmilter. Please try to avoid
34**	using libsm specific functions.
35*/
36
37/*
38**  SM_ERRSTRING -- return string description of error code
39**
40**	Parameters:
41**		errnum -- the error number to translate
42**
43**	Returns:
44**		A string description of errnum.
45**
46**	Note: this may point to a local (static) buffer.
47*/
48
49const char *
50sm_errstring(errnum)
51	int errnum;
52{
53	char *ret;
54
55
56	switch (errnum)
57	{
58	  case EPERM:
59		/* SunOS gives "Not owner" -- this is the POSIX message */
60		return "Operation not permitted";
61
62	/*
63	**  Error messages used internally in sendmail.
64	*/
65
66	  case E_SM_OPENTIMEOUT:
67		return "Timeout on file open";
68
69	  case E_SM_NOSLINK:
70		return "Symbolic links not allowed";
71
72	  case E_SM_NOHLINK:
73		return "Hard links not allowed";
74
75	  case E_SM_REGONLY:
76		return "Regular files only";
77
78	  case E_SM_ISEXEC:
79		return "Executable files not allowed";
80
81	  case E_SM_WWDIR:
82		return "World writable directory";
83
84	  case E_SM_GWDIR:
85		return "Group writable directory";
86
87	  case E_SM_FILECHANGE:
88		return "File changed after open";
89
90	  case E_SM_WWFILE:
91		return "World writable file";
92
93	  case E_SM_GWFILE:
94		return "Group writable file";
95
96	  case E_SM_GRFILE:
97		return "Group readable file";
98
99	  case E_SM_WRFILE:
100		return "World readable file";
101
102	/*
103	**  DNS error messages.
104	*/
105
106#if NAMED_BIND
107	  case HOST_NOT_FOUND + E_DNSBASE:
108		return "Name server: host not found";
109
110	  case TRY_AGAIN + E_DNSBASE:
111		return "Name server: host name lookup failure";
112
113	  case NO_RECOVERY + E_DNSBASE:
114		return "Name server: non-recoverable error";
115
116	  case NO_DATA + E_DNSBASE:
117		return "Name server: no data known";
118#endif /* NAMED_BIND */
119
120	/*
121	**  libsmdb error messages.
122	*/
123
124	  case SMDBE_MALLOC:
125		return "Memory allocation failed";
126
127	  case SMDBE_GDBM_IS_BAD:
128		return "GDBM is not supported";
129
130	  case SMDBE_UNSUPPORTED:
131		return "Unsupported action";
132
133	  case SMDBE_DUPLICATE:
134		return "Key already exists";
135
136	  case SMDBE_BAD_OPEN:
137		return "Database open failed";
138
139	  case SMDBE_NOT_FOUND:
140		return "Key not found";
141
142	  case SMDBE_UNKNOWN_DB_TYPE:
143		return "Unknown database type";
144
145	  case SMDBE_UNSUPPORTED_DB_TYPE:
146		return "Support for database type not compiled into this program";
147
148	  case SMDBE_INCOMPLETE:
149		return "DB sync did not finish";
150
151	  case SMDBE_KEY_EMPTY:
152		return "Key is empty";
153
154	  case SMDBE_KEY_EXIST:
155		return "Key already exists";
156
157	  case SMDBE_LOCK_DEADLOCK:
158		return "Locker killed to resolve deadlock";
159
160	  case SMDBE_LOCK_NOT_GRANTED:
161		return "Lock unavailable";
162
163	  case SMDBE_LOCK_NOT_HELD:
164		return "Lock not held by locker";
165
166	  case SMDBE_RUN_RECOVERY:
167		return "Database panic, run recovery";
168
169	  case SMDBE_IO_ERROR:
170		return "I/O error";
171
172	  case SMDBE_READ_ONLY:
173		return "Database opened read-only";
174
175	  case SMDBE_DB_NAME_TOO_LONG:
176		return "Name too long";
177
178	  case SMDBE_INVALID_PARAMETER:
179		return "Invalid parameter";
180
181	  case SMDBE_ONLY_SUPPORTS_ONE_CURSOR:
182		return "Only one cursor allowed";
183
184	  case SMDBE_NOT_A_VALID_CURSOR:
185		return "Invalid cursor";
186
187	  case SMDBE_OLD_VERSION:
188		return "Berkeley DB file is an old version, recreate it";
189
190	  case SMDBE_VERSION_MISMATCH:
191		return "Berkeley DB version mismatch between include file and library";
192
193#if LDAPMAP
194
195	/*
196	**  LDAP URL error messages.
197	*/
198
199	/* OpenLDAP errors */
200# ifdef LDAP_URL_ERR_MEM
201	  case E_LDAPURLBASE + LDAP_URL_ERR_MEM:
202		return "LDAP URL can't allocate memory space";
203# endif
204
205# ifdef LDAP_URL_ERR_PARAM
206	  case E_LDAPURLBASE + LDAP_URL_ERR_PARAM:
207		return "LDAP URL parameter is bad";
208# endif
209
210# ifdef LDAP_URL_ERR_BADSCHEME
211	  case E_LDAPURLBASE + LDAP_URL_ERR_BADSCHEME:
212		return "LDAP URL doesn't begin with \"ldap[si]://\"";
213# endif
214
215# ifdef LDAP_URL_ERR_BADENCLOSURE
216	  case E_LDAPURLBASE + LDAP_URL_ERR_BADENCLOSURE:
217		return "LDAP URL is missing trailing \">\"";
218# endif
219
220# ifdef LDAP_URL_ERR_BADURL
221	  case E_LDAPURLBASE + LDAP_URL_ERR_BADURL:
222		return "LDAP URL is bad";
223# endif
224
225# ifdef LDAP_URL_ERR_BADHOST
226	  case E_LDAPURLBASE + LDAP_URL_ERR_BADHOST:
227		return "LDAP URL host port is bad";
228# endif
229
230# ifdef LDAP_URL_ERR_BADATTRS
231	  case E_LDAPURLBASE + LDAP_URL_ERR_BADATTRS:
232		return "LDAP URL bad (or missing) attributes";
233# endif
234
235# ifdef LDAP_URL_ERR_BADSCOPE
236	  case E_LDAPURLBASE + LDAP_URL_ERR_BADSCOPE:
237		return "LDAP URL scope string is invalid (or missing)";
238# endif
239
240# ifdef LDAP_URL_ERR_BADFILTER
241	  case E_LDAPURLBASE + LDAP_URL_ERR_BADFILTER:
242		return "LDAP URL bad or missing filter";
243# endif
244
245# ifdef LDAP_URL_ERR_BADEXTS
246	  case E_LDAPURLBASE + LDAP_URL_ERR_BADEXTS:
247		return "LDAP URL bad or missing extensions";
248# endif
249
250	/* Sun LDAP errors */
251# ifdef LDAP_URL_ERR_NOTLDAP
252	  case E_LDAPURLBASE + LDAP_URL_ERR_NOTLDAP:
253		return "LDAP URL doesn't begin with \"ldap://\"";
254# endif
255
256# ifdef LDAP_URL_ERR_NODN
257	  case E_LDAPURLBASE + LDAP_URL_ERR_NODN:
258		return "LDAP URL has no DN (required)";
259# endif
260
261#endif /* LDAPMAP */
262	}
263
264#if LDAPMAP
265
266	/*
267	**  LDAP error messages.  Handle small negative errors from
268	**  libldap (in the range -E_LDAP_SHIM to zero, offset by E_LDAPBASE)
269	**  as well.
270	*/
271
272	if (errnum >= E_LDAPBASE - E_LDAP_SHIM)
273		return ldap_err2string(errnum - E_LDAPBASE);
274#endif /* LDAPMAP */
275
276	ret = strerror(errnum);
277	if (ret == NULL)
278	{
279		static char buf[30];
280
281		(void) sm_snprintf(buf, sizeof buf, "Error %d", errnum);
282		return buf;
283	}
284	return ret;
285}
286