xref: /titanic_41/usr/src/lib/libnsl/rpc/clnt_perror.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28  * Portions of this source code were derived from Berkeley
29  * 4.3 BSD under license from the Regents of the University of
30  * California.
31  */
32 
33 #pragma ident	"%Z%%M%	%I%	%E% SMI"
34 
35 /*
36  * clnt_perror.c
37  *
38  */
39 
40 #include "mt.h"
41 #include "rpc_mt.h"
42 #ifndef KERNEL
43 #include <stdio.h>
44 #include <libintl.h>
45 #include <string.h>
46 #endif
47 
48 #include <rpc/types.h>
49 #include <rpc/trace.h>
50 #include <rpc/auth.h>
51 #include <sys/tiuser.h>
52 #include <rpc/clnt.h>
53 #include <stdlib.h>
54 #include <syslog.h>
55 #include <string.h>
56 
57 extern char *netdir_sperror();
58 
59 const char __nsl_dom[]  = "SUNW_OST_NETRPC";
60 
61 #ifndef KERNEL
62 
63 #define	ERRBUFSZ	512
64 
65 static char *
66 __buf()
67 {
68 	char *buf;
69 	static char buf_main[ERRBUFSZ];
70 	static pthread_key_t perror_key;
71 
72 	trace1(TR___buf, 0);
73 	buf = thr_main()? buf_main :
74 		thr_get_storage(&perror_key, ERRBUFSZ, free);
75 	if (buf == NULL)
76 		syslog(LOG_WARNING,
77 		"clnt_sperror: malloc failed when trying to create buffer\n");
78 	trace1(TR___buf, 1);
79 	return (buf);
80 }
81 
82 static char *
83 auth_errmsg(stat)
84 	enum auth_stat stat;
85 {
86 	trace1(TR_auth_errmsg, 0);
87 	switch (stat) {
88 	case AUTH_OK:
89 		trace1(TR_auth_errmsg, 1);
90 		return (dgettext(__nsl_dom, "Authentication OK"));
91 	case AUTH_BADCRED:
92 		trace1(TR_auth_errmsg, 1);
93 		return (dgettext(__nsl_dom, "Invalid client credential"));
94 	case AUTH_REJECTEDCRED:
95 		trace1(TR_auth_errmsg, 1);
96 		return (dgettext(__nsl_dom, "Server rejected credential"));
97 	case AUTH_BADVERF:
98 		trace1(TR_auth_errmsg, 1);
99 		return (dgettext(__nsl_dom, "Invalid client verifier"));
100 	case AUTH_REJECTEDVERF:
101 		trace1(TR_auth_errmsg, 1);
102 		return (dgettext(__nsl_dom, "Server rejected verifier"));
103 	case AUTH_TOOWEAK:
104 		trace1(TR_auth_errmsg, 1);
105 		return (dgettext(__nsl_dom, "Client credential too weak"));
106 	case AUTH_INVALIDRESP:
107 		trace1(TR_auth_errmsg, 1);
108 		return (dgettext(__nsl_dom, "Invalid server verifier"));
109 	case AUTH_FAILED:
110 		trace1(TR_auth_errmsg, 1);
111 		return (dgettext(__nsl_dom, "Failed (unspecified error)"));
112 
113 	/* kerberos specific */
114 	case AUTH_DECODE:
115 		trace1(TR_auth_errmsg, 1);
116 		return (dgettext(__nsl_dom, "Could not decode authenticator"));
117 	case AUTH_TIMEEXPIRE:
118 		trace1(TR_auth_errmsg, 1);
119 		return (dgettext(__nsl_dom, "Time of credential expired"));
120 	case AUTH_TKT_FILE:
121 		trace1(TR_auth_errmsg, 1);
122 		return (dgettext(__nsl_dom,
123 			"Something wrong with kerberos ticket file"));
124 	case AUTH_NET_ADDR:
125 		trace1(TR_auth_errmsg, 1);
126 		return (dgettext(__nsl_dom,
127 		"Incorrect network address in kerberos ticket"));
128 	case AUTH_KERB_GENERIC:
129 		trace1(TR_auth_errmsg, 1);
130 		return (dgettext(__nsl_dom, "Kerberos generic error"));
131 	}
132 	trace1(TR_auth_errmsg, 1);
133 	return (dgettext(__nsl_dom, "Unknown authentication error"));
134 }
135 
136 /*
137  * Return string reply error info. For use after clnt_call()
138  */
139 
140 #define	REMAINDER	(ERRBUFSZ - (str - strstart))
141 
142 char *
143 clnt_sperror(cl, s)
144 	const CLIENT *cl;
145 	const char *s;
146 {
147 	struct rpc_err e;
148 	char *err;
149 	char *str = __buf();
150 	char *strstart = str;
151 
152 	trace2(TR_clnt_sperror, 0, cl);
153 	if (str == NULL) {
154 		trace2(TR_clnt_sperror, 1, cl);
155 		return (NULL);
156 	}
157 	CLNT_GETERR((CLIENT *) cl, &e);
158 
159 	(void) snprintf(str, ERRBUFSZ, "%s: ", s);
160 	str += strlcat(str, clnt_sperrno(e.re_status), ERRBUFSZ);
161 
162 	switch (e.re_status) {
163 	case RPC_SUCCESS:
164 	case RPC_CANTENCODEARGS:
165 	case RPC_CANTDECODERES:
166 	case RPC_TIMEDOUT:
167 	case RPC_PROGUNAVAIL:
168 	case RPC_PROCUNAVAIL:
169 	case RPC_CANTDECODEARGS:
170 	case RPC_SYSTEMERROR:
171 	case RPC_UNKNOWNHOST:
172 	case RPC_UNKNOWNPROTO:
173 	case RPC_UNKNOWNADDR:
174 	case RPC_NOBROADCAST:
175 	case RPC_RPCBFAILURE:
176 	case RPC_PROGNOTREGISTERED:
177 	case RPC_FAILED:
178 		break;
179 
180 	case RPC_N2AXLATEFAILURE:
181 		(void) snprintf(str, REMAINDER, "; %s", netdir_sperror());
182 		str += strlen(str);
183 		break;
184 
185 	case RPC_TLIERROR:
186 		(void) snprintf(str, REMAINDER, "; %s", t_errlist[e.re_terrno]);
187 		str += strlen(str);
188 		if (e.re_errno) {
189 			(void) snprintf(str, REMAINDER,
190 			    "; %s", strerror(e.re_errno));
191 			str += strlen(str);
192 		}
193 		break;
194 
195 	case RPC_CANTSTORE:
196 	case RPC_CANTSEND:
197 	case RPC_CANTRECV:
198 		if (e.re_errno) {
199 			(void) snprintf(str, REMAINDER, "; errno = %s",
200 					strerror(e.re_errno));
201 			str += strlen(str);
202 		}
203 		if (e.re_terrno) {
204 			(void) snprintf(str, REMAINDER,
205 				"; %s", t_errlist[e.re_terrno]);
206 			str += strlen(str);
207 		}
208 		break;
209 
210 	case RPC_VERSMISMATCH:
211 		(void) snprintf(str, REMAINDER,
212 				"; low version = %lu, high version = %lu",
213 				e.re_vers.low, e.re_vers.high);
214 		str += strlen(str);
215 		break;
216 
217 	case RPC_AUTHERROR:
218 		err = auth_errmsg(e.re_why);
219 		(void) snprintf(str, REMAINDER, "; why = ");
220 		str += strlen(str);
221 		if (err != NULL) {
222 			(void) snprintf(str, REMAINDER, "%s", err);
223 		} else {
224 			(void) snprintf(str, REMAINDER,
225 				"(unknown authentication error - %d)",
226 				(int)e.re_why);
227 		}
228 		str += strlen(str);
229 		break;
230 
231 	case RPC_PROGVERSMISMATCH:
232 		(void) snprintf(str, REMAINDER,
233 				"; low version = %lu, high version = %lu",
234 				e.re_vers.low, e.re_vers.high);
235 		str += strlen(str);
236 		break;
237 
238 	default:	/* unknown */
239 		(void) snprintf(str, REMAINDER, "; s1 = %lu, s2 = %lu",
240 				e.re_lb.s1, e.re_lb.s2);
241 		str += strlen(str);
242 		break;
243 	}
244 	trace2(TR_clnt_sperror, 1, cl);
245 	return (strstart);
246 }
247 #undef	REMAINDER
248 
249 void
250 clnt_perror(cl, s)
251 	const CLIENT *cl;
252 	const char *s;
253 {
254 	trace2(TR_clnt_perror, 0, cl);
255 	(void) fprintf(stderr, "%s\n", clnt_sperror(cl, s));
256 	trace2(TR_clnt_perror, 1, cl);
257 }
258 
259 void
260 clnt_perrno(num)
261 	enum clnt_stat num;
262 {
263 	trace1(TR_clnt_perrno, 0);
264 	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
265 	trace1(TR_clnt_perrno, 1);
266 }
267 
268 /*
269  * Why a client handle could not be created
270  */
271 char *
272 clnt_spcreateerror(s)
273 	const char *s;
274 {
275 	char *errstr;
276 	char *str = __buf();
277 
278 	trace1(TR_clnt_spcreateerror, 0);
279 	if (str == NULL) {
280 		trace1(TR_clnt_spcreateerror, 1);
281 		return (NULL);
282 	}
283 	(void) snprintf(str, ERRBUFSZ, "%s: ", s);
284 	(void) strlcat(str, clnt_sperrno(rpc_createerr.cf_stat), ERRBUFSZ);
285 
286 	switch (rpc_createerr.cf_stat) {
287 	case RPC_N2AXLATEFAILURE:
288 		(void) strlcat(str, " - ", ERRBUFSZ);
289 		(void) strlcat(str, netdir_sperror(), ERRBUFSZ);
290 		break;
291 
292 	case RPC_RPCBFAILURE:
293 		(void) strlcat(str, " - ", ERRBUFSZ);
294 		(void) strlcat(str,
295 			clnt_sperrno(rpc_createerr.cf_error.re_status),
296 			ERRBUFSZ);
297 		break;
298 
299 	case RPC_SYSTEMERROR:
300 		(void) strlcat(str, " - ", ERRBUFSZ);
301 		errstr = strerror(rpc_createerr.cf_error.re_errno);
302 		if (errstr != NULL)
303 			(void) strlcat(str, errstr, ERRBUFSZ);
304 		else
305 			(void) snprintf(&str[strlen(str)],
306 			    ERRBUFSZ - strlen(str), "Error %d",
307 			    rpc_createerr.cf_error.re_errno);
308 		break;
309 
310 	case RPC_TLIERROR:
311 		(void) strlcat(str, " - ", ERRBUFSZ);
312 		if ((rpc_createerr.cf_error.re_terrno > 0) &&
313 			(rpc_createerr.cf_error.re_terrno < t_nerr)) {
314 			(void) strlcat(str,
315 				t_errlist[rpc_createerr.cf_error.re_terrno],
316 				ERRBUFSZ);
317 			if (rpc_createerr.cf_error.re_terrno == TSYSERR) {
318 				char *err;
319 				err = strerror(rpc_createerr.cf_error.re_errno);
320 				if (err) {
321 					strlcat(str, " (", ERRBUFSZ);
322 					strlcat(str, err, ERRBUFSZ);
323 					strlcat(str, ")", ERRBUFSZ);
324 				}
325 			}
326 		} else {
327 			(void) snprintf(&str[strlen(str)],
328 			    ERRBUFSZ - strlen(str),
329 			    dgettext(__nsl_dom,  "TLI Error %d"),
330 			    rpc_createerr.cf_error.re_terrno);
331 		}
332 		errstr = strerror(rpc_createerr.cf_error.re_errno);
333 		if (errstr != NULL)
334 			(void) strlcat(str, errstr, ERRBUFSZ);
335 		else
336 			(void) snprintf(&str[strlen(str)],
337 			    ERRBUFSZ - strlen(str), "Error %d",
338 			    rpc_createerr.cf_error.re_errno);
339 		break;
340 
341 	case RPC_AUTHERROR:
342 		(void) strlcat(str, " - ", ERRBUFSZ);
343 		(void) strlcat(str,
344 			auth_errmsg(rpc_createerr.cf_error.re_why), ERRBUFSZ);
345 		break;
346 	}
347 	trace1(TR_clnt_spcreateerror, 1);
348 	return (str);
349 }
350 
351 void
352 clnt_pcreateerror(s)
353 	const char *s;
354 {
355 	trace1(TR_clnt_pcreateerror, 0);
356 	(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
357 	trace1(TR_clnt_pcreateerror, 1);
358 }
359 #endif /* ! KERNEL */
360 
361 /*
362  * This interface for use by rpc_call() and rpc_broadcast()
363  */
364 const char *
365 clnt_sperrno(stat)
366 	const enum clnt_stat stat;
367 {
368 	trace1(TR_clnt_sperrno, 0);
369 	switch (stat) {
370 	case RPC_SUCCESS:
371 		trace1(TR_clnt_sperrno, 1);
372 		return (dgettext(__nsl_dom, "RPC: Success"));
373 	case RPC_CANTENCODEARGS:
374 		trace1(TR_clnt_sperrno, 1);
375 		return (dgettext(__nsl_dom, "RPC: Can't encode arguments"));
376 	case RPC_CANTDECODERES:
377 		trace1(TR_clnt_sperrno, 1);
378 		return (dgettext(__nsl_dom, "RPC: Can't decode result"));
379 	case RPC_CANTSTORE:
380 		trace1(TR_clnt_sperrno, 1);
381 		return (dgettext(__nsl_dom, "RPC: Can't store request"));
382 	case RPC_CANTSEND:
383 		trace1(TR_clnt_sperrno, 1);
384 		return (dgettext(__nsl_dom, "RPC: Unable to send"));
385 	case RPC_CANTRECV:
386 		trace1(TR_clnt_sperrno, 1);
387 		return (dgettext(__nsl_dom, "RPC: Unable to receive"));
388 	case RPC_TIMEDOUT:
389 		trace1(TR_clnt_sperrno, 1);
390 		return (dgettext(__nsl_dom, "RPC: Timed out"));
391 	case RPC_VERSMISMATCH:
392 		trace1(TR_clnt_sperrno, 1);
393 		return (dgettext(__nsl_dom,
394 			"RPC: Incompatible versions of RPC"));
395 	case RPC_AUTHERROR:
396 		trace1(TR_clnt_sperrno, 1);
397 		return (dgettext(__nsl_dom, "RPC: Authentication error"));
398 	case RPC_PROGUNAVAIL:
399 		trace1(TR_clnt_sperrno, 1);
400 		return (dgettext(__nsl_dom, "RPC: Program unavailable"));
401 	case RPC_PROGVERSMISMATCH:
402 		trace1(TR_clnt_sperrno, 1);
403 		return (dgettext(__nsl_dom, "RPC: Program/version mismatch"));
404 	case RPC_PROCUNAVAIL:
405 		trace1(TR_clnt_sperrno, 1);
406 		return (dgettext(__nsl_dom, "RPC: Procedure unavailable"));
407 	case RPC_CANTDECODEARGS:
408 		trace1(TR_clnt_sperrno, 1);
409 		return (dgettext(__nsl_dom,
410 			"RPC: Server can't decode arguments"));
411 
412 	case RPC_SYSTEMERROR:
413 		trace1(TR_clnt_sperrno, 1);
414 		return (dgettext(__nsl_dom, "RPC: Remote system error"));
415 	case RPC_UNKNOWNHOST:
416 		trace1(TR_clnt_sperrno, 1);
417 		return (dgettext(__nsl_dom, "RPC: Unknown host"));
418 	case RPC_UNKNOWNPROTO:
419 		trace1(TR_clnt_sperrno, 1);
420 		return (dgettext(__nsl_dom, "RPC: Unknown protocol"));
421 	case RPC_RPCBFAILURE:
422 		trace1(TR_clnt_sperrno, 1);
423 		return (dgettext(__nsl_dom, "RPC: Rpcbind failure"));
424 	case RPC_N2AXLATEFAILURE:
425 		trace1(TR_clnt_sperrno, 1);
426 		return (dgettext(__nsl_dom,
427 			"RPC: Name to address translation failed"));
428 	case RPC_NOBROADCAST:
429 		trace1(TR_clnt_sperrno, 1);
430 		return (dgettext(__nsl_dom, "RPC: Broadcast not supported"));
431 	case RPC_PROGNOTREGISTERED:
432 		trace1(TR_clnt_sperrno, 1);
433 		return (dgettext(__nsl_dom, "RPC: Program not registered"));
434 	case RPC_UNKNOWNADDR:
435 		trace1(TR_clnt_sperrno, 1);
436 		return (dgettext(__nsl_dom,
437 			"RPC: Remote server address unknown"));
438 	case RPC_TLIERROR:
439 		trace1(TR_clnt_sperrno, 1);
440 		return (dgettext(__nsl_dom, "RPC: Miscellaneous tli error"));
441 	case RPC_FAILED:
442 		trace1(TR_clnt_sperrno, 1);
443 		return (dgettext(__nsl_dom, "RPC: Failed (unspecified error)"));
444 	case RPC_INPROGRESS:
445 		trace1(TR_clnt_sperrno, 1);
446 		return (dgettext(__nsl_dom, "RPC: RAC call in progress"));
447 	case RPC_STALERACHANDLE:
448 		trace1(TR_clnt_sperrno, 1);
449 		return (dgettext(__nsl_dom, "RPC: Stale RAC handle"));
450 	case RPC_CANTCONNECT:
451 		trace1(TR_clnt_sperrno, 1);
452 		return (dgettext(__nsl_dom, "RPC: Couldn't make connection"));
453 	case RPC_XPRTFAILED:
454 		trace1(TR_clnt_sperrno, 1);
455 		return (dgettext(__nsl_dom,
456 			"RPC: Received disconnect from remote"));
457 	case RPC_CANTCREATESTREAM:
458 		trace1(TR_clnt_sperrno, 1);
459 		return (dgettext(__nsl_dom, "RPC: Can't push RPC module"));
460 	}
461 	trace1(TR_clnt_sperrno, 1);
462 	return (dgettext(__nsl_dom, "RPC: (unknown error code)"));
463 }
464