2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
2N/A/* All Rights Reserved */
2N/A/*
2N/A * Portions of this source code were derived from Berkeley
2N/A * 4.3 BSD under license from the Regents of the University of
2N/A * California.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * clnt_perror.c
2N/A *
2N/A */
2N/A
2N/A#include "mt.h"
2N/A#include "rpc_mt.h"
2N/A#include <stdio.h>
2N/A#include <libintl.h>
2N/A#include <string.h>
2N/A#include <rpc/types.h>
2N/A#include <rpc/auth.h>
2N/A#include <sys/tiuser.h>
2N/A#include <rpc/clnt.h>
2N/A#include <stdlib.h>
2N/A#include <syslog.h>
2N/A#include <string.h>
2N/A
2N/Aextern char *netdir_sperror();
2N/A
2N/Aconst char __nsl_dom[] = "SUNW_OST_NETRPC";
2N/A
2N/A#define ERRBUFSZ 512
2N/A
2N/Astatic char *
2N/A__buf(void)
2N/A{
2N/A char *buf;
2N/A static char buf_main[ERRBUFSZ];
2N/A static pthread_key_t perror_key = PTHREAD_ONCE_KEY_NP;
2N/A
2N/A buf = thr_main()? buf_main :
2N/A thr_get_storage(&perror_key, ERRBUFSZ, free);
2N/A if (buf == NULL)
2N/A syslog(LOG_WARNING,
2N/A "clnt_sperror: malloc failed when trying to create buffer\n");
2N/A return (buf);
2N/A}
2N/A
2N/Astatic char *
2N/Aauth_errmsg(enum auth_stat stat)
2N/A{
2N/A switch (stat) {
2N/A case AUTH_OK:
2N/A return (dgettext(__nsl_dom, "Authentication OK"));
2N/A case AUTH_BADCRED:
2N/A return (dgettext(__nsl_dom, "Invalid client credential"));
2N/A case AUTH_REJECTEDCRED:
2N/A return (dgettext(__nsl_dom, "Server rejected credential"));
2N/A case AUTH_BADVERF:
2N/A return (dgettext(__nsl_dom, "Invalid client verifier"));
2N/A case AUTH_REJECTEDVERF:
2N/A return (dgettext(__nsl_dom, "Server rejected verifier"));
2N/A case AUTH_TOOWEAK:
2N/A return (dgettext(__nsl_dom, "Client credential too weak"));
2N/A case AUTH_INVALIDRESP:
2N/A return (dgettext(__nsl_dom, "Invalid server verifier"));
2N/A case AUTH_FAILED:
2N/A return (dgettext(__nsl_dom, "Failed (unspecified error)"));
2N/A
2N/A /* kerberos specific */
2N/A case AUTH_DECODE:
2N/A return (dgettext(__nsl_dom, "Could not decode authenticator"));
2N/A case AUTH_TIMEEXPIRE:
2N/A return (dgettext(__nsl_dom, "Time of credential expired"));
2N/A case AUTH_TKT_FILE:
2N/A return (dgettext(__nsl_dom,
2N/A "Something wrong with kerberos ticket file"));
2N/A case AUTH_NET_ADDR:
2N/A return (dgettext(__nsl_dom,
2N/A "Incorrect network address in kerberos ticket"));
2N/A case AUTH_KERB_GENERIC:
2N/A return (dgettext(__nsl_dom, "Kerberos generic error"));
2N/A }
2N/A return (dgettext(__nsl_dom, "Unknown authentication error"));
2N/A}
2N/A
2N/A/*
2N/A * Return string reply error info. For use after clnt_call()
2N/A */
2N/A
2N/A#define REMAINDER (ERRBUFSZ - (str - strstart))
2N/A
2N/Achar *
2N/Aclnt_sperror(const CLIENT *cl, const char *s)
2N/A{
2N/A struct rpc_err e;
2N/A char *err;
2N/A char *str = __buf();
2N/A char *strstart = str;
2N/A
2N/A if (str == NULL)
2N/A return (NULL);
2N/A CLNT_GETERR((CLIENT *) cl, &e);
2N/A
2N/A (void) snprintf(str, ERRBUFSZ, "%s: ", s);
2N/A str += strlcat(str, clnt_sperrno(e.re_status), ERRBUFSZ);
2N/A
2N/A switch (e.re_status) {
2N/A case RPC_SUCCESS:
2N/A case RPC_CANTENCODEARGS:
2N/A case RPC_CANTDECODERES:
2N/A case RPC_TIMEDOUT:
2N/A case RPC_PROGUNAVAIL:
2N/A case RPC_PROCUNAVAIL:
2N/A case RPC_CANTDECODEARGS:
2N/A case RPC_SYSTEMERROR:
2N/A case RPC_UNKNOWNHOST:
2N/A case RPC_UNKNOWNPROTO:
2N/A case RPC_UNKNOWNADDR:
2N/A case RPC_NOBROADCAST:
2N/A case RPC_RPCBFAILURE:
2N/A case RPC_PROGNOTREGISTERED:
2N/A case RPC_FAILED:
2N/A break;
2N/A
2N/A case RPC_N2AXLATEFAILURE:
2N/A (void) snprintf(str, REMAINDER, "; %s", netdir_sperror());
2N/A str += strlen(str);
2N/A break;
2N/A
2N/A case RPC_TLIERROR:
2N/A (void) snprintf(str, REMAINDER, "; %s", t_errlist[e.re_terrno]);
2N/A str += strlen(str);
2N/A if (e.re_errno) {
2N/A (void) snprintf(str, REMAINDER,
2N/A "; %s", strerror(e.re_errno));
2N/A str += strlen(str);
2N/A }
2N/A break;
2N/A
2N/A case RPC_CANTSTORE:
2N/A case RPC_CANTSEND:
2N/A case RPC_CANTRECV:
2N/A if (e.re_errno) {
2N/A (void) snprintf(str, REMAINDER, "; errno = %s",
2N/A strerror(e.re_errno));
2N/A str += strlen(str);
2N/A }
2N/A if (e.re_terrno) {
2N/A (void) snprintf(str, REMAINDER,
2N/A "; %s", t_errlist[e.re_terrno]);
2N/A str += strlen(str);
2N/A }
2N/A break;
2N/A
2N/A case RPC_VERSMISMATCH:
2N/A (void) snprintf(str, REMAINDER,
2N/A "; low version = %lu, high version = %lu",
2N/A e.re_vers.low, e.re_vers.high);
2N/A str += strlen(str);
2N/A break;
2N/A
2N/A case RPC_AUTHERROR:
2N/A err = auth_errmsg(e.re_why);
2N/A (void) snprintf(str, REMAINDER, "; why = ");
2N/A str += strlen(str);
2N/A if (err != NULL) {
2N/A (void) snprintf(str, REMAINDER, "%s", err);
2N/A } else {
2N/A (void) snprintf(str, REMAINDER,
2N/A "(unknown authentication error - %d)",
2N/A (int)e.re_why);
2N/A }
2N/A str += strlen(str);
2N/A break;
2N/A
2N/A case RPC_PROGVERSMISMATCH:
2N/A (void) snprintf(str, REMAINDER,
2N/A "; low version = %lu, high version = %lu",
2N/A e.re_vers.low, e.re_vers.high);
2N/A str += strlen(str);
2N/A break;
2N/A
2N/A default: /* unknown */
2N/A (void) snprintf(str, REMAINDER, "; s1 = %lu, s2 = %lu",
2N/A e.re_lb.s1, e.re_lb.s2);
2N/A str += strlen(str);
2N/A break;
2N/A }
2N/A return (strstart);
2N/A}
2N/A#undef REMAINDER
2N/A
2N/Avoid
2N/Aclnt_perror(const CLIENT *cl, const char *s)
2N/A{
2N/A (void) fprintf(stderr, "%s\n", clnt_sperror(cl, s));
2N/A}
2N/A
2N/Avoid
2N/Aclnt_perrno(const enum clnt_stat num)
2N/A{
2N/A (void) fprintf(stderr, "%s\n", clnt_sperrno(num));
2N/A}
2N/A
2N/A/*
2N/A * Why a client handle could not be created
2N/A */
2N/Achar *
2N/Aclnt_spcreateerror(const char *s)
2N/A{
2N/A char *errstr;
2N/A char *str = __buf();
2N/A
2N/A if (str == NULL)
2N/A return (NULL);
2N/A (void) snprintf(str, ERRBUFSZ, "%s: ", s);
2N/A (void) strlcat(str, clnt_sperrno(rpc_createerr.cf_stat), ERRBUFSZ);
2N/A
2N/A switch (rpc_createerr.cf_stat) {
2N/A case RPC_N2AXLATEFAILURE:
2N/A (void) strlcat(str, " - ", ERRBUFSZ);
2N/A (void) strlcat(str, netdir_sperror(), ERRBUFSZ);
2N/A break;
2N/A
2N/A case RPC_RPCBFAILURE:
2N/A (void) strlcat(str, " - ", ERRBUFSZ);
2N/A (void) strlcat(str,
2N/A clnt_sperrno(rpc_createerr.cf_error.re_status),
2N/A ERRBUFSZ);
2N/A break;
2N/A
2N/A case RPC_SYSTEMERROR:
2N/A (void) strlcat(str, " - ", ERRBUFSZ);
2N/A errstr = strerror(rpc_createerr.cf_error.re_errno);
2N/A if (errstr != NULL)
2N/A (void) strlcat(str, errstr, ERRBUFSZ);
2N/A else
2N/A (void) snprintf(&str[strlen(str)],
2N/A ERRBUFSZ - strlen(str), "Error %d",
2N/A rpc_createerr.cf_error.re_errno);
2N/A break;
2N/A
2N/A case RPC_TLIERROR:
2N/A (void) strlcat(str, " - ", ERRBUFSZ);
2N/A if ((rpc_createerr.cf_error.re_terrno > 0) &&
2N/A (rpc_createerr.cf_error.re_terrno < t_nerr)) {
2N/A (void) strlcat(str,
2N/A t_errlist[rpc_createerr.cf_error.re_terrno],
2N/A ERRBUFSZ);
2N/A if (rpc_createerr.cf_error.re_terrno == TSYSERR) {
2N/A char *err;
2N/A err = strerror(rpc_createerr.cf_error.re_errno);
2N/A if (err) {
2N/A (void) strlcat(str, " (", ERRBUFSZ);
2N/A (void) strlcat(str, err, ERRBUFSZ);
2N/A (void) strlcat(str, ")", ERRBUFSZ);
2N/A }
2N/A }
2N/A } else {
2N/A (void) snprintf(&str[strlen(str)],
2N/A ERRBUFSZ - strlen(str),
2N/A dgettext(__nsl_dom, "TLI Error %d"),
2N/A rpc_createerr.cf_error.re_terrno);
2N/A }
2N/A errstr = strerror(rpc_createerr.cf_error.re_errno);
2N/A if (errstr != NULL)
2N/A (void) strlcat(str, errstr, ERRBUFSZ);
2N/A else
2N/A (void) snprintf(&str[strlen(str)],
2N/A ERRBUFSZ - strlen(str), "Error %d",
2N/A rpc_createerr.cf_error.re_errno);
2N/A break;
2N/A
2N/A case RPC_AUTHERROR:
2N/A (void) strlcat(str, " - ", ERRBUFSZ);
2N/A (void) strlcat(str,
2N/A auth_errmsg(rpc_createerr.cf_error.re_why), ERRBUFSZ);
2N/A break;
2N/A }
2N/A return (str);
2N/A}
2N/A
2N/Avoid
2N/Aclnt_pcreateerror(const char *s)
2N/A{
2N/A (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
2N/A}
2N/A
2N/A/*
2N/A * This interface for use by rpc_call() and rpc_broadcast()
2N/A */
2N/Aconst char *
2N/Aclnt_sperrno(const enum clnt_stat stat)
2N/A{
2N/A switch (stat) {
2N/A case RPC_SUCCESS:
2N/A return (dgettext(__nsl_dom, "RPC: Success"));
2N/A case RPC_CANTENCODEARGS:
2N/A return (dgettext(__nsl_dom, "RPC: Can't encode arguments"));
2N/A case RPC_CANTDECODERES:
2N/A return (dgettext(__nsl_dom, "RPC: Can't decode result"));
2N/A case RPC_CANTSTORE:
2N/A return (dgettext(__nsl_dom, "RPC: Can't store request"));
2N/A case RPC_CANTSEND:
2N/A return (dgettext(__nsl_dom, "RPC: Unable to send"));
2N/A case RPC_CANTRECV:
2N/A return (dgettext(__nsl_dom, "RPC: Unable to receive"));
2N/A case RPC_TIMEDOUT:
2N/A return (dgettext(__nsl_dom, "RPC: Timed out"));
2N/A case RPC_VERSMISMATCH:
2N/A return (dgettext(__nsl_dom,
2N/A "RPC: Incompatible versions of RPC"));
2N/A case RPC_AUTHERROR:
2N/A return (dgettext(__nsl_dom, "RPC: Authentication error"));
2N/A case RPC_PROGUNAVAIL:
2N/A return (dgettext(__nsl_dom, "RPC: Program unavailable"));
2N/A case RPC_PROGVERSMISMATCH:
2N/A return (dgettext(__nsl_dom, "RPC: Program/version mismatch"));
2N/A case RPC_PROCUNAVAIL:
2N/A return (dgettext(__nsl_dom, "RPC: Procedure unavailable"));
2N/A case RPC_CANTDECODEARGS:
2N/A return (dgettext(__nsl_dom,
2N/A "RPC: Server can't decode arguments"));
2N/A
2N/A case RPC_SYSTEMERROR:
2N/A return (dgettext(__nsl_dom, "RPC: Remote system error"));
2N/A case RPC_UNKNOWNHOST:
2N/A return (dgettext(__nsl_dom, "RPC: Unknown host"));
2N/A case RPC_UNKNOWNPROTO:
2N/A return (dgettext(__nsl_dom, "RPC: Unknown protocol"));
2N/A case RPC_RPCBFAILURE:
2N/A return (dgettext(__nsl_dom, "RPC: Rpcbind failure"));
2N/A case RPC_N2AXLATEFAILURE:
2N/A return (dgettext(__nsl_dom,
2N/A "RPC: Name to address translation failed"));
2N/A case RPC_NOBROADCAST:
2N/A return (dgettext(__nsl_dom, "RPC: Broadcast not supported"));
2N/A case RPC_PROGNOTREGISTERED:
2N/A return (dgettext(__nsl_dom, "RPC: Program not registered"));
2N/A case RPC_UNKNOWNADDR:
2N/A return (dgettext(__nsl_dom,
2N/A "RPC: Remote server address unknown"));
2N/A case RPC_TLIERROR:
2N/A return (dgettext(__nsl_dom, "RPC: Miscellaneous tli error"));
2N/A case RPC_FAILED:
2N/A return (dgettext(__nsl_dom, "RPC: Failed (unspecified error)"));
2N/A case RPC_INPROGRESS:
2N/A return (dgettext(__nsl_dom, "RPC: RAC call in progress"));
2N/A case RPC_STALERACHANDLE:
2N/A return (dgettext(__nsl_dom, "RPC: Stale RAC handle"));
2N/A case RPC_CANTCONNECT:
2N/A return (dgettext(__nsl_dom, "RPC: Couldn't make connection"));
2N/A case RPC_XPRTFAILED:
2N/A return (dgettext(__nsl_dom,
2N/A "RPC: Received disconnect from remote"));
2N/A case RPC_CANTCREATESTREAM:
2N/A return (dgettext(__nsl_dom, "RPC: Can't push RPC module"));
2N/A }
2N/A return (dgettext(__nsl_dom, "RPC: (unknown error code)"));
2N/A}