1 /* $NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $ */ 2 3 4 /*- 5 * Copyright (c) 2009, Sun Microsystems, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * - Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * - Neither the name of Sun Microsystems, Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #if defined(LIBC_SCCS) && !defined(lint) 33 static char *sccsid2 = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; 34 static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC"; 35 #endif 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 /* 40 * clnt_perror.c 41 * 42 * Copyright (C) 1984, Sun Microsystems, Inc. 43 * 44 */ 45 #include "namespace.h" 46 #include <assert.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 51 #include <rpc/rpc.h> 52 #include <rpc/types.h> 53 #include <rpc/auth.h> 54 #include <rpc/clnt.h> 55 #include "un-namespace.h" 56 57 static char *buf; 58 59 static char *_buf(void); 60 static char *auth_errmsg(enum auth_stat); 61 #define CLNT_PERROR_BUFLEN 256 62 63 static char * 64 _buf(void) 65 { 66 67 if (buf == NULL) 68 buf = malloc(CLNT_PERROR_BUFLEN); 69 return (buf); 70 } 71 72 /* 73 * Print reply error info 74 */ 75 char * 76 clnt_sperror(CLIENT *rpch, const char *s) 77 { 78 struct rpc_err e; 79 char *err; 80 char *str; 81 char *strstart; 82 size_t len, i; 83 84 assert(rpch != NULL); 85 assert(s != NULL); 86 87 str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */ 88 if (str == NULL) 89 return (0); 90 len = CLNT_PERROR_BUFLEN; 91 strstart = str; 92 CLNT_GETERR(rpch, &e); 93 94 if ((i = snprintf(str, len, "%s: ", s)) > 0) { 95 str += i; 96 len -= i; 97 } 98 99 (void)strncpy(str, clnt_sperrno(e.re_status), len - 1); 100 i = strlen(str); 101 str += i; 102 len -= i; 103 104 switch (e.re_status) { 105 case RPC_SUCCESS: 106 case RPC_CANTENCODEARGS: 107 case RPC_CANTDECODERES: 108 case RPC_TIMEDOUT: 109 case RPC_PROGUNAVAIL: 110 case RPC_PROCUNAVAIL: 111 case RPC_CANTDECODEARGS: 112 case RPC_SYSTEMERROR: 113 case RPC_UNKNOWNHOST: 114 case RPC_UNKNOWNPROTO: 115 case RPC_PMAPFAILURE: 116 case RPC_PROGNOTREGISTERED: 117 case RPC_FAILED: 118 break; 119 120 case RPC_CANTSEND: 121 case RPC_CANTRECV: 122 i = snprintf(str, len, "; errno = %s", strerror(e.re_errno)); 123 if (i > 0) { 124 str += i; 125 len -= i; 126 } 127 break; 128 129 case RPC_VERSMISMATCH: 130 i = snprintf(str, len, "; low version = %u, high version = %u", 131 e.re_vers.low, e.re_vers.high); 132 if (i > 0) { 133 str += i; 134 len -= i; 135 } 136 break; 137 138 case RPC_AUTHERROR: 139 err = auth_errmsg(e.re_why); 140 i = snprintf(str, len, "; why = "); 141 if (i > 0) { 142 str += i; 143 len -= i; 144 } 145 if (err != NULL) { 146 i = snprintf(str, len, "%s",err); 147 } else { 148 i = snprintf(str, len, 149 "(unknown authentication error - %d)", 150 (int) e.re_why); 151 } 152 if (i > 0) { 153 str += i; 154 len -= i; 155 } 156 break; 157 158 case RPC_PROGVERSMISMATCH: 159 i = snprintf(str, len, "; low version = %u, high version = %u", 160 e.re_vers.low, e.re_vers.high); 161 if (i > 0) { 162 str += i; 163 len -= i; 164 } 165 break; 166 167 default: /* unknown */ 168 i = snprintf(str, len, "; s1 = %u, s2 = %u", 169 e.re_lb.s1, e.re_lb.s2); 170 if (i > 0) { 171 str += i; 172 len -= i; 173 } 174 break; 175 } 176 strstart[CLNT_PERROR_BUFLEN-1] = '\0'; 177 return(strstart) ; 178 } 179 180 void 181 clnt_perror(CLIENT *rpch, const char *s) 182 { 183 184 assert(rpch != NULL); 185 assert(s != NULL); 186 187 (void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s)); 188 } 189 190 static const char *const rpc_errlist[] = { 191 "RPC: Success", /* 0 - RPC_SUCCESS */ 192 "RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */ 193 "RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */ 194 "RPC: Unable to send", /* 3 - RPC_CANTSEND */ 195 "RPC: Unable to receive", /* 4 - RPC_CANTRECV */ 196 "RPC: Timed out", /* 5 - RPC_TIMEDOUT */ 197 "RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */ 198 "RPC: Authentication error", /* 7 - RPC_AUTHERROR */ 199 "RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */ 200 "RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */ 201 "RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */ 202 "RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */ 203 "RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */ 204 "RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */ 205 "RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */ 206 "RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */ 207 "RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */ 208 "RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */ 209 }; 210 211 212 /* 213 * This interface for use by clntrpc 214 */ 215 char * 216 clnt_sperrno(enum clnt_stat stat) 217 { 218 unsigned int errnum = stat; 219 220 if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) 221 /* LINTED interface problem */ 222 return (char *)rpc_errlist[errnum]; 223 224 return ("RPC: (unknown error code)"); 225 } 226 227 void 228 clnt_perrno(enum clnt_stat num) 229 { 230 (void) fprintf(stderr, "%s\n", clnt_sperrno(num)); 231 } 232 233 234 char * 235 clnt_spcreateerror(const char *s) 236 { 237 char *str; 238 size_t len, i; 239 240 assert(s != NULL); 241 242 str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */ 243 if (str == NULL) 244 return(0); 245 len = CLNT_PERROR_BUFLEN; 246 i = snprintf(str, len, "%s: ", s); 247 if (i > 0) 248 len -= i; 249 (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1); 250 switch (rpc_createerr.cf_stat) { 251 case RPC_PMAPFAILURE: 252 (void) strncat(str, " - ", len - 1); 253 (void) strncat(str, 254 clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4); 255 break; 256 257 case RPC_SYSTEMERROR: 258 (void)strncat(str, " - ", len - 1); 259 (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno), 260 len - 4); 261 break; 262 263 case RPC_CANTSEND: 264 case RPC_CANTDECODERES: 265 case RPC_CANTENCODEARGS: 266 case RPC_SUCCESS: 267 case RPC_UNKNOWNPROTO: 268 case RPC_PROGNOTREGISTERED: 269 case RPC_FAILED: 270 case RPC_UNKNOWNHOST: 271 case RPC_CANTDECODEARGS: 272 case RPC_PROCUNAVAIL: 273 case RPC_PROGVERSMISMATCH: 274 case RPC_PROGUNAVAIL: 275 case RPC_AUTHERROR: 276 case RPC_VERSMISMATCH: 277 case RPC_TIMEDOUT: 278 case RPC_CANTRECV: 279 default: 280 break; 281 } 282 str[CLNT_PERROR_BUFLEN-1] = '\0'; 283 return (str); 284 } 285 286 void 287 clnt_pcreateerror(const char *s) 288 { 289 290 assert(s != NULL); 291 292 (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s)); 293 } 294 295 static const char *const auth_errlist[] = { 296 "Authentication OK", /* 0 - AUTH_OK */ 297 "Invalid client credential", /* 1 - AUTH_BADCRED */ 298 "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */ 299 "Invalid client verifier", /* 3 - AUTH_BADVERF */ 300 "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */ 301 "Client credential too weak", /* 5 - AUTH_TOOWEAK */ 302 "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */ 303 "Failed (unspecified error)", /* 7 - AUTH_FAILED */ 304 "Kerberos generic error", /* 8 - AUTH_KERB_GENERIC*/ 305 "Kerberos credential expired", /* 9 - AUTH_TIMEEXPIRE */ 306 "Bad kerberos ticket file", /* 10 - AUTH_TKT_FILE */ 307 "Can't decode kerberos authenticator", /* 11 - AUTH_DECODE */ 308 "Address wrong in kerberos ticket", /* 12 - AUTH_NET_ADDR */ 309 "GSS-API crediential problem", /* 13 - RPCSEC_GSS_CREDPROBLEM */ 310 "GSS-API context problem" /* 14 - RPCSEC_GSS_CTXPROBLEM */ 311 }; 312 313 static char * 314 auth_errmsg(enum auth_stat stat) 315 { 316 unsigned int errnum = stat; 317 318 if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0]))) 319 /* LINTED interface problem */ 320 return (char *)auth_errlist[errnum]; 321 322 return(NULL); 323 } 324