1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * Portions of this source code were derived from Berkeley 29 * 4.3 BSD under license from the Regents of the University of 30 * California. 31 */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 /* 36 * clnt_perror.c 37 * 38 */ 39 40 #include "mt.h" 41 #include "rpc_mt.h" 42 #ifndef KERNEL 43 #include <stdio.h> 44 #include <libintl.h> 45 #include <string.h> 46 #endif 47 48 #include <rpc/types.h> 49 #include <rpc/trace.h> 50 #include <rpc/auth.h> 51 #include <sys/tiuser.h> 52 #include <rpc/clnt.h> 53 #include <stdlib.h> 54 #include <syslog.h> 55 #include <string.h> 56 57 extern char *netdir_sperror(); 58 59 const char __nsl_dom[] = "SUNW_OST_NETRPC"; 60 61 #ifndef KERNEL 62 63 #define ERRBUFSZ 512 64 65 static char * 66 __buf() 67 { 68 char *buf; 69 static char buf_main[ERRBUFSZ]; 70 static pthread_key_t perror_key; 71 72 trace1(TR___buf, 0); 73 buf = thr_main()? buf_main : 74 thr_get_storage(&perror_key, ERRBUFSZ, free); 75 if (buf == NULL) 76 syslog(LOG_WARNING, 77 "clnt_sperror: malloc failed when trying to create buffer\n"); 78 trace1(TR___buf, 1); 79 return (buf); 80 } 81 82 static char * 83 auth_errmsg(stat) 84 enum auth_stat stat; 85 { 86 trace1(TR_auth_errmsg, 0); 87 switch (stat) { 88 case AUTH_OK: 89 trace1(TR_auth_errmsg, 1); 90 return (dgettext(__nsl_dom, "Authentication OK")); 91 case AUTH_BADCRED: 92 trace1(TR_auth_errmsg, 1); 93 return (dgettext(__nsl_dom, "Invalid client credential")); 94 case AUTH_REJECTEDCRED: 95 trace1(TR_auth_errmsg, 1); 96 return (dgettext(__nsl_dom, "Server rejected credential")); 97 case AUTH_BADVERF: 98 trace1(TR_auth_errmsg, 1); 99 return (dgettext(__nsl_dom, "Invalid client verifier")); 100 case AUTH_REJECTEDVERF: 101 trace1(TR_auth_errmsg, 1); 102 return (dgettext(__nsl_dom, "Server rejected verifier")); 103 case AUTH_TOOWEAK: 104 trace1(TR_auth_errmsg, 1); 105 return (dgettext(__nsl_dom, "Client credential too weak")); 106 case AUTH_INVALIDRESP: 107 trace1(TR_auth_errmsg, 1); 108 return (dgettext(__nsl_dom, "Invalid server verifier")); 109 case AUTH_FAILED: 110 trace1(TR_auth_errmsg, 1); 111 return (dgettext(__nsl_dom, "Failed (unspecified error)")); 112 113 /* kerberos specific */ 114 case AUTH_DECODE: 115 trace1(TR_auth_errmsg, 1); 116 return (dgettext(__nsl_dom, "Could not decode authenticator")); 117 case AUTH_TIMEEXPIRE: 118 trace1(TR_auth_errmsg, 1); 119 return (dgettext(__nsl_dom, "Time of credential expired")); 120 case AUTH_TKT_FILE: 121 trace1(TR_auth_errmsg, 1); 122 return (dgettext(__nsl_dom, 123 "Something wrong with kerberos ticket file")); 124 case AUTH_NET_ADDR: 125 trace1(TR_auth_errmsg, 1); 126 return (dgettext(__nsl_dom, 127 "Incorrect network address in kerberos ticket")); 128 case AUTH_KERB_GENERIC: 129 trace1(TR_auth_errmsg, 1); 130 return (dgettext(__nsl_dom, "Kerberos generic error")); 131 } 132 trace1(TR_auth_errmsg, 1); 133 return (dgettext(__nsl_dom, "Unknown authentication error")); 134 } 135 136 /* 137 * Return string reply error info. For use after clnt_call() 138 */ 139 140 #define REMAINDER (ERRBUFSZ - (str - strstart)) 141 142 char * 143 clnt_sperror(cl, s) 144 const CLIENT *cl; 145 const char *s; 146 { 147 struct rpc_err e; 148 char *err; 149 char *str = __buf(); 150 char *strstart = str; 151 152 trace2(TR_clnt_sperror, 0, cl); 153 if (str == NULL) { 154 trace2(TR_clnt_sperror, 1, cl); 155 return (NULL); 156 } 157 CLNT_GETERR((CLIENT *) cl, &e); 158 159 (void) snprintf(str, ERRBUFSZ, "%s: ", s); 160 str += strlcat(str, clnt_sperrno(e.re_status), ERRBUFSZ); 161 162 switch (e.re_status) { 163 case RPC_SUCCESS: 164 case RPC_CANTENCODEARGS: 165 case RPC_CANTDECODERES: 166 case RPC_TIMEDOUT: 167 case RPC_PROGUNAVAIL: 168 case RPC_PROCUNAVAIL: 169 case RPC_CANTDECODEARGS: 170 case RPC_SYSTEMERROR: 171 case RPC_UNKNOWNHOST: 172 case RPC_UNKNOWNPROTO: 173 case RPC_UNKNOWNADDR: 174 case RPC_NOBROADCAST: 175 case RPC_RPCBFAILURE: 176 case RPC_PROGNOTREGISTERED: 177 case RPC_FAILED: 178 break; 179 180 case RPC_N2AXLATEFAILURE: 181 (void) snprintf(str, REMAINDER, "; %s", netdir_sperror()); 182 str += strlen(str); 183 break; 184 185 case RPC_TLIERROR: 186 (void) snprintf(str, REMAINDER, "; %s", t_errlist[e.re_terrno]); 187 str += strlen(str); 188 if (e.re_errno) { 189 (void) snprintf(str, REMAINDER, 190 "; %s", strerror(e.re_errno)); 191 str += strlen(str); 192 } 193 break; 194 195 case RPC_CANTSTORE: 196 case RPC_CANTSEND: 197 case RPC_CANTRECV: 198 if (e.re_errno) { 199 (void) snprintf(str, REMAINDER, "; errno = %s", 200 strerror(e.re_errno)); 201 str += strlen(str); 202 } 203 if (e.re_terrno) { 204 (void) snprintf(str, REMAINDER, 205 "; %s", t_errlist[e.re_terrno]); 206 str += strlen(str); 207 } 208 break; 209 210 case RPC_VERSMISMATCH: 211 (void) snprintf(str, REMAINDER, 212 "; low version = %lu, high version = %lu", 213 e.re_vers.low, e.re_vers.high); 214 str += strlen(str); 215 break; 216 217 case RPC_AUTHERROR: 218 err = auth_errmsg(e.re_why); 219 (void) snprintf(str, REMAINDER, "; why = "); 220 str += strlen(str); 221 if (err != NULL) { 222 (void) snprintf(str, REMAINDER, "%s", err); 223 } else { 224 (void) snprintf(str, REMAINDER, 225 "(unknown authentication error - %d)", 226 (int)e.re_why); 227 } 228 str += strlen(str); 229 break; 230 231 case RPC_PROGVERSMISMATCH: 232 (void) snprintf(str, REMAINDER, 233 "; low version = %lu, high version = %lu", 234 e.re_vers.low, e.re_vers.high); 235 str += strlen(str); 236 break; 237 238 default: /* unknown */ 239 (void) snprintf(str, REMAINDER, "; s1 = %lu, s2 = %lu", 240 e.re_lb.s1, e.re_lb.s2); 241 str += strlen(str); 242 break; 243 } 244 trace2(TR_clnt_sperror, 1, cl); 245 return (strstart); 246 } 247 #undef REMAINDER 248 249 void 250 clnt_perror(cl, s) 251 const CLIENT *cl; 252 const char *s; 253 { 254 trace2(TR_clnt_perror, 0, cl); 255 (void) fprintf(stderr, "%s\n", clnt_sperror(cl, s)); 256 trace2(TR_clnt_perror, 1, cl); 257 } 258 259 void 260 clnt_perrno(num) 261 enum clnt_stat num; 262 { 263 trace1(TR_clnt_perrno, 0); 264 (void) fprintf(stderr, "%s\n", clnt_sperrno(num)); 265 trace1(TR_clnt_perrno, 1); 266 } 267 268 /* 269 * Why a client handle could not be created 270 */ 271 char * 272 clnt_spcreateerror(s) 273 const char *s; 274 { 275 char *errstr; 276 char *str = __buf(); 277 278 trace1(TR_clnt_spcreateerror, 0); 279 if (str == NULL) { 280 trace1(TR_clnt_spcreateerror, 1); 281 return (NULL); 282 } 283 (void) snprintf(str, ERRBUFSZ, "%s: ", s); 284 (void) strlcat(str, clnt_sperrno(rpc_createerr.cf_stat), ERRBUFSZ); 285 286 switch (rpc_createerr.cf_stat) { 287 case RPC_N2AXLATEFAILURE: 288 (void) strlcat(str, " - ", ERRBUFSZ); 289 (void) strlcat(str, netdir_sperror(), ERRBUFSZ); 290 break; 291 292 case RPC_RPCBFAILURE: 293 (void) strlcat(str, " - ", ERRBUFSZ); 294 (void) strlcat(str, 295 clnt_sperrno(rpc_createerr.cf_error.re_status), 296 ERRBUFSZ); 297 break; 298 299 case RPC_SYSTEMERROR: 300 (void) strlcat(str, " - ", ERRBUFSZ); 301 errstr = strerror(rpc_createerr.cf_error.re_errno); 302 if (errstr != NULL) 303 (void) strlcat(str, errstr, ERRBUFSZ); 304 else 305 (void) snprintf(&str[strlen(str)], 306 ERRBUFSZ - strlen(str), "Error %d", 307 rpc_createerr.cf_error.re_errno); 308 break; 309 310 case RPC_TLIERROR: 311 (void) strlcat(str, " - ", ERRBUFSZ); 312 if ((rpc_createerr.cf_error.re_terrno > 0) && 313 (rpc_createerr.cf_error.re_terrno < t_nerr)) { 314 (void) strlcat(str, 315 t_errlist[rpc_createerr.cf_error.re_terrno], 316 ERRBUFSZ); 317 if (rpc_createerr.cf_error.re_terrno == TSYSERR) { 318 char *err; 319 err = strerror(rpc_createerr.cf_error.re_errno); 320 if (err) { 321 strlcat(str, " (", ERRBUFSZ); 322 strlcat(str, err, ERRBUFSZ); 323 strlcat(str, ")", ERRBUFSZ); 324 } 325 } 326 } else { 327 (void) snprintf(&str[strlen(str)], 328 ERRBUFSZ - strlen(str), 329 dgettext(__nsl_dom, "TLI Error %d"), 330 rpc_createerr.cf_error.re_terrno); 331 } 332 errstr = strerror(rpc_createerr.cf_error.re_errno); 333 if (errstr != NULL) 334 (void) strlcat(str, errstr, ERRBUFSZ); 335 else 336 (void) snprintf(&str[strlen(str)], 337 ERRBUFSZ - strlen(str), "Error %d", 338 rpc_createerr.cf_error.re_errno); 339 break; 340 341 case RPC_AUTHERROR: 342 (void) strlcat(str, " - ", ERRBUFSZ); 343 (void) strlcat(str, 344 auth_errmsg(rpc_createerr.cf_error.re_why), ERRBUFSZ); 345 break; 346 } 347 trace1(TR_clnt_spcreateerror, 1); 348 return (str); 349 } 350 351 void 352 clnt_pcreateerror(s) 353 const char *s; 354 { 355 trace1(TR_clnt_pcreateerror, 0); 356 (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s)); 357 trace1(TR_clnt_pcreateerror, 1); 358 } 359 #endif /* ! KERNEL */ 360 361 /* 362 * This interface for use by rpc_call() and rpc_broadcast() 363 */ 364 const char * 365 clnt_sperrno(stat) 366 const enum clnt_stat stat; 367 { 368 trace1(TR_clnt_sperrno, 0); 369 switch (stat) { 370 case RPC_SUCCESS: 371 trace1(TR_clnt_sperrno, 1); 372 return (dgettext(__nsl_dom, "RPC: Success")); 373 case RPC_CANTENCODEARGS: 374 trace1(TR_clnt_sperrno, 1); 375 return (dgettext(__nsl_dom, "RPC: Can't encode arguments")); 376 case RPC_CANTDECODERES: 377 trace1(TR_clnt_sperrno, 1); 378 return (dgettext(__nsl_dom, "RPC: Can't decode result")); 379 case RPC_CANTSTORE: 380 trace1(TR_clnt_sperrno, 1); 381 return (dgettext(__nsl_dom, "RPC: Can't store request")); 382 case RPC_CANTSEND: 383 trace1(TR_clnt_sperrno, 1); 384 return (dgettext(__nsl_dom, "RPC: Unable to send")); 385 case RPC_CANTRECV: 386 trace1(TR_clnt_sperrno, 1); 387 return (dgettext(__nsl_dom, "RPC: Unable to receive")); 388 case RPC_TIMEDOUT: 389 trace1(TR_clnt_sperrno, 1); 390 return (dgettext(__nsl_dom, "RPC: Timed out")); 391 case RPC_VERSMISMATCH: 392 trace1(TR_clnt_sperrno, 1); 393 return (dgettext(__nsl_dom, 394 "RPC: Incompatible versions of RPC")); 395 case RPC_AUTHERROR: 396 trace1(TR_clnt_sperrno, 1); 397 return (dgettext(__nsl_dom, "RPC: Authentication error")); 398 case RPC_PROGUNAVAIL: 399 trace1(TR_clnt_sperrno, 1); 400 return (dgettext(__nsl_dom, "RPC: Program unavailable")); 401 case RPC_PROGVERSMISMATCH: 402 trace1(TR_clnt_sperrno, 1); 403 return (dgettext(__nsl_dom, "RPC: Program/version mismatch")); 404 case RPC_PROCUNAVAIL: 405 trace1(TR_clnt_sperrno, 1); 406 return (dgettext(__nsl_dom, "RPC: Procedure unavailable")); 407 case RPC_CANTDECODEARGS: 408 trace1(TR_clnt_sperrno, 1); 409 return (dgettext(__nsl_dom, 410 "RPC: Server can't decode arguments")); 411 412 case RPC_SYSTEMERROR: 413 trace1(TR_clnt_sperrno, 1); 414 return (dgettext(__nsl_dom, "RPC: Remote system error")); 415 case RPC_UNKNOWNHOST: 416 trace1(TR_clnt_sperrno, 1); 417 return (dgettext(__nsl_dom, "RPC: Unknown host")); 418 case RPC_UNKNOWNPROTO: 419 trace1(TR_clnt_sperrno, 1); 420 return (dgettext(__nsl_dom, "RPC: Unknown protocol")); 421 case RPC_RPCBFAILURE: 422 trace1(TR_clnt_sperrno, 1); 423 return (dgettext(__nsl_dom, "RPC: Rpcbind failure")); 424 case RPC_N2AXLATEFAILURE: 425 trace1(TR_clnt_sperrno, 1); 426 return (dgettext(__nsl_dom, 427 "RPC: Name to address translation failed")); 428 case RPC_NOBROADCAST: 429 trace1(TR_clnt_sperrno, 1); 430 return (dgettext(__nsl_dom, "RPC: Broadcast not supported")); 431 case RPC_PROGNOTREGISTERED: 432 trace1(TR_clnt_sperrno, 1); 433 return (dgettext(__nsl_dom, "RPC: Program not registered")); 434 case RPC_UNKNOWNADDR: 435 trace1(TR_clnt_sperrno, 1); 436 return (dgettext(__nsl_dom, 437 "RPC: Remote server address unknown")); 438 case RPC_TLIERROR: 439 trace1(TR_clnt_sperrno, 1); 440 return (dgettext(__nsl_dom, "RPC: Miscellaneous tli error")); 441 case RPC_FAILED: 442 trace1(TR_clnt_sperrno, 1); 443 return (dgettext(__nsl_dom, "RPC: Failed (unspecified error)")); 444 case RPC_INPROGRESS: 445 trace1(TR_clnt_sperrno, 1); 446 return (dgettext(__nsl_dom, "RPC: RAC call in progress")); 447 case RPC_STALERACHANDLE: 448 trace1(TR_clnt_sperrno, 1); 449 return (dgettext(__nsl_dom, "RPC: Stale RAC handle")); 450 case RPC_CANTCONNECT: 451 trace1(TR_clnt_sperrno, 1); 452 return (dgettext(__nsl_dom, "RPC: Couldn't make connection")); 453 case RPC_XPRTFAILED: 454 trace1(TR_clnt_sperrno, 1); 455 return (dgettext(__nsl_dom, 456 "RPC: Received disconnect from remote")); 457 case RPC_CANTCREATESTREAM: 458 trace1(TR_clnt_sperrno, 1); 459 return (dgettext(__nsl_dom, "RPC: Can't push RPC module")); 460 } 461 trace1(TR_clnt_sperrno, 1); 462 return (dgettext(__nsl_dom, "RPC: (unknown error code)")); 463 } 464