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 3299064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 33a986ef57SDavid E. O'Brien static char *sccsid2 = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; 348360efbdSAlfred Perlstein static char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC"; 3599064799SGarrett Wollman #endif 36d3d20c82SDavid E. O'Brien #include <sys/cdefs.h> 37d3d20c82SDavid E. O'Brien __FBSDID("$FreeBSD$"); 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 { 111102c7c92SJohn Birrell enum accept_stat *par_stat; 11299064799SGarrett Wollman 1138360efbdSAlfred Perlstein assert(xdrs != NULL); 1148360efbdSAlfred Perlstein assert(ar != NULL); 1158360efbdSAlfred Perlstein 116102c7c92SJohn Birrell par_stat = &ar->ar_stat; 117102c7c92SJohn Birrell 11899064799SGarrett Wollman /* personalized union, rather than calling xdr_union */ 11999064799SGarrett Wollman if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) 12099064799SGarrett Wollman return (FALSE); 121102c7c92SJohn Birrell if (! xdr_enum(xdrs, (enum_t *) par_stat)) 12299064799SGarrett Wollman return (FALSE); 12399064799SGarrett Wollman switch (ar->ar_stat) { 12499064799SGarrett Wollman 12599064799SGarrett Wollman case SUCCESS: 12699064799SGarrett Wollman return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); 12799064799SGarrett Wollman 12899064799SGarrett Wollman case PROG_MISMATCH: 12939f37784SPeter Wemm if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low))) 13099064799SGarrett Wollman return (FALSE); 13139f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high))); 1328360efbdSAlfred Perlstein 1338360efbdSAlfred Perlstein case GARBAGE_ARGS: 1348360efbdSAlfred Perlstein case SYSTEM_ERR: 1358360efbdSAlfred Perlstein case PROC_UNAVAIL: 1368360efbdSAlfred Perlstein case PROG_UNAVAIL: 137f12d1a5dSJames Raynard break; 13899064799SGarrett Wollman } 13999064799SGarrett Wollman return (TRUE); /* TRUE => open ended set of problems */ 14099064799SGarrett Wollman } 14199064799SGarrett Wollman 14299064799SGarrett Wollman /* 14399064799SGarrett Wollman * XDR the MSG_DENIED part of a reply message union 14499064799SGarrett Wollman */ 14599064799SGarrett Wollman bool_t 14699064799SGarrett Wollman xdr_rejected_reply(xdrs, rr) 1478360efbdSAlfred Perlstein XDR *xdrs; 1488360efbdSAlfred Perlstein struct rejected_reply *rr; 14999064799SGarrett Wollman { 150102c7c92SJohn Birrell enum reject_stat *prj_stat; 151102c7c92SJohn Birrell enum auth_stat *prj_why; 15299064799SGarrett Wollman 1538360efbdSAlfred Perlstein assert(xdrs != NULL); 1548360efbdSAlfred Perlstein assert(rr != NULL); 1558360efbdSAlfred Perlstein 156102c7c92SJohn Birrell prj_stat = &rr->rj_stat; 157102c7c92SJohn Birrell 15899064799SGarrett Wollman /* personalized union, rather than calling xdr_union */ 159102c7c92SJohn Birrell if (! xdr_enum(xdrs, (enum_t *) prj_stat)) 16099064799SGarrett Wollman return (FALSE); 16199064799SGarrett Wollman switch (rr->rj_stat) { 16299064799SGarrett Wollman 16399064799SGarrett Wollman case RPC_MISMATCH: 16439f37784SPeter Wemm if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low))) 16599064799SGarrett Wollman return (FALSE); 16639f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high))); 16799064799SGarrett Wollman 16899064799SGarrett Wollman case AUTH_ERROR: 169102c7c92SJohn Birrell prj_why = &rr->rj_why; 170102c7c92SJohn Birrell return (xdr_enum(xdrs, (enum_t *) prj_why)); 17199064799SGarrett Wollman } 1728360efbdSAlfred Perlstein /* NOTREACHED */ 1738360efbdSAlfred Perlstein assert(0); 17499064799SGarrett Wollman return (FALSE); 17599064799SGarrett Wollman } 17699064799SGarrett Wollman 1778360efbdSAlfred Perlstein static const struct xdr_discrim reply_dscrm[3] = { 1788360efbdSAlfred Perlstein { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply }, 1798360efbdSAlfred Perlstein { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply }, 18099064799SGarrett Wollman { __dontcare__, NULL_xdrproc_t } }; 18199064799SGarrett Wollman 18299064799SGarrett Wollman /* 18399064799SGarrett Wollman * XDR a reply message 18499064799SGarrett Wollman */ 18599064799SGarrett Wollman bool_t 18699064799SGarrett Wollman xdr_replymsg(xdrs, rmsg) 1878360efbdSAlfred Perlstein XDR *xdrs; 1888360efbdSAlfred Perlstein struct rpc_msg *rmsg; 18999064799SGarrett Wollman { 190102c7c92SJohn Birrell enum msg_type *prm_direction; 191102c7c92SJohn Birrell enum reply_stat *prp_stat; 192102c7c92SJohn Birrell 1938360efbdSAlfred Perlstein assert(xdrs != NULL); 1948360efbdSAlfred Perlstein assert(rmsg != NULL); 1958360efbdSAlfred Perlstein 196102c7c92SJohn Birrell prm_direction = &rmsg->rm_direction; 197102c7c92SJohn Birrell prp_stat = &rmsg->rm_reply.rp_stat; 198102c7c92SJohn Birrell 19999064799SGarrett Wollman if ( 20039f37784SPeter Wemm xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) && 201102c7c92SJohn Birrell xdr_enum(xdrs, (enum_t *) prm_direction) && 20299064799SGarrett Wollman (rmsg->rm_direction == REPLY) ) 203102c7c92SJohn Birrell return (xdr_union(xdrs, (enum_t *) prp_stat, 2048360efbdSAlfred Perlstein (caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm, 2058360efbdSAlfred Perlstein NULL_xdrproc_t)); 20699064799SGarrett Wollman return (FALSE); 20799064799SGarrett Wollman } 20899064799SGarrett Wollman 20999064799SGarrett Wollman 21099064799SGarrett Wollman /* 21199064799SGarrett Wollman * Serializes the "static part" of a call message header. 21299064799SGarrett Wollman * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. 21399064799SGarrett Wollman * The rm_xid is not really static, but the user can easily munge on the fly. 21499064799SGarrett Wollman */ 21599064799SGarrett Wollman bool_t 21699064799SGarrett Wollman xdr_callhdr(xdrs, cmsg) 2178360efbdSAlfred Perlstein XDR *xdrs; 2188360efbdSAlfred Perlstein struct rpc_msg *cmsg; 21999064799SGarrett Wollman { 220102c7c92SJohn Birrell enum msg_type *prm_direction; 22199064799SGarrett Wollman 2228360efbdSAlfred Perlstein assert(xdrs != NULL); 2238360efbdSAlfred Perlstein assert(cmsg != NULL); 2248360efbdSAlfred Perlstein 225102c7c92SJohn Birrell prm_direction = &cmsg->rm_direction; 226102c7c92SJohn Birrell 22799064799SGarrett Wollman cmsg->rm_direction = CALL; 22899064799SGarrett Wollman cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; 22999064799SGarrett Wollman if ( 23099064799SGarrett Wollman (xdrs->x_op == XDR_ENCODE) && 23139f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && 232102c7c92SJohn Birrell xdr_enum(xdrs, (enum_t *) prm_direction) && 23339f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 23439f37784SPeter Wemm xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) ) 23539f37784SPeter Wemm return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers))); 23699064799SGarrett Wollman return (FALSE); 23799064799SGarrett Wollman } 23899064799SGarrett Wollman 23999064799SGarrett Wollman /* ************************** Client utility routine ************* */ 24099064799SGarrett Wollman 24199064799SGarrett Wollman static void 24299064799SGarrett Wollman accepted(acpt_stat, error) 2438360efbdSAlfred Perlstein enum accept_stat acpt_stat; 2448360efbdSAlfred Perlstein struct rpc_err *error; 24599064799SGarrett Wollman { 24699064799SGarrett Wollman 2478360efbdSAlfred Perlstein assert(error != NULL); 2488360efbdSAlfred Perlstein 24999064799SGarrett Wollman switch (acpt_stat) { 25099064799SGarrett Wollman 25199064799SGarrett Wollman case PROG_UNAVAIL: 25299064799SGarrett Wollman error->re_status = RPC_PROGUNAVAIL; 25399064799SGarrett Wollman return; 25499064799SGarrett Wollman 25599064799SGarrett Wollman case PROG_MISMATCH: 25699064799SGarrett Wollman error->re_status = RPC_PROGVERSMISMATCH; 25799064799SGarrett Wollman return; 25899064799SGarrett Wollman 25999064799SGarrett Wollman case PROC_UNAVAIL: 26099064799SGarrett Wollman error->re_status = RPC_PROCUNAVAIL; 26199064799SGarrett Wollman return; 26299064799SGarrett Wollman 26399064799SGarrett Wollman case GARBAGE_ARGS: 26499064799SGarrett Wollman error->re_status = RPC_CANTDECODEARGS; 26599064799SGarrett Wollman return; 26699064799SGarrett Wollman 26799064799SGarrett Wollman case SYSTEM_ERR: 26899064799SGarrett Wollman error->re_status = RPC_SYSTEMERROR; 26999064799SGarrett Wollman return; 27099064799SGarrett Wollman 27199064799SGarrett Wollman case SUCCESS: 27299064799SGarrett Wollman error->re_status = RPC_SUCCESS; 27399064799SGarrett Wollman return; 27499064799SGarrett Wollman } 2758360efbdSAlfred Perlstein /* NOTREACHED */ 27699064799SGarrett Wollman /* something's wrong, but we don't know what ... */ 27799064799SGarrett Wollman error->re_status = RPC_FAILED; 2788360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)MSG_ACCEPTED; 2798360efbdSAlfred Perlstein error->re_lb.s2 = (int32_t)acpt_stat; 28099064799SGarrett Wollman } 28199064799SGarrett Wollman 28299064799SGarrett Wollman static void 28399064799SGarrett Wollman rejected(rjct_stat, error) 2848360efbdSAlfred Perlstein enum reject_stat rjct_stat; 2858360efbdSAlfred Perlstein struct rpc_err *error; 28699064799SGarrett Wollman { 28799064799SGarrett Wollman 2888360efbdSAlfred Perlstein assert(error != NULL); 28999064799SGarrett Wollman 2908360efbdSAlfred Perlstein switch (rjct_stat) { 2918360efbdSAlfred Perlstein case RPC_MISMATCH: 29299064799SGarrett Wollman error->re_status = RPC_VERSMISMATCH; 29399064799SGarrett Wollman return; 29499064799SGarrett Wollman 29599064799SGarrett Wollman case AUTH_ERROR: 29699064799SGarrett Wollman error->re_status = RPC_AUTHERROR; 29799064799SGarrett Wollman return; 29899064799SGarrett Wollman } 29999064799SGarrett Wollman /* something's wrong, but we don't know what ... */ 3008360efbdSAlfred Perlstein /* NOTREACHED */ 30199064799SGarrett Wollman error->re_status = RPC_FAILED; 3028360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)MSG_DENIED; 3038360efbdSAlfred Perlstein error->re_lb.s2 = (int32_t)rjct_stat; 30499064799SGarrett Wollman } 30599064799SGarrett Wollman 30699064799SGarrett Wollman /* 30799064799SGarrett Wollman * given a reply message, fills in the error 30899064799SGarrett Wollman */ 30999064799SGarrett Wollman void 31099064799SGarrett Wollman _seterr_reply(msg, error) 3118360efbdSAlfred Perlstein struct rpc_msg *msg; 3128360efbdSAlfred Perlstein struct rpc_err *error; 31399064799SGarrett Wollman { 31499064799SGarrett Wollman 3158360efbdSAlfred Perlstein assert(msg != NULL); 3168360efbdSAlfred Perlstein assert(error != NULL); 3178360efbdSAlfred Perlstein 31899064799SGarrett Wollman /* optimized for normal, SUCCESSful case */ 31999064799SGarrett Wollman switch (msg->rm_reply.rp_stat) { 32099064799SGarrett Wollman 32199064799SGarrett Wollman case MSG_ACCEPTED: 32299064799SGarrett Wollman if (msg->acpted_rply.ar_stat == SUCCESS) { 32399064799SGarrett Wollman error->re_status = RPC_SUCCESS; 32499064799SGarrett Wollman return; 3258360efbdSAlfred Perlstein } 32699064799SGarrett Wollman accepted(msg->acpted_rply.ar_stat, error); 32799064799SGarrett Wollman break; 32899064799SGarrett Wollman 32999064799SGarrett Wollman case MSG_DENIED: 33099064799SGarrett Wollman rejected(msg->rjcted_rply.rj_stat, error); 33199064799SGarrett Wollman break; 33299064799SGarrett Wollman 33399064799SGarrett Wollman default: 33499064799SGarrett Wollman error->re_status = RPC_FAILED; 3358360efbdSAlfred Perlstein error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat); 33699064799SGarrett Wollman break; 33799064799SGarrett Wollman } 33899064799SGarrett Wollman switch (error->re_status) { 33999064799SGarrett Wollman 34099064799SGarrett Wollman case RPC_VERSMISMATCH: 34199064799SGarrett Wollman error->re_vers.low = msg->rjcted_rply.rj_vers.low; 34299064799SGarrett Wollman error->re_vers.high = msg->rjcted_rply.rj_vers.high; 34399064799SGarrett Wollman break; 34499064799SGarrett Wollman 34599064799SGarrett Wollman case RPC_AUTHERROR: 34699064799SGarrett Wollman error->re_why = msg->rjcted_rply.rj_why; 34799064799SGarrett Wollman break; 34899064799SGarrett Wollman 34999064799SGarrett Wollman case RPC_PROGVERSMISMATCH: 35099064799SGarrett Wollman error->re_vers.low = msg->acpted_rply.ar_vers.low; 35199064799SGarrett Wollman error->re_vers.high = msg->acpted_rply.ar_vers.high; 35299064799SGarrett Wollman break; 3538360efbdSAlfred Perlstein 3548360efbdSAlfred Perlstein case RPC_FAILED: 3558360efbdSAlfred Perlstein case RPC_SUCCESS: 3568360efbdSAlfred Perlstein case RPC_PROGNOTREGISTERED: 3578360efbdSAlfred Perlstein case RPC_PMAPFAILURE: 3588360efbdSAlfred Perlstein case RPC_UNKNOWNPROTO: 3598360efbdSAlfred Perlstein case RPC_UNKNOWNHOST: 3608360efbdSAlfred Perlstein case RPC_SYSTEMERROR: 3618360efbdSAlfred Perlstein case RPC_CANTDECODEARGS: 3628360efbdSAlfred Perlstein case RPC_PROCUNAVAIL: 3638360efbdSAlfred Perlstein case RPC_PROGUNAVAIL: 3648360efbdSAlfred Perlstein case RPC_TIMEDOUT: 3658360efbdSAlfred Perlstein case RPC_CANTRECV: 3668360efbdSAlfred Perlstein case RPC_CANTSEND: 3678360efbdSAlfred Perlstein case RPC_CANTDECODERES: 3688360efbdSAlfred Perlstein case RPC_CANTENCODEARGS: 369f12d1a5dSJames Raynard default: 370f12d1a5dSJames Raynard break; 37199064799SGarrett Wollman } 37299064799SGarrett Wollman } 373