xref: /netbsd-src/lib/libc/rpc/clnt_perror.c (revision 47c0e0c312cd964546204bd0febab9a56fa11df9)
1*47c0e0c3Stron /*	$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $	*/
29e15c989Scgd 
363d7b677Scgd /*
4*47c0e0c3Stron  * Copyright (c) 2010, Oracle America, Inc.
563d7b677Scgd  *
6*47c0e0c3Stron  * Redistribution and use in source and binary forms, with or without
7*47c0e0c3Stron  * modification, are permitted provided that the following conditions are
8*47c0e0c3Stron  * met:
963d7b677Scgd  *
10*47c0e0c3Stron  *     * Redistributions of source code must retain the above copyright
11*47c0e0c3Stron  *       notice, this list of conditions and the following disclaimer.
12*47c0e0c3Stron  *     * Redistributions in binary form must reproduce the above
13*47c0e0c3Stron  *       copyright notice, this list of conditions and the following
14*47c0e0c3Stron  *       disclaimer in the documentation and/or other materials
15*47c0e0c3Stron  *       provided with the distribution.
16*47c0e0c3Stron  *     * Neither the name of the "Oracle America, Inc." nor the names of its
17*47c0e0c3Stron  *       contributors may be used to endorse or promote products derived
18*47c0e0c3Stron  *       from this software without specific prior written permission.
1963d7b677Scgd  *
20*47c0e0c3Stron  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*47c0e0c3Stron  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*47c0e0c3Stron  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*47c0e0c3Stron  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*47c0e0c3Stron  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*47c0e0c3Stron  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*47c0e0c3Stron  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27*47c0e0c3Stron  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*47c0e0c3Stron  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29*47c0e0c3Stron  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30*47c0e0c3Stron  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*47c0e0c3Stron  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3263d7b677Scgd  */
3363d7b677Scgd 
34b8138fe7Schristos #include <sys/cdefs.h>
3563d7b677Scgd #if defined(LIBC_SCCS) && !defined(lint)
36b8138fe7Schristos #if 0
37b8138fe7Schristos static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
38b8138fe7Schristos static char *sccsid = "@(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";
39b8138fe7Schristos #else
40*47c0e0c3Stron __RCSID("$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $");
41b8138fe7Schristos #endif
4263d7b677Scgd #endif
4363d7b677Scgd 
4463d7b677Scgd /*
4563d7b677Scgd  * clnt_perror.c
4663d7b677Scgd  *
4763d7b677Scgd  * Copyright (C) 1984, Sun Microsystems, Inc.
4863d7b677Scgd  *
4963d7b677Scgd  */
5043fa6fe3Sjtc #include "namespace.h"
5146e6c5e8Slukem 
52b48252f3Slukem #include <assert.h>
5363d7b677Scgd #include <stdio.h>
542e2a3a25Scgd #include <stdlib.h>
5563d7b677Scgd #include <string.h>
5646e6c5e8Slukem 
5763d7b677Scgd #include <rpc/rpc.h>
5863d7b677Scgd #include <rpc/types.h>
5963d7b677Scgd #include <rpc/auth.h>
6063d7b677Scgd #include <rpc/clnt.h>
6163d7b677Scgd 
6243fa6fe3Sjtc #ifdef __weak_alias
6360549036Smycroft __weak_alias(clnt_pcreateerror,_clnt_pcreateerror)
6460549036Smycroft __weak_alias(clnt_perrno,_clnt_perrno)
6560549036Smycroft __weak_alias(clnt_perror,_clnt_perror)
6660549036Smycroft __weak_alias(clnt_spcreateerror,_clnt_spcreateerror)
6760549036Smycroft __weak_alias(clnt_sperrno,_clnt_sperrno)
6860549036Smycroft __weak_alias(clnt_sperror,_clnt_sperror)
6943fa6fe3Sjtc #endif
7043fa6fe3Sjtc 
7163d7b677Scgd static char *buf;
7228fbffc2Schristos static size_t buflen;
7363d7b677Scgd 
74adb74221Smatt static char *_buf(void);
75adb74221Smatt static char *auth_errmsg(enum auth_stat);
76b8138fe7Schristos 
7763d7b677Scgd static char *
_buf(void)78adb74221Smatt _buf(void)
7963d7b677Scgd {
8063d7b677Scgd 
819cd5492cSmrg 	buflen = 256;
826c13a3b8Slukem 	if (buf == 0)
83c9cdc302Schristos 		buf = malloc(buflen);
8463d7b677Scgd 	return (buf);
8563d7b677Scgd }
8663d7b677Scgd 
8763d7b677Scgd /*
8863d7b677Scgd  * Print reply error info
8963d7b677Scgd  */
9063d7b677Scgd char *
clnt_sperror(CLIENT * rpch,const char * s)91adb74221Smatt clnt_sperror(CLIENT *rpch, const char *s)
9263d7b677Scgd {
9363d7b677Scgd 	struct rpc_err e;
9463d7b677Scgd 	char *err;
95b48252f3Slukem 	char *str;
9693eb76ddSexplorer 	char *strstart;
9765bf8c30Sdrochner 	size_t len, i;
9863d7b677Scgd 
99b48252f3Slukem 	_DIAGASSERT(rpch != NULL);
100b48252f3Slukem 	_DIAGASSERT(s != NULL);
101b48252f3Slukem 
10265bf8c30Sdrochner 	str = _buf(); /* side effect: sets "buflen" */
103ce147c1cSlukem 	if (str == 0)
104ce147c1cSlukem 		return (0);
10565bf8c30Sdrochner 	len = buflen;
10693eb76ddSexplorer 	strstart = str;
10763d7b677Scgd 	CLNT_GETERR(rpch, &e);
10863d7b677Scgd 
1099cd5492cSmrg 	i = snprintf(str, len, "%s: ", s);
1109cd5492cSmrg 	str += i;
1119cd5492cSmrg 	len -= i;
11263d7b677Scgd 
1139cd5492cSmrg 	(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
1149cd5492cSmrg 	i = strlen(str);
1159cd5492cSmrg 	str += i;
1169cd5492cSmrg 	len -= i;
11763d7b677Scgd 
11863d7b677Scgd 	switch (e.re_status) {
11963d7b677Scgd 	case RPC_SUCCESS:
12063d7b677Scgd 	case RPC_CANTENCODEARGS:
12163d7b677Scgd 	case RPC_CANTDECODERES:
12263d7b677Scgd 	case RPC_TIMEDOUT:
12363d7b677Scgd 	case RPC_PROGUNAVAIL:
12463d7b677Scgd 	case RPC_PROCUNAVAIL:
12563d7b677Scgd 	case RPC_CANTDECODEARGS:
12663d7b677Scgd 	case RPC_SYSTEMERROR:
12763d7b677Scgd 	case RPC_UNKNOWNHOST:
12863d7b677Scgd 	case RPC_UNKNOWNPROTO:
12963d7b677Scgd 	case RPC_PMAPFAILURE:
13063d7b677Scgd 	case RPC_PROGNOTREGISTERED:
13163d7b677Scgd 	case RPC_FAILED:
13263d7b677Scgd 		break;
13363d7b677Scgd 
13463d7b677Scgd 	case RPC_CANTSEND:
13563d7b677Scgd 	case RPC_CANTRECV:
1366c13a3b8Slukem 		i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
1379cd5492cSmrg 		str += i;
1389cd5492cSmrg 		len -= i;
13963d7b677Scgd 		break;
14063d7b677Scgd 
14163d7b677Scgd 	case RPC_VERSMISMATCH:
1426c13a3b8Slukem 		i = snprintf(str, len, "; low version = %u, high version = %u",
14363d7b677Scgd 			e.re_vers.low, e.re_vers.high);
1449cd5492cSmrg 		str += i;
1459cd5492cSmrg 		len -= i;
14663d7b677Scgd 		break;
14763d7b677Scgd 
14863d7b677Scgd 	case RPC_AUTHERROR:
14963d7b677Scgd 		err = auth_errmsg(e.re_why);
1509cd5492cSmrg 		i = snprintf(str, len, "; why = ");
1519cd5492cSmrg 		str += i;
1529cd5492cSmrg 		len -= i;
15363d7b677Scgd 		if (err != NULL) {
1549cd5492cSmrg 			i = snprintf(str, len, "%s",err);
15563d7b677Scgd 		} else {
1569cd5492cSmrg 			i = snprintf(str, len,
15763d7b677Scgd 				"(unknown authentication error - %d)",
15863d7b677Scgd 				(int) e.re_why);
15963d7b677Scgd 		}
1609cd5492cSmrg 		str += i;
1619cd5492cSmrg 		len -= i;
16263d7b677Scgd 		break;
16363d7b677Scgd 
16463d7b677Scgd 	case RPC_PROGVERSMISMATCH:
1656c13a3b8Slukem 		i = snprintf(str, len, "; low version = %u, high version = %u",
16663d7b677Scgd 			e.re_vers.low, e.re_vers.high);
1679cd5492cSmrg 		str += i;
1689cd5492cSmrg 		len -= i;
16963d7b677Scgd 		break;
17063d7b677Scgd 
17163d7b677Scgd 	default:	/* unknown */
1726c13a3b8Slukem 		i = snprintf(str, len, "; s1 = %u, s2 = %u",
17363d7b677Scgd 			e.re_lb.s1, e.re_lb.s2);
1749cd5492cSmrg 		str += i;
1759cd5492cSmrg 		len -= i;
17663d7b677Scgd 		break;
17763d7b677Scgd 	}
17863d7b677Scgd 	return(strstart) ;
17963d7b677Scgd }
18063d7b677Scgd 
18163d7b677Scgd void
clnt_perror(CLIENT * rpch,const char * s)182adb74221Smatt clnt_perror(CLIENT *rpch, const char *s)
18363d7b677Scgd {
184b48252f3Slukem 
185b48252f3Slukem 	_DIAGASSERT(rpch != NULL);
186b48252f3Slukem 	_DIAGASSERT(s != NULL);
187b48252f3Slukem 
1888453143fSjtc 	(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
18963d7b677Scgd }
19063d7b677Scgd 
19161207f14Sjtc static const char *const rpc_errlist[] = {
192b848cb99Syamt 	[RPC_SUCCESS] =			"RPC: Success",
193b848cb99Syamt 	[RPC_CANTENCODEARGS] =		"RPC: Can't encode arguments",
194b848cb99Syamt 	[RPC_CANTDECODERES] =		"RPC: Can't decode result",
195b848cb99Syamt 	[RPC_CANTSEND] =		"RPC: Unable to send",
196b848cb99Syamt 	[RPC_CANTRECV] =		"RPC: Unable to receive",
197b848cb99Syamt 	[RPC_TIMEDOUT] =		"RPC: Timed out",
198b848cb99Syamt 	[RPC_VERSMISMATCH] =		"RPC: Incompatible versions of RPC",
199b848cb99Syamt 	[RPC_AUTHERROR] = 		"RPC: Authentication error",
200b848cb99Syamt 	[RPC_PROGUNAVAIL] =		"RPC: Program unavailable",
201b848cb99Syamt 	[RPC_PROGVERSMISMATCH] =	"RPC: Program/version mismatch",
202b848cb99Syamt 	[RPC_PROCUNAVAIL] =		"RPC: Procedure unavailable",
203b848cb99Syamt 	[RPC_CANTDECODEARGS] =		"RPC: Server can't decode arguments",
204b848cb99Syamt 	[RPC_SYSTEMERROR] =		"RPC: Remote system error",
205b848cb99Syamt 	[RPC_UNKNOWNHOST] =		"RPC: Unknown host",
206b848cb99Syamt 	[RPC_PMAPFAILURE] =		"RPC: Port mapper failure",
207b848cb99Syamt 	[RPC_PROGNOTREGISTERED] =	"RPC: Program not registered",
208b848cb99Syamt 	[RPC_FAILED] =			"RPC: Failed (unspecified error)",
209b848cb99Syamt 	[RPC_UNKNOWNPROTO] =		"RPC: Unknown protocol",
210b848cb99Syamt 	[RPC_UNKNOWNADDR] =		"RPC: Remote address unknown",
211b848cb99Syamt 	[RPC_TLIERROR] =		"RPC: Misc error in the TLI library",
212b848cb99Syamt 	[RPC_NOBROADCAST] =		"RPC: Broadcasting not supported",
213b848cb99Syamt 	[RPC_N2AXLATEFAILURE] =		"RPC: Name -> addr translation failed",
214b848cb99Syamt 	[RPC_INPROGRESS] =		"RPC: In progress",
215b848cb99Syamt 	[RPC_STALERACHANDLE] =		"RPC: Stale handle",
21663d7b677Scgd };
21763d7b677Scgd 
21863d7b677Scgd 
21963d7b677Scgd /*
22063d7b677Scgd  * This interface for use by clntrpc
22163d7b677Scgd  */
22263d7b677Scgd char *
clnt_sperrno(enum clnt_stat stat)223adb74221Smatt clnt_sperrno(enum clnt_stat stat)
22463d7b677Scgd {
22561207f14Sjtc 	unsigned int errnum = stat;
226b848cb99Syamt 	const char *msg;
22761207f14Sjtc 
228b848cb99Syamt 	msg = NULL;
229b848cb99Syamt 	if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) {
230b848cb99Syamt 		msg = rpc_errlist[errnum];
231b848cb99Syamt 	}
232b848cb99Syamt 	if (msg == NULL) {
233b848cb99Syamt 		msg = "RPC: (unknown error code)";
234b848cb99Syamt 	}
235b848cb99Syamt 	return __UNCONST(msg);
23663d7b677Scgd }
23763d7b677Scgd 
23863d7b677Scgd void
clnt_perrno(enum clnt_stat num)239adb74221Smatt clnt_perrno(enum clnt_stat num)
24063d7b677Scgd {
2418453143fSjtc 	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
24263d7b677Scgd }
24363d7b677Scgd 
24463d7b677Scgd 
24563d7b677Scgd char *
clnt_spcreateerror(const char * s)246adb74221Smatt clnt_spcreateerror(const char *s)
24763d7b677Scgd {
248b48252f3Slukem 	char *str;
24965bf8c30Sdrochner 	size_t len, i;
25063d7b677Scgd 
251b48252f3Slukem 	_DIAGASSERT(s != NULL);
252b48252f3Slukem 
25365bf8c30Sdrochner 	str = _buf(); /* side effect: sets "buflen" */
254ce147c1cSlukem 	if (str == 0)
255ce147c1cSlukem 		return(0);
25665bf8c30Sdrochner 	len = buflen;
2579cd5492cSmrg 	i = snprintf(str, len, "%s: ", s);
2589cd5492cSmrg 	len -= i;
2599cd5492cSmrg 	(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
26063d7b677Scgd 	switch (rpc_createerr.cf_stat) {
26163d7b677Scgd 	case RPC_PMAPFAILURE:
2629cd5492cSmrg 		(void) strncat(str, " - ", len - 1);
2639cd5492cSmrg 		(void) strncat(str,
2649cd5492cSmrg 		    clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
26563d7b677Scgd 		break;
26663d7b677Scgd 
26763d7b677Scgd 	case RPC_SYSTEMERROR:
2689cd5492cSmrg 		(void)strncat(str, " - ", len - 1);
2699cd5492cSmrg 		(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
2709cd5492cSmrg 		    len - 4);
27163d7b677Scgd 		break;
272b8138fe7Schristos 
273b8138fe7Schristos 	case RPC_CANTSEND:
274b8138fe7Schristos 	case RPC_CANTDECODERES:
275b8138fe7Schristos 	case RPC_CANTENCODEARGS:
276b8138fe7Schristos 	case RPC_SUCCESS:
277b8138fe7Schristos 	case RPC_UNKNOWNPROTO:
278b8138fe7Schristos 	case RPC_PROGNOTREGISTERED:
279b8138fe7Schristos 	case RPC_FAILED:
280b8138fe7Schristos 	case RPC_UNKNOWNHOST:
281b8138fe7Schristos 	case RPC_CANTDECODEARGS:
282b8138fe7Schristos 	case RPC_PROCUNAVAIL:
283b8138fe7Schristos 	case RPC_PROGVERSMISMATCH:
284b8138fe7Schristos 	case RPC_PROGUNAVAIL:
285b8138fe7Schristos 	case RPC_AUTHERROR:
286b8138fe7Schristos 	case RPC_VERSMISMATCH:
287b8138fe7Schristos 	case RPC_TIMEDOUT:
288b8138fe7Schristos 	case RPC_CANTRECV:
2897df0ccbaSfvdl 	default:
290b8138fe7Schristos 		break;
29163d7b677Scgd 	}
29263d7b677Scgd 	return (str);
29363d7b677Scgd }
29463d7b677Scgd 
29563d7b677Scgd void
clnt_pcreateerror(const char * s)296adb74221Smatt clnt_pcreateerror(const char *s)
29763d7b677Scgd {
298b48252f3Slukem 
299b48252f3Slukem 	_DIAGASSERT(s != NULL);
300b48252f3Slukem 
3018453143fSjtc 	(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
30263d7b677Scgd }
30363d7b677Scgd 
30461207f14Sjtc static const char *const auth_errlist[] = {
30561207f14Sjtc 	"Authentication OK",			/* 0 - AUTH_OK */
30661207f14Sjtc 	"Invalid client credential",		/* 1 - AUTH_BADCRED */
30761207f14Sjtc 	"Server rejected credential",		/* 2 - AUTH_REJECTEDCRED */
30861207f14Sjtc 	"Invalid client verifier", 		/* 3 - AUTH_BADVERF */
30961207f14Sjtc 	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
31061207f14Sjtc 	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
31161207f14Sjtc 	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
31261207f14Sjtc 	"Failed (unspecified error)"		/* 7 - AUTH_FAILED */
31363d7b677Scgd };
31463d7b677Scgd 
31563d7b677Scgd static char *
auth_errmsg(enum auth_stat stat)316adb74221Smatt auth_errmsg(enum auth_stat stat)
31763d7b677Scgd {
31861207f14Sjtc 	unsigned int errnum = stat;
31963d7b677Scgd 
320adb74221Smatt 	if (errnum < __arraycount(auth_errlist))
32103256c6eSchristos 		return __UNCONST(auth_errlist[errnum]);
32261207f14Sjtc 
32363d7b677Scgd 	return(NULL);
32463d7b677Scgd }
325