1*84d9c625SLionel Sambuc /* $NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $ */
22fe8fb19SBen Gras
32fe8fb19SBen Gras /*
4*84d9c625SLionel Sambuc * Copyright (c) 2010, Oracle America, Inc.
52fe8fb19SBen Gras *
6*84d9c625SLionel Sambuc * Redistribution and use in source and binary forms, with or without
7*84d9c625SLionel Sambuc * modification, are permitted provided that the following conditions are
8*84d9c625SLionel Sambuc * met:
92fe8fb19SBen Gras *
10*84d9c625SLionel Sambuc * * Redistributions of source code must retain the above copyright
11*84d9c625SLionel Sambuc * notice, this list of conditions and the following disclaimer.
12*84d9c625SLionel Sambuc * * Redistributions in binary form must reproduce the above
13*84d9c625SLionel Sambuc * copyright notice, this list of conditions and the following
14*84d9c625SLionel Sambuc * disclaimer in the documentation and/or other materials
15*84d9c625SLionel Sambuc * provided with the distribution.
16*84d9c625SLionel Sambuc * * Neither the name of the "Oracle America, Inc." nor the names of its
17*84d9c625SLionel Sambuc * contributors may be used to endorse or promote products derived
18*84d9c625SLionel Sambuc * from this software without specific prior written permission.
192fe8fb19SBen Gras *
20*84d9c625SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*84d9c625SLionel Sambuc * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*84d9c625SLionel Sambuc * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*84d9c625SLionel Sambuc * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*84d9c625SLionel Sambuc * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*84d9c625SLionel Sambuc * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*84d9c625SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27*84d9c625SLionel Sambuc * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*84d9c625SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29*84d9c625SLionel Sambuc * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30*84d9c625SLionel Sambuc * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*84d9c625SLionel Sambuc * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
322fe8fb19SBen Gras */
332fe8fb19SBen Gras
342fe8fb19SBen Gras #include <sys/cdefs.h>
352fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
362fe8fb19SBen Gras #if 0
372fe8fb19SBen Gras static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
382fe8fb19SBen Gras static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";
392fe8fb19SBen Gras #else
40*84d9c625SLionel Sambuc __RCSID("$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $");
412fe8fb19SBen Gras #endif
422fe8fb19SBen Gras #endif
432fe8fb19SBen Gras
442fe8fb19SBen Gras /*
452fe8fb19SBen Gras * clnt_perror.c
462fe8fb19SBen Gras *
472fe8fb19SBen Gras * Copyright (C) 1984, Sun Microsystems, Inc.
482fe8fb19SBen Gras *
492fe8fb19SBen Gras */
502fe8fb19SBen Gras #include "namespace.h"
512fe8fb19SBen Gras
522fe8fb19SBen Gras #include <assert.h>
532fe8fb19SBen Gras #include <stdio.h>
542fe8fb19SBen Gras #include <stdlib.h>
552fe8fb19SBen Gras #include <string.h>
562fe8fb19SBen Gras
572fe8fb19SBen Gras #include <rpc/rpc.h>
582fe8fb19SBen Gras #include <rpc/types.h>
592fe8fb19SBen Gras #include <rpc/auth.h>
602fe8fb19SBen Gras #include <rpc/clnt.h>
612fe8fb19SBen Gras
622fe8fb19SBen Gras #ifdef __weak_alias
632fe8fb19SBen Gras __weak_alias(clnt_pcreateerror,_clnt_pcreateerror)
642fe8fb19SBen Gras __weak_alias(clnt_perrno,_clnt_perrno)
652fe8fb19SBen Gras __weak_alias(clnt_perror,_clnt_perror)
662fe8fb19SBen Gras __weak_alias(clnt_spcreateerror,_clnt_spcreateerror)
672fe8fb19SBen Gras __weak_alias(clnt_sperrno,_clnt_sperrno)
682fe8fb19SBen Gras __weak_alias(clnt_sperror,_clnt_sperror)
692fe8fb19SBen Gras #endif
702fe8fb19SBen Gras
712fe8fb19SBen Gras static char *buf;
722fe8fb19SBen Gras static size_t buflen;
732fe8fb19SBen Gras
74f14fb602SLionel Sambuc static char *_buf(void);
75f14fb602SLionel Sambuc static char *auth_errmsg(enum auth_stat);
762fe8fb19SBen Gras
772fe8fb19SBen Gras static char *
_buf(void)78f14fb602SLionel Sambuc _buf(void)
792fe8fb19SBen Gras {
802fe8fb19SBen Gras
812fe8fb19SBen Gras buflen = 256;
822fe8fb19SBen Gras if (buf == 0)
832fe8fb19SBen Gras buf = malloc(buflen);
842fe8fb19SBen Gras return (buf);
852fe8fb19SBen Gras }
862fe8fb19SBen Gras
872fe8fb19SBen Gras /*
882fe8fb19SBen Gras * Print reply error info
892fe8fb19SBen Gras */
902fe8fb19SBen Gras char *
clnt_sperror(CLIENT * rpch,const char * s)91f14fb602SLionel Sambuc clnt_sperror(CLIENT *rpch, const char *s)
922fe8fb19SBen Gras {
932fe8fb19SBen Gras struct rpc_err e;
942fe8fb19SBen Gras char *err;
952fe8fb19SBen Gras char *str;
962fe8fb19SBen Gras char *strstart;
972fe8fb19SBen Gras size_t len, i;
982fe8fb19SBen Gras
992fe8fb19SBen Gras _DIAGASSERT(rpch != NULL);
1002fe8fb19SBen Gras _DIAGASSERT(s != NULL);
1012fe8fb19SBen Gras
1022fe8fb19SBen Gras str = _buf(); /* side effect: sets "buflen" */
1032fe8fb19SBen Gras if (str == 0)
1042fe8fb19SBen Gras return (0);
1052fe8fb19SBen Gras len = buflen;
1062fe8fb19SBen Gras strstart = str;
1072fe8fb19SBen Gras CLNT_GETERR(rpch, &e);
1082fe8fb19SBen Gras
1092fe8fb19SBen Gras i = snprintf(str, len, "%s: ", s);
1102fe8fb19SBen Gras str += i;
1112fe8fb19SBen Gras len -= i;
1122fe8fb19SBen Gras
1132fe8fb19SBen Gras (void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
1142fe8fb19SBen Gras i = strlen(str);
1152fe8fb19SBen Gras str += i;
1162fe8fb19SBen Gras len -= i;
1172fe8fb19SBen Gras
1182fe8fb19SBen Gras switch (e.re_status) {
1192fe8fb19SBen Gras case RPC_SUCCESS:
1202fe8fb19SBen Gras case RPC_CANTENCODEARGS:
1212fe8fb19SBen Gras case RPC_CANTDECODERES:
1222fe8fb19SBen Gras case RPC_TIMEDOUT:
1232fe8fb19SBen Gras case RPC_PROGUNAVAIL:
1242fe8fb19SBen Gras case RPC_PROCUNAVAIL:
1252fe8fb19SBen Gras case RPC_CANTDECODEARGS:
1262fe8fb19SBen Gras case RPC_SYSTEMERROR:
1272fe8fb19SBen Gras case RPC_UNKNOWNHOST:
1282fe8fb19SBen Gras case RPC_UNKNOWNPROTO:
1292fe8fb19SBen Gras case RPC_PMAPFAILURE:
1302fe8fb19SBen Gras case RPC_PROGNOTREGISTERED:
1312fe8fb19SBen Gras case RPC_FAILED:
1322fe8fb19SBen Gras break;
1332fe8fb19SBen Gras
1342fe8fb19SBen Gras case RPC_CANTSEND:
1352fe8fb19SBen Gras case RPC_CANTRECV:
1362fe8fb19SBen Gras i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
1372fe8fb19SBen Gras str += i;
1382fe8fb19SBen Gras len -= i;
1392fe8fb19SBen Gras break;
1402fe8fb19SBen Gras
1412fe8fb19SBen Gras case RPC_VERSMISMATCH:
1422fe8fb19SBen Gras i = snprintf(str, len, "; low version = %u, high version = %u",
1432fe8fb19SBen Gras e.re_vers.low, e.re_vers.high);
1442fe8fb19SBen Gras str += i;
1452fe8fb19SBen Gras len -= i;
1462fe8fb19SBen Gras break;
1472fe8fb19SBen Gras
1482fe8fb19SBen Gras case RPC_AUTHERROR:
1492fe8fb19SBen Gras err = auth_errmsg(e.re_why);
1502fe8fb19SBen Gras i = snprintf(str, len, "; why = ");
1512fe8fb19SBen Gras str += i;
1522fe8fb19SBen Gras len -= i;
1532fe8fb19SBen Gras if (err != NULL) {
1542fe8fb19SBen Gras i = snprintf(str, len, "%s",err);
1552fe8fb19SBen Gras } else {
1562fe8fb19SBen Gras i = snprintf(str, len,
1572fe8fb19SBen Gras "(unknown authentication error - %d)",
1582fe8fb19SBen Gras (int) e.re_why);
1592fe8fb19SBen Gras }
1602fe8fb19SBen Gras str += i;
1612fe8fb19SBen Gras len -= i;
1622fe8fb19SBen Gras break;
1632fe8fb19SBen Gras
1642fe8fb19SBen Gras case RPC_PROGVERSMISMATCH:
1652fe8fb19SBen Gras i = snprintf(str, len, "; low version = %u, high version = %u",
1662fe8fb19SBen Gras e.re_vers.low, e.re_vers.high);
1672fe8fb19SBen Gras str += i;
1682fe8fb19SBen Gras len -= i;
1692fe8fb19SBen Gras break;
1702fe8fb19SBen Gras
1712fe8fb19SBen Gras default: /* unknown */
1722fe8fb19SBen Gras i = snprintf(str, len, "; s1 = %u, s2 = %u",
1732fe8fb19SBen Gras e.re_lb.s1, e.re_lb.s2);
1742fe8fb19SBen Gras str += i;
1752fe8fb19SBen Gras len -= i;
1762fe8fb19SBen Gras break;
1772fe8fb19SBen Gras }
1782fe8fb19SBen Gras return(strstart) ;
1792fe8fb19SBen Gras }
1802fe8fb19SBen Gras
1812fe8fb19SBen Gras void
clnt_perror(CLIENT * rpch,const char * s)182f14fb602SLionel Sambuc clnt_perror(CLIENT *rpch, const char *s)
1832fe8fb19SBen Gras {
1842fe8fb19SBen Gras
1852fe8fb19SBen Gras _DIAGASSERT(rpch != NULL);
1862fe8fb19SBen Gras _DIAGASSERT(s != NULL);
1872fe8fb19SBen Gras
1882fe8fb19SBen Gras (void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
1892fe8fb19SBen Gras }
1902fe8fb19SBen Gras
1912fe8fb19SBen Gras static const char *const rpc_errlist[] = {
1922fe8fb19SBen Gras [RPC_SUCCESS] = "RPC: Success",
1932fe8fb19SBen Gras [RPC_CANTENCODEARGS] = "RPC: Can't encode arguments",
1942fe8fb19SBen Gras [RPC_CANTDECODERES] = "RPC: Can't decode result",
1952fe8fb19SBen Gras [RPC_CANTSEND] = "RPC: Unable to send",
1962fe8fb19SBen Gras [RPC_CANTRECV] = "RPC: Unable to receive",
1972fe8fb19SBen Gras [RPC_TIMEDOUT] = "RPC: Timed out",
1982fe8fb19SBen Gras [RPC_VERSMISMATCH] = "RPC: Incompatible versions of RPC",
1992fe8fb19SBen Gras [RPC_AUTHERROR] = "RPC: Authentication error",
2002fe8fb19SBen Gras [RPC_PROGUNAVAIL] = "RPC: Program unavailable",
2012fe8fb19SBen Gras [RPC_PROGVERSMISMATCH] = "RPC: Program/version mismatch",
2022fe8fb19SBen Gras [RPC_PROCUNAVAIL] = "RPC: Procedure unavailable",
2032fe8fb19SBen Gras [RPC_CANTDECODEARGS] = "RPC: Server can't decode arguments",
2042fe8fb19SBen Gras [RPC_SYSTEMERROR] = "RPC: Remote system error",
2052fe8fb19SBen Gras [RPC_UNKNOWNHOST] = "RPC: Unknown host",
2062fe8fb19SBen Gras [RPC_PMAPFAILURE] = "RPC: Port mapper failure",
2072fe8fb19SBen Gras [RPC_PROGNOTREGISTERED] = "RPC: Program not registered",
2082fe8fb19SBen Gras [RPC_FAILED] = "RPC: Failed (unspecified error)",
2092fe8fb19SBen Gras [RPC_UNKNOWNPROTO] = "RPC: Unknown protocol",
2102fe8fb19SBen Gras [RPC_UNKNOWNADDR] = "RPC: Remote address unknown",
2112fe8fb19SBen Gras [RPC_TLIERROR] = "RPC: Misc error in the TLI library",
2122fe8fb19SBen Gras [RPC_NOBROADCAST] = "RPC: Broadcasting not supported",
2132fe8fb19SBen Gras [RPC_N2AXLATEFAILURE] = "RPC: Name -> addr translation failed",
2142fe8fb19SBen Gras [RPC_INPROGRESS] = "RPC: In progress",
2152fe8fb19SBen Gras [RPC_STALERACHANDLE] = "RPC: Stale handle",
2162fe8fb19SBen Gras };
2172fe8fb19SBen Gras
2182fe8fb19SBen Gras
2192fe8fb19SBen Gras /*
2202fe8fb19SBen Gras * This interface for use by clntrpc
2212fe8fb19SBen Gras */
2222fe8fb19SBen Gras char *
clnt_sperrno(enum clnt_stat stat)223f14fb602SLionel Sambuc clnt_sperrno(enum clnt_stat stat)
2242fe8fb19SBen Gras {
2252fe8fb19SBen Gras unsigned int errnum = stat;
2262fe8fb19SBen Gras const char *msg;
2272fe8fb19SBen Gras
2282fe8fb19SBen Gras msg = NULL;
2292fe8fb19SBen Gras if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) {
2302fe8fb19SBen Gras msg = rpc_errlist[errnum];
2312fe8fb19SBen Gras }
2322fe8fb19SBen Gras if (msg == NULL) {
2332fe8fb19SBen Gras msg = "RPC: (unknown error code)";
2342fe8fb19SBen Gras }
2352fe8fb19SBen Gras return __UNCONST(msg);
2362fe8fb19SBen Gras }
2372fe8fb19SBen Gras
2382fe8fb19SBen Gras void
clnt_perrno(enum clnt_stat num)239f14fb602SLionel Sambuc clnt_perrno(enum clnt_stat num)
2402fe8fb19SBen Gras {
2412fe8fb19SBen Gras (void) fprintf(stderr, "%s\n", clnt_sperrno(num));
2422fe8fb19SBen Gras }
2432fe8fb19SBen Gras
2442fe8fb19SBen Gras
2452fe8fb19SBen Gras char *
clnt_spcreateerror(const char * s)246f14fb602SLionel Sambuc clnt_spcreateerror(const char *s)
2472fe8fb19SBen Gras {
2482fe8fb19SBen Gras char *str;
2492fe8fb19SBen Gras size_t len, i;
2502fe8fb19SBen Gras
2512fe8fb19SBen Gras _DIAGASSERT(s != NULL);
2522fe8fb19SBen Gras
2532fe8fb19SBen Gras str = _buf(); /* side effect: sets "buflen" */
2542fe8fb19SBen Gras if (str == 0)
2552fe8fb19SBen Gras return(0);
2562fe8fb19SBen Gras len = buflen;
2572fe8fb19SBen Gras i = snprintf(str, len, "%s: ", s);
2582fe8fb19SBen Gras len -= i;
2592fe8fb19SBen Gras (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
2602fe8fb19SBen Gras switch (rpc_createerr.cf_stat) {
2612fe8fb19SBen Gras case RPC_PMAPFAILURE:
2622fe8fb19SBen Gras (void) strncat(str, " - ", len - 1);
2632fe8fb19SBen Gras (void) strncat(str,
2642fe8fb19SBen Gras clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
2652fe8fb19SBen Gras break;
2662fe8fb19SBen Gras
2672fe8fb19SBen Gras case RPC_SYSTEMERROR:
2682fe8fb19SBen Gras (void)strncat(str, " - ", len - 1);
2692fe8fb19SBen Gras (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
2702fe8fb19SBen Gras len - 4);
2712fe8fb19SBen Gras break;
2722fe8fb19SBen Gras
2732fe8fb19SBen Gras case RPC_CANTSEND:
2742fe8fb19SBen Gras case RPC_CANTDECODERES:
2752fe8fb19SBen Gras case RPC_CANTENCODEARGS:
2762fe8fb19SBen Gras case RPC_SUCCESS:
2772fe8fb19SBen Gras case RPC_UNKNOWNPROTO:
2782fe8fb19SBen Gras case RPC_PROGNOTREGISTERED:
2792fe8fb19SBen Gras case RPC_FAILED:
2802fe8fb19SBen Gras case RPC_UNKNOWNHOST:
2812fe8fb19SBen Gras case RPC_CANTDECODEARGS:
2822fe8fb19SBen Gras case RPC_PROCUNAVAIL:
2832fe8fb19SBen Gras case RPC_PROGVERSMISMATCH:
2842fe8fb19SBen Gras case RPC_PROGUNAVAIL:
2852fe8fb19SBen Gras case RPC_AUTHERROR:
2862fe8fb19SBen Gras case RPC_VERSMISMATCH:
2872fe8fb19SBen Gras case RPC_TIMEDOUT:
2882fe8fb19SBen Gras case RPC_CANTRECV:
2892fe8fb19SBen Gras default:
2902fe8fb19SBen Gras break;
2912fe8fb19SBen Gras }
2922fe8fb19SBen Gras return (str);
2932fe8fb19SBen Gras }
2942fe8fb19SBen Gras
2952fe8fb19SBen Gras void
clnt_pcreateerror(const char * s)296f14fb602SLionel Sambuc clnt_pcreateerror(const char *s)
2972fe8fb19SBen Gras {
2982fe8fb19SBen Gras
2992fe8fb19SBen Gras _DIAGASSERT(s != NULL);
3002fe8fb19SBen Gras
3012fe8fb19SBen Gras (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
3022fe8fb19SBen Gras }
3032fe8fb19SBen Gras
3042fe8fb19SBen Gras static const char *const auth_errlist[] = {
3052fe8fb19SBen Gras "Authentication OK", /* 0 - AUTH_OK */
3062fe8fb19SBen Gras "Invalid client credential", /* 1 - AUTH_BADCRED */
3072fe8fb19SBen Gras "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
3082fe8fb19SBen Gras "Invalid client verifier", /* 3 - AUTH_BADVERF */
3092fe8fb19SBen Gras "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
3102fe8fb19SBen Gras "Client credential too weak", /* 5 - AUTH_TOOWEAK */
3112fe8fb19SBen Gras "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
3122fe8fb19SBen Gras "Failed (unspecified error)" /* 7 - AUTH_FAILED */
3132fe8fb19SBen Gras };
3142fe8fb19SBen Gras
3152fe8fb19SBen Gras static char *
auth_errmsg(enum auth_stat stat)316f14fb602SLionel Sambuc auth_errmsg(enum auth_stat stat)
3172fe8fb19SBen Gras {
3182fe8fb19SBen Gras unsigned int errnum = stat;
3192fe8fb19SBen Gras
320f14fb602SLionel Sambuc if (errnum < __arraycount(auth_errlist))
3212fe8fb19SBen Gras return __UNCONST(auth_errlist[errnum]);
3222fe8fb19SBen Gras
3232fe8fb19SBen Gras return(NULL);
3242fe8fb19SBen Gras }
325