1 /* @(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30 #if 0
31 static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
32 #endif
33 
34 /*
35  * clnt_perror.c
36  *
37  * Copyright (C) 1984, Sun Microsystems, Inc.
38  *
39  */
40 
41 #include <stdio.h>
42 #include <string.h>
43 #include "rpc_private.h"
44 
45 static char *auth_errmsg (enum auth_stat stat) internal_function;
46 
47 #ifdef __UCLIBC_HAS_THREADS__
48 /*
49  * Making buf a preprocessor macro requires renaming the local
50  * buf variable in a few functions.  Overriding a global variable
51  * with a local variable of the same name is a bad idea, anyway.
52  */
53 #define buf (*(char **)&RPC_THREAD_VARIABLE(clnt_perr_buf_s))
54 #else
55 static char *buf;
56 #endif
57 
58 static char *
_buf(void)59 _buf (void)
60 {
61   if (buf == NULL)
62     buf = (char *) malloc (256);
63   return buf;
64 }
65 
66 struct rpc_errtab
67 {
68   enum clnt_stat status;
69   unsigned int message_off;
70 };
71 
72 static const char rpc_errstr[] =
73 {
74 #define RPC_SUCCESS_IDX		0
75   N_("RPC: Success")
76   "\0"
77 #define RPC_CANTENCODEARGS_IDX	(RPC_SUCCESS_IDX + sizeof "RPC: Success")
78   N_("RPC: Can't encode arguments")
79   "\0"
80 #define RPC_CANTDECODERES_IDX	(RPC_CANTENCODEARGS_IDX \
81 				 + sizeof "RPC: Can't encode arguments")
82   N_("RPC: Can't decode result")
83   "\0"
84 #define RPC_CANTSEND_IDX	(RPC_CANTDECODERES_IDX \
85 				 + sizeof "RPC: Can't decode result")
86   N_("RPC: Unable to send")
87   "\0"
88 #define RPC_CANTRECV_IDX	(RPC_CANTSEND_IDX \
89 				 + sizeof "RPC: Unable to send")
90   N_("RPC: Unable to receive")
91   "\0"
92 #define RPC_TIMEDOUT_IDX	(RPC_CANTRECV_IDX \
93 				 + sizeof "RPC: Unable to receive")
94   N_("RPC: Timed out")
95   "\0"
96 #define RPC_VERSMISMATCH_IDX	(RPC_TIMEDOUT_IDX \
97 				 + sizeof "RPC: Timed out")
98   N_("RPC: Incompatible versions of RPC")
99   "\0"
100 #define RPC_AUTHERROR_IDX	(RPC_VERSMISMATCH_IDX \
101 				 + sizeof "RPC: Incompatible versions of RPC")
102   N_("RPC: Authentication error")
103   "\0"
104 #define RPC_PROGUNAVAIL_IDX		(RPC_AUTHERROR_IDX \
105 				 + sizeof "RPC: Authentication error")
106   N_("RPC: Program unavailable")
107   "\0"
108 #define RPC_PROGVERSMISMATCH_IDX (RPC_PROGUNAVAIL_IDX \
109 				  + sizeof "RPC: Program unavailable")
110   N_("RPC: Program/version mismatch")
111   "\0"
112 #define RPC_PROCUNAVAIL_IDX	(RPC_PROGVERSMISMATCH_IDX \
113 				 + sizeof "RPC: Program/version mismatch")
114   N_("RPC: Procedure unavailable")
115   "\0"
116 #define RPC_CANTDECODEARGS_IDX	(RPC_PROCUNAVAIL_IDX \
117 				 + sizeof "RPC: Procedure unavailable")
118   N_("RPC: Server can't decode arguments")
119   "\0"
120 #define RPC_SYSTEMERROR_IDX	(RPC_CANTDECODEARGS_IDX \
121 				 + sizeof "RPC: Server can't decode arguments")
122   N_("RPC: Remote system error")
123   "\0"
124 #define RPC_UNKNOWNHOST_IDX	(RPC_SYSTEMERROR_IDX \
125 				 + sizeof "RPC: Remote system error")
126   N_("RPC: Unknown host")
127   "\0"
128 #define RPC_UNKNOWNPROTO_IDX	(RPC_UNKNOWNHOST_IDX \
129 				 + sizeof "RPC: Unknown host")
130   N_("RPC: Unknown protocol")
131   "\0"
132 #define RPC_PMAPFAILURE_IDX	(RPC_UNKNOWNPROTO_IDX \
133 				 + sizeof "RPC: Unknown protocol")
134   N_("RPC: Port mapper failure")
135   "\0"
136 #define RPC_PROGNOTREGISTERED_IDX (RPC_PMAPFAILURE_IDX \
137 				   + sizeof "RPC: Port mapper failure")
138   N_("RPC: Program not registered")
139   "\0"
140 #define RPC_FAILED_IDX		(RPC_PROGNOTREGISTERED_IDX \
141 				 + sizeof "RPC: Program not registered")
142   N_("RPC: Failed (unspecified error)")
143 };
144 
145 static const struct rpc_errtab rpc_errlist[] =
146 {
147   { RPC_SUCCESS, RPC_SUCCESS_IDX },
148   { RPC_CANTENCODEARGS, RPC_CANTENCODEARGS_IDX },
149   { RPC_CANTDECODERES, RPC_CANTDECODERES_IDX },
150   { RPC_CANTSEND, RPC_CANTSEND_IDX },
151   { RPC_CANTRECV, RPC_CANTRECV_IDX },
152   { RPC_TIMEDOUT, RPC_TIMEDOUT_IDX },
153   { RPC_VERSMISMATCH, RPC_VERSMISMATCH_IDX },
154   { RPC_AUTHERROR, RPC_AUTHERROR_IDX },
155   { RPC_PROGUNAVAIL, RPC_PROGUNAVAIL_IDX },
156   { RPC_PROGVERSMISMATCH, RPC_PROGVERSMISMATCH_IDX },
157   { RPC_PROCUNAVAIL, RPC_PROCUNAVAIL_IDX },
158   { RPC_CANTDECODEARGS, RPC_CANTDECODEARGS_IDX },
159   { RPC_SYSTEMERROR, RPC_SYSTEMERROR_IDX },
160   { RPC_UNKNOWNHOST, RPC_UNKNOWNHOST_IDX },
161   { RPC_UNKNOWNPROTO, RPC_UNKNOWNPROTO_IDX },
162   { RPC_PMAPFAILURE, RPC_PMAPFAILURE_IDX },
163   { RPC_PROGNOTREGISTERED, RPC_PROGNOTREGISTERED_IDX },
164   { RPC_FAILED, RPC_FAILED_IDX }
165 };
166 
167 
168 /*
169  * This interface for use by clntrpc
170  */
171 char *
clnt_sperrno(enum clnt_stat stat)172 clnt_sperrno (enum clnt_stat stat)
173 {
174   size_t i;
175 
176   for (i = 0; i < sizeof (rpc_errlist) / sizeof (struct rpc_errtab); i++)
177     {
178       if (rpc_errlist[i].status == stat)
179 	{
180 	  return (char*)_(rpc_errstr + rpc_errlist[i].message_off);
181 	}
182     }
183   return N_("RPC: (unknown error code)");
184 }
libc_hidden_def(clnt_sperrno)185 libc_hidden_def(clnt_sperrno)
186 
187 void
188 clnt_perrno (enum clnt_stat num)
189 {
190   (void) fputs (clnt_sperrno (num), stderr);
191 }
192 
193 /*
194  * Print reply error info
195  */
196 char *
clnt_sperror(CLIENT * rpch,const char * msg)197 clnt_sperror (CLIENT * rpch, const char *msg)
198 {
199   char chrbuf[1024];
200   struct rpc_err e;
201   char *err;
202   char *str = _buf ();
203   char *strstart = str;
204   int len;
205 
206   if (str == NULL)
207     return NULL;
208   CLNT_GETERR (rpch, &e);
209 
210   len = sprintf (str, "%s: ", msg);
211   str += len;
212 
213   (void) strcpy(str, clnt_sperrno(e.re_status));
214   str += strlen(str);
215 
216   switch (e.re_status)
217     {
218     case RPC_SUCCESS:
219     case RPC_CANTENCODEARGS:
220     case RPC_CANTDECODERES:
221     case RPC_TIMEDOUT:
222     case RPC_PROGUNAVAIL:
223     case RPC_PROCUNAVAIL:
224     case RPC_CANTDECODEARGS:
225     case RPC_SYSTEMERROR:
226     case RPC_UNKNOWNHOST:
227     case RPC_UNKNOWNPROTO:
228     case RPC_PMAPFAILURE:
229     case RPC_PROGNOTREGISTERED:
230     case RPC_FAILED:
231       break;
232 
233     case RPC_CANTSEND:
234     case RPC_CANTRECV:
235       __glibc_strerror_r (e.re_errno, chrbuf, sizeof chrbuf);
236       len = sprintf (str, "; errno = %s", chrbuf);
237       str += len;
238       break;
239 
240     case RPC_VERSMISMATCH:
241       len= sprintf (str, _("; low version = %lu, high version = %lu"),
242 		    e.re_vers.low, e.re_vers.high);
243       str += len;
244       break;
245 
246     case RPC_AUTHERROR:
247       err = auth_errmsg (e.re_why);
248       (void) strcpy(str, _("; why = "));
249       str += strlen(str);
250 
251       if (err != NULL)
252 	{
253 	  (void) strcpy(str, err);
254 	  str += strlen(str);
255 	}
256       else
257 	{
258 	  len = sprintf (str, _("(unknown authentication error - %d)"),
259 			 (int) e.re_why);
260 	  str += len;
261 	}
262       break;
263 
264     case RPC_PROGVERSMISMATCH:
265       len = sprintf (str, _("; low version = %lu, high version = %lu"),
266 		     e.re_vers.low, e.re_vers.high);
267       str += len;
268       break;
269 
270     default:			/* unknown */
271       len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
272       str += len;
273       break;
274     }
275   *str = '\n';
276   *++str = '\0';
277   return (strstart);
278 }
libc_hidden_def(clnt_sperror)279 libc_hidden_def(clnt_sperror)
280 
281 void
282 clnt_perror (CLIENT * rpch, const char *msg)
283 {
284   (void) fputs (clnt_sperror (rpch, msg), stderr);
285 }
libc_hidden_def(clnt_perror)286 libc_hidden_def(clnt_perror)
287 
288 char *
289 clnt_spcreateerror (const char *msg)
290 {
291   char chrbuf[1024];
292   char *str = _buf ();
293   char *cp;
294   int len;
295   struct rpc_createerr *ce;
296 
297   if (str == NULL)
298     return NULL;
299   ce = &get_rpc_createerr ();
300   len = sprintf (str, "%s: ", msg);
301   cp = str + len;
302   (void) strcpy(cp, clnt_sperrno (ce->cf_stat));
303   cp += strlen(cp);
304 
305   switch (ce->cf_stat)
306     {
307     case RPC_PMAPFAILURE:
308       (void) strcpy(cp, " - ");
309       cp += strlen(cp);
310 
311       (void) strcpy(cp, clnt_sperrno (ce->cf_error.re_status));
312       cp += strlen(cp);
313 
314       break;
315 
316     case RPC_SYSTEMERROR:
317       (void) strcpy(cp, " - ");
318       cp += strlen(cp);
319 
320       __glibc_strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf);
321       (void) strcpy(cp, chrbuf);
322       cp += strlen(cp);
323       break;
324     default:
325       break;
326     }
327   *cp = '\n';
328   *++cp = '\0';
329   return str;
330 }
libc_hidden_def(clnt_spcreateerror)331 libc_hidden_def(clnt_spcreateerror)
332 
333 void
334 clnt_pcreateerror (const char *msg)
335 {
336   (void) fputs (clnt_spcreateerror (msg), stderr);
337 }
338 
339 struct auth_errtab
340 {
341   enum auth_stat status;
342   unsigned int message_off;
343 };
344 
345 static const char auth_errstr[] =
346 {
347 #define AUTH_OK_IDX		0
348    N_("Authentication OK")
349    "\0"
350 #define AUTH_BADCRED_IDX	(AUTH_OK_IDX + sizeof "Authentication OK")
351    N_("Invalid client credential")
352    "\0"
353 #define AUTH_REJECTEDCRED_IDX	(AUTH_BADCRED_IDX \
354 				 + sizeof "Invalid client credential")
355    N_("Server rejected credential")
356    "\0"
357 #define AUTH_BADVERF_IDX	(AUTH_REJECTEDCRED_IDX \
358 				 + sizeof "Server rejected credential")
359    N_("Invalid client verifier")
360    "\0"
361 #define AUTH_REJECTEDVERF_IDX	(AUTH_BADVERF_IDX \
362 				 + sizeof "Invalid client verifier")
363    N_("Server rejected verifier")
364    "\0"
365 #define AUTH_TOOWEAK_IDX	(AUTH_REJECTEDVERF_IDX \
366 				 + sizeof "Server rejected verifier")
367    N_("Client credential too weak")
368    "\0"
369 #define AUTH_INVALIDRESP_IDX	(AUTH_TOOWEAK_IDX \
370 				 + sizeof "Client credential too weak")
371    N_("Invalid server verifier")
372    "\0"
373 #define AUTH_FAILED_IDX		(AUTH_INVALIDRESP_IDX \
374 				 + sizeof "Invalid server verifier")
375    N_("Failed (unspecified error)")
376 };
377 
378 static const struct auth_errtab auth_errlist[] =
379 {
380   { AUTH_OK, AUTH_OK_IDX },
381   { AUTH_BADCRED, AUTH_BADCRED_IDX },
382   { AUTH_REJECTEDCRED, AUTH_REJECTEDCRED_IDX },
383   { AUTH_BADVERF, AUTH_BADVERF_IDX },
384   { AUTH_REJECTEDVERF, AUTH_REJECTEDVERF_IDX },
385   { AUTH_TOOWEAK, AUTH_TOOWEAK_IDX },
386   { AUTH_INVALIDRESP, AUTH_INVALIDRESP_IDX },
387   { AUTH_FAILED, AUTH_FAILED_IDX }
388 };
389 
390 static char *
391 internal_function
auth_errmsg(enum auth_stat stat)392 auth_errmsg (enum auth_stat stat)
393 {
394   size_t i;
395 
396   for (i = 0; i < sizeof (auth_errlist) / sizeof (struct auth_errtab); i++)
397     {
398       if (auth_errlist[i].status == stat)
399 	{
400 	  return (char*)_(auth_errstr + auth_errlist[i].message_off);
401 	}
402     }
403   return NULL;
404 }
405 
406 
407 static void __attribute_used__
free_mem(void)408 free_mem (void)
409 {
410   free (buf);
411 }
412