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