18360efbdSAlfred Perlstein /* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */ 28360efbdSAlfred Perlstein 399064799SGarrett Wollman /* 499064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 599064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 699064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 799064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 899064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 999064799SGarrett Wollman * program developed by the user. 1099064799SGarrett Wollman * 1199064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1299064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1399064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1499064799SGarrett Wollman * 1599064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1699064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1799064799SGarrett Wollman * modification or enhancement. 1899064799SGarrett Wollman * 1999064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2099064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2199064799SGarrett Wollman * OR ANY PART THEREOF. 2299064799SGarrett Wollman * 2399064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2499064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2599064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2699064799SGarrett Wollman * 2799064799SGarrett Wollman * Sun Microsystems, Inc. 2899064799SGarrett Wollman * 2550 Garcia Avenue 2999064799SGarrett Wollman * Mountain View, California 94043 3099064799SGarrett Wollman */ 3199064799SGarrett Wollman 328360efbdSAlfred Perlstein #include <sys/cdefs.h> 3399064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 348360efbdSAlfred Perlstein static char *sccsid = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; 358360efbdSAlfred Perlstein static char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC"; 367f3dea24SPeter Wemm static char *rcsid = "$FreeBSD$"; 3799064799SGarrett Wollman #endif 3899064799SGarrett Wollman 3999064799SGarrett Wollman /* 4099064799SGarrett Wollman * rpc_prot.c 4199064799SGarrett Wollman * 4299064799SGarrett Wollman * Copyright (C) 1984, Sun Microsystems, Inc. 4399064799SGarrett Wollman * 4499064799SGarrett Wollman * This set of routines implements the rpc message definition, 4599064799SGarrett Wollman * its serializer and some common rpc utility routines. 4699064799SGarrett Wollman * The routines are meant for various implementations of rpc - 4799064799SGarrett Wollman * they are NOT for the rpc client or rpc service implementations! 4899064799SGarrett Wollman * Because authentication stuff is easy and is part of rpc, the opaque 4999064799SGarrett Wollman * routines are also in this program. 5099064799SGarrett Wollman */ 5199064799SGarrett Wollman 528360efbdSAlfred Perlstein #include "namespace.h" 5399064799SGarrett Wollman #include <sys/param.h> 5499064799SGarrett Wollman 558360efbdSAlfred Perlstein #include <assert.h> 568360efbdSAlfred Perlstein 5799064799SGarrett Wollman #include <rpc/rpc.h> 588360efbdSAlfred Perlstein #include "un-namespace.h" 598360efbdSAlfred Perlstein 60c05ac53bSDavid E. O'Brien static void accepted(enum accept_stat, struct rpc_err *); 61c05ac53bSDavid E. O'Brien static void rejected(enum reject_stat, struct rpc_err *); 6299064799SGarrett Wollman 6399064799SGarrett Wollman /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ 6499064799SGarrett Wollman 658360efbdSAlfred Perlstein extern struct opaque_auth _null_auth; 6699064799SGarrett Wollman 6799064799SGarrett Wollman /* 6899064799SGarrett Wollman * XDR an opaque authentication struct 6999064799SGarrett Wollman * (see auth.h) 7099064799SGarrett Wollman */ 7199064799SGarrett Wollman bool_t 7299064799SGarrett Wollman xdr_opaque_auth(xdrs, ap) 738360efbdSAlfred Perlstein XDR *xdrs; 748360efbdSAlfred Perlstein struct opaque_auth *ap; 7599064799SGarrett Wollman { 7699064799SGarrett Wollman 778360efbdSAlfred Perlstein assert(xdrs != NULL); 788360efbdSAlfred Perlstein assert(ap != NULL); 798360efbdSAlfred Perlstein 8099064799SGarrett Wollman if (xdr_enum(xdrs, &(ap->oa_flavor))) 8199064799SGarrett Wollman return (xdr_bytes(xdrs, &ap->oa_base, 8299064799SGarrett Wollman &ap->oa_length, MAX_AUTH_BYTES)); 8399064799SGarrett Wollman return (FALSE); 8499064799SGarrett Wollman } 8599064799SGarrett Wollman 8699064799SGarrett Wollman /* 8799064799SGarrett Wollman * XDR a DES block 8899064799SGarrett Wollman */ 8999064799SGarrett Wollman bool_t 9099064799SGarrett Wollman xdr_des_block(xdrs, blkp) 918360efbdSAlfred Perlstein XDR *xdrs; 928360efbdSAlfred Perlstein des_block *blkp; 9399064799SGarrett Wollman { 948360efbdSAlfred Perlstein 958360efbdSAlfred Perlstein assert(xdrs != NULL); 968360efbdSAlfred Perlstein assert(blkp != NULL); 978360efbdSAlfred Perlstein 988360efbdSAlfred Perlstein return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block))); 9999064799SGarrett Wollman } 10099064799SGarrett Wollman 10199064799SGarrett Wollman /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ 10299064799SGarrett Wollman 10399064799SGarrett Wollman /* 10499064799SGarrett Wollman * XDR the MSG_ACCEPTED part of a reply message union 10599064799SGarrett Wollman */ 10699064799SGarrett Wollman bool_t 10799064799SGarrett Wollman xdr_accepted_reply(xdrs, ar) 1088360efbdSAlfred Perlstein XDR *xdrs; 1098360efbdSAlfred Perlstein struct accepted_reply *ar; 11099064799SGarrett Wollman { 11199064799SGarrett Wollman 1128360efbdSAlfred Perlstein assert(xdrs != NULL); 1138360efbdSAlfred Perlstein assert(ar != NULL); 1148360efbdSAlfred Perlstein 11599064799SGarrett Wollman /* personalized union, rather than calling xdr_union */ 11699064799SGarrett Wollman if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) 11799064799SGarrett Wollman return (FALSE); 11899064799SGarrett Wollman if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) 11999064799SGarrett Wollman return (FALSE); 12099064799SGarrett Wollman switch (ar->ar_stat) { 12199064799SGarrett Wollman 12299064799SGarrett Wollman case SUCCESS: 12399064799SGarrett Wollman return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); 12499064799SGarrett Wollman 12599064799SGarrett Wollman case PROG_MISMATCH: 12639f37784SPeter Wemm if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low))) 12799064799SGarrett Wollman return (FALSE); 12839f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high))); 1298360efbdSAlfred Perlstein 1308360efbdSAlfred Perlstein case GARBAGE_ARGS: 1318360efbdSAlfred Perlstein case SYSTEM_ERR: 1328360efbdSAlfred Perlstein case PROC_UNAVAIL: 1338360efbdSAlfred Perlstein case PROG_UNAVAIL: 134f12d1a5dSJames Raynard break; 13599064799SGarrett Wollman } 13699064799SGarrett Wollman return (TRUE); /* TRUE => open ended set of problems */ 13799064799SGarrett Wollman } 13899064799SGarrett Wollman 13999064799SGarrett Wollman /* 14099064799SGarrett Wollman * XDR the MSG_DENIED part of a reply message union 14199064799SGarrett Wollman */ 14299064799SGarrett Wollman bool_t 14399064799SGarrett Wollman xdr_rejected_reply(xdrs, rr) 1448360efbdSAlfred Perlstein XDR *xdrs; 1458360efbdSAlfred Perlstein struct rejected_reply *rr; 14699064799SGarrett Wollman { 14799064799SGarrett Wollman 1488360efbdSAlfred Perlstein assert(xdrs != NULL); 1498360efbdSAlfred Perlstein assert(rr != NULL); 1508360efbdSAlfred Perlstein 15199064799SGarrett Wollman /* personalized union, rather than calling xdr_union */ 15299064799SGarrett Wollman if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) 15399064799SGarrett Wollman return (FALSE); 15499064799SGarrett Wollman switch (rr->rj_stat) { 15599064799SGarrett Wollman 15699064799SGarrett Wollman case RPC_MISMATCH: 15739f37784SPeter Wemm if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low))) 15899064799SGarrett Wollman return (FALSE); 15939f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high))); 16099064799SGarrett Wollman 16199064799SGarrett Wollman case AUTH_ERROR: 16299064799SGarrett Wollman return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); 16399064799SGarrett Wollman } 1648360efbdSAlfred Perlstein /* NOTREACHED */ 1658360efbdSAlfred Perlstein assert(0); 16699064799SGarrett Wollman return (FALSE); 16799064799SGarrett Wollman } 16899064799SGarrett Wollman 1698360efbdSAlfred Perlstein static const struct xdr_discrim reply_dscrm[3] = { 1708360efbdSAlfred Perlstein { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply }, 1718360efbdSAlfred Perlstein { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply }, 17299064799SGarrett Wollman { __dontcare__, NULL_xdrproc_t } }; 17399064799SGarrett Wollman 17499064799SGarrett Wollman /* 17599064799SGarrett Wollman * XDR a reply message 17699064799SGarrett Wollman */ 17799064799SGarrett Wollman bool_t 17899064799SGarrett Wollman xdr_replymsg(xdrs, rmsg) 1798360efbdSAlfred Perlstein XDR *xdrs; 1808360efbdSAlfred Perlstein struct rpc_msg *rmsg; 18199064799SGarrett Wollman { 1828360efbdSAlfred Perlstein assert(xdrs != NULL); 1838360efbdSAlfred Perlstein assert(rmsg != NULL); 1848360efbdSAlfred Perlstein 18599064799SGarrett Wollman if ( 18639f37784SPeter Wemm xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) && 18799064799SGarrett Wollman xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && 18899064799SGarrett Wollman (rmsg->rm_direction == REPLY) ) 18999064799SGarrett Wollman return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), 1908360efbdSAlfred Perlstein (caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm, 1918360efbdSAlfred Perlstein NULL_xdrproc_t)); 19299064799SGarrett Wollman return (FALSE); 19399064799SGarrett Wollman } 19499064799SGarrett Wollman 19599064799SGarrett Wollman 19699064799SGarrett Wollman /* 19799064799SGarrett Wollman * Serializes the "static part" of a call message header. 19899064799SGarrett Wollman * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. 19999064799SGarrett Wollman * The rm_xid is not really static, but the user can easily munge on the fly. 20099064799SGarrett Wollman */ 20199064799SGarrett Wollman bool_t 20299064799SGarrett Wollman xdr_callhdr(xdrs, cmsg) 2038360efbdSAlfred Perlstein XDR *xdrs; 2048360efbdSAlfred Perlstein struct rpc_msg *cmsg; 20599064799SGarrett Wollman { 20699064799SGarrett Wollman 2078360efbdSAlfred Perlstein assert(xdrs != NULL); 2088360efbdSAlfred Perlstein assert(cmsg != NULL); 2098360efbdSAlfred Perlstein 21099064799SGarrett Wollman cmsg->rm_direction = CALL; 21199064799SGarrett Wollman cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; 21299064799SGarrett Wollman if ( 21399064799SGarrett Wollman (xdrs->x_op == XDR_ENCODE) && 21439f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && 21599064799SGarrett Wollman xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 21639f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 21739f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) ) 21839f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers))); 21999064799SGarrett Wollman return (FALSE); 22099064799SGarrett Wollman } 22199064799SGarrett Wollman 22299064799SGarrett Wollman /* ************************** Client utility routine ************* */ 22399064799SGarrett Wollman 22499064799SGarrett Wollman static void 22599064799SGarrett Wollman accepted(acpt_stat, error) 2268360efbdSAlfred Perlstein enum accept_stat acpt_stat; 2278360efbdSAlfred Perlstein struct rpc_err *error; 22899064799SGarrett Wollman { 22999064799SGarrett Wollman 2308360efbdSAlfred Perlstein assert(error != NULL); 2318360efbdSAlfred Perlstein 23299064799SGarrett Wollman switch (acpt_stat) { 23399064799SGarrett Wollman 23499064799SGarrett Wollman case PROG_UNAVAIL: 23599064799SGarrett Wollman error->re_status = RPC_PROGUNAVAIL; 23699064799SGarrett Wollman return; 23799064799SGarrett Wollman 23899064799SGarrett Wollman case PROG_MISMATCH: 23999064799SGarrett Wollman error->re_status = RPC_PROGVERSMISMATCH; 24099064799SGarrett Wollman return; 24199064799SGarrett Wollman 24299064799SGarrett Wollman case PROC_UNAVAIL: 24399064799SGarrett Wollman error->re_status = RPC_PROCUNAVAIL; 24499064799SGarrett Wollman return; 24599064799SGarrett Wollman 24699064799SGarrett Wollman case GARBAGE_ARGS: 24799064799SGarrett Wollman error->re_status = RPC_CANTDECODEARGS; 24899064799SGarrett Wollman return; 24999064799SGarrett Wollman 25099064799SGarrett Wollman case SYSTEM_ERR: 25199064799SGarrett Wollman error->re_status = RPC_SYSTEMERROR; 25299064799SGarrett Wollman return; 25399064799SGarrett Wollman 25499064799SGarrett Wollman case SUCCESS: 25599064799SGarrett Wollman error->re_status = RPC_SUCCESS; 25699064799SGarrett Wollman return; 25799064799SGarrett Wollman } 2588360efbdSAlfred Perlstein /* NOTREACHED */ 25999064799SGarrett Wollman /* something's wrong, but we don't know what ... */ 26099064799SGarrett Wollman error->re_status = RPC_FAILED; 2618360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)MSG_ACCEPTED; 2628360efbdSAlfred Perlstein error->re_lb.s2 = (int32_t)acpt_stat; 26399064799SGarrett Wollman } 26499064799SGarrett Wollman 26599064799SGarrett Wollman static void 26699064799SGarrett Wollman rejected(rjct_stat, error) 2678360efbdSAlfred Perlstein enum reject_stat rjct_stat; 2688360efbdSAlfred Perlstein struct rpc_err *error; 26999064799SGarrett Wollman { 27099064799SGarrett Wollman 2718360efbdSAlfred Perlstein assert(error != NULL); 27299064799SGarrett Wollman 2738360efbdSAlfred Perlstein switch (rjct_stat) { 2748360efbdSAlfred Perlstein case RPC_MISMATCH: 27599064799SGarrett Wollman error->re_status = RPC_VERSMISMATCH; 27699064799SGarrett Wollman return; 27799064799SGarrett Wollman 27899064799SGarrett Wollman case AUTH_ERROR: 27999064799SGarrett Wollman error->re_status = RPC_AUTHERROR; 28099064799SGarrett Wollman return; 28199064799SGarrett Wollman } 28299064799SGarrett Wollman /* something's wrong, but we don't know what ... */ 2838360efbdSAlfred Perlstein /* NOTREACHED */ 28499064799SGarrett Wollman error->re_status = RPC_FAILED; 2858360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)MSG_DENIED; 2868360efbdSAlfred Perlstein error->re_lb.s2 = (int32_t)rjct_stat; 28799064799SGarrett Wollman } 28899064799SGarrett Wollman 28999064799SGarrett Wollman /* 29099064799SGarrett Wollman * given a reply message, fills in the error 29199064799SGarrett Wollman */ 29299064799SGarrett Wollman void 29399064799SGarrett Wollman _seterr_reply(msg, error) 2948360efbdSAlfred Perlstein struct rpc_msg *msg; 2958360efbdSAlfred Perlstein struct rpc_err *error; 29699064799SGarrett Wollman { 29799064799SGarrett Wollman 2988360efbdSAlfred Perlstein assert(msg != NULL); 2998360efbdSAlfred Perlstein assert(error != NULL); 3008360efbdSAlfred Perlstein 30199064799SGarrett Wollman /* optimized for normal, SUCCESSful case */ 30299064799SGarrett Wollman switch (msg->rm_reply.rp_stat) { 30399064799SGarrett Wollman 30499064799SGarrett Wollman case MSG_ACCEPTED: 30599064799SGarrett Wollman if (msg->acpted_rply.ar_stat == SUCCESS) { 30699064799SGarrett Wollman error->re_status = RPC_SUCCESS; 30799064799SGarrett Wollman return; 3088360efbdSAlfred Perlstein } 30999064799SGarrett Wollman accepted(msg->acpted_rply.ar_stat, error); 31099064799SGarrett Wollman break; 31199064799SGarrett Wollman 31299064799SGarrett Wollman case MSG_DENIED: 31399064799SGarrett Wollman rejected(msg->rjcted_rply.rj_stat, error); 31499064799SGarrett Wollman break; 31599064799SGarrett Wollman 31699064799SGarrett Wollman default: 31799064799SGarrett Wollman error->re_status = RPC_FAILED; 3188360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat); 31999064799SGarrett Wollman break; 32099064799SGarrett Wollman } 32199064799SGarrett Wollman switch (error->re_status) { 32299064799SGarrett Wollman 32399064799SGarrett Wollman case RPC_VERSMISMATCH: 32499064799SGarrett Wollman error->re_vers.low = msg->rjcted_rply.rj_vers.low; 32599064799SGarrett Wollman error->re_vers.high = msg->rjcted_rply.rj_vers.high; 32699064799SGarrett Wollman break; 32799064799SGarrett Wollman 32899064799SGarrett Wollman case RPC_AUTHERROR: 32999064799SGarrett Wollman error->re_why = msg->rjcted_rply.rj_why; 33099064799SGarrett Wollman break; 33199064799SGarrett Wollman 33299064799SGarrett Wollman case RPC_PROGVERSMISMATCH: 33399064799SGarrett Wollman error->re_vers.low = msg->acpted_rply.ar_vers.low; 33499064799SGarrett Wollman error->re_vers.high = msg->acpted_rply.ar_vers.high; 33599064799SGarrett Wollman break; 3368360efbdSAlfred Perlstein 3378360efbdSAlfred Perlstein case RPC_FAILED: 3388360efbdSAlfred Perlstein case RPC_SUCCESS: 3398360efbdSAlfred Perlstein case RPC_PROGNOTREGISTERED: 3408360efbdSAlfred Perlstein case RPC_PMAPFAILURE: 3418360efbdSAlfred Perlstein case RPC_UNKNOWNPROTO: 3428360efbdSAlfred Perlstein case RPC_UNKNOWNHOST: 3438360efbdSAlfred Perlstein case RPC_SYSTEMERROR: 3448360efbdSAlfred Perlstein case RPC_CANTDECODEARGS: 3458360efbdSAlfred Perlstein case RPC_PROCUNAVAIL: 3468360efbdSAlfred Perlstein case RPC_PROGUNAVAIL: 3478360efbdSAlfred Perlstein case RPC_TIMEDOUT: 3488360efbdSAlfred Perlstein case RPC_CANTRECV: 3498360efbdSAlfred Perlstein case RPC_CANTSEND: 3508360efbdSAlfred Perlstein case RPC_CANTDECODERES: 3518360efbdSAlfred Perlstein case RPC_CANTENCODEARGS: 352f12d1a5dSJames Raynard default: 353f12d1a5dSJames Raynard break; 35499064799SGarrett Wollman } 35599064799SGarrett Wollman } 356