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