174462Salfred/* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */ 274462Salfred 3261046Smav/*- 4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261046Smav * All rights reserved. 68870Srgrimes * 7261046Smav * Redistribution and use in source and binary forms, with or without 8261046Smav * modification, are permitted provided that the following conditions are met: 9261046Smav * - Redistributions of source code must retain the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer. 11261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261046Smav * this list of conditions and the following disclaimer in the documentation 13261046Smav * and/or other materials provided with the distribution. 14261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261046Smav * contributors may be used to endorse or promote products derived 16261046Smav * from this software without specific prior written permission. 17261046Smav * 18261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261046Smav * POSSIBILITY OF SUCH DAMAGE. 291901Swollman */ 301901Swollman 311901Swollman#if defined(LIBC_SCCS) && !defined(lint) 32136581Sobrienstatic char *sccsid2 = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; 3374462Salfredstatic char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC"; 341901Swollman#endif 3592990Sobrien#include <sys/cdefs.h> 3692990Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/rpc_prot.c 309494 2016-12-03 18:17:06Z ngie $"); 371901Swollman 381901Swollman/* 391901Swollman * rpc_prot.c 401901Swollman * 411901Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 421901Swollman * 431901Swollman * This set of routines implements the rpc message definition, 441901Swollman * its serializer and some common rpc utility routines. 451901Swollman * The routines are meant for various implementations of rpc - 461901Swollman * they are NOT for the rpc client or rpc service implementations! 471901Swollman * Because authentication stuff is easy and is part of rpc, the opaque 481901Swollman * routines are also in this program. 491901Swollman */ 501901Swollman 5174462Salfred#include "namespace.h" 521901Swollman#include <sys/param.h> 531901Swollman 5474462Salfred#include <assert.h> 5574462Salfred 561901Swollman#include <rpc/rpc.h> 5774462Salfred#include "un-namespace.h" 581901Swollman 5992905Sobrienstatic void accepted(enum accept_stat, struct rpc_err *); 6092905Sobrienstatic void rejected(enum reject_stat, struct rpc_err *); 6174462Salfred 621901Swollman/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ 631901Swollman 6474462Salfredextern struct opaque_auth _null_auth; 651901Swollman 661901Swollman/* 671901Swollman * XDR an opaque authentication struct 681901Swollman * (see auth.h) 691901Swollman */ 701901Swollmanbool_t 71309494Sngiexdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap) 721901Swollman{ 731901Swollman 7474462Salfred assert(xdrs != NULL); 7574462Salfred assert(ap != NULL); 7674462Salfred 771901Swollman if (xdr_enum(xdrs, &(ap->oa_flavor))) 781901Swollman return (xdr_bytes(xdrs, &ap->oa_base, 791901Swollman &ap->oa_length, MAX_AUTH_BYTES)); 801901Swollman return (FALSE); 811901Swollman} 821901Swollman 831901Swollman/* 841901Swollman * XDR a DES block 851901Swollman */ 861901Swollmanbool_t 87309494Sngiexdr_des_block(XDR *xdrs, des_block *blkp) 881901Swollman{ 8974462Salfred 9074462Salfred assert(xdrs != NULL); 9174462Salfred assert(blkp != NULL); 9274462Salfred 9374462Salfred return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block))); 941901Swollman} 951901Swollman 961901Swollman/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ 971901Swollman 981901Swollman/* 991901Swollman * XDR the MSG_ACCEPTED part of a reply message union 1001901Swollman */ 1018870Srgrimesbool_t 102309494Sngiexdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar) 1031901Swollman{ 104173763Sjb enum accept_stat *par_stat; 1051901Swollman 10674462Salfred assert(xdrs != NULL); 10774462Salfred assert(ar != NULL); 10874462Salfred 109173763Sjb par_stat = &ar->ar_stat; 110173763Sjb 1111901Swollman /* personalized union, rather than calling xdr_union */ 1121901Swollman if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) 1131901Swollman return (FALSE); 114173763Sjb if (! xdr_enum(xdrs, (enum_t *) par_stat)) 1151901Swollman return (FALSE); 1161901Swollman switch (ar->ar_stat) { 1171901Swollman 1181901Swollman case SUCCESS: 1191901Swollman return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); 1201901Swollman 1211901Swollman case PROG_MISMATCH: 122309493Sngie if (!xdr_rpcvers(xdrs, &(ar->ar_vers.low))) 1231901Swollman return (FALSE); 124309493Sngie return (xdr_rpcvers(xdrs, &(ar->ar_vers.high))); 12574462Salfred 12674462Salfred case GARBAGE_ARGS: 12774462Salfred case SYSTEM_ERR: 12874462Salfred case PROC_UNAVAIL: 12974462Salfred case PROG_UNAVAIL: 13016283Sjraynard break; 1311901Swollman } 1321901Swollman return (TRUE); /* TRUE => open ended set of problems */ 1331901Swollman} 1341901Swollman 1351901Swollman/* 1361901Swollman * XDR the MSG_DENIED part of a reply message union 1371901Swollman */ 13874462Salfredbool_t 139309494Sngiexdr_rejected_reply(XDR *xdrs, struct rejected_reply *rr) 1401901Swollman{ 141173763Sjb enum reject_stat *prj_stat; 142173763Sjb enum auth_stat *prj_why; 1431901Swollman 14474462Salfred assert(xdrs != NULL); 14574462Salfred assert(rr != NULL); 14674462Salfred 147173763Sjb prj_stat = &rr->rj_stat; 148173763Sjb 1491901Swollman /* personalized union, rather than calling xdr_union */ 150173763Sjb if (! xdr_enum(xdrs, (enum_t *) prj_stat)) 1511901Swollman return (FALSE); 1521901Swollman switch (rr->rj_stat) { 1531901Swollman 1541901Swollman case RPC_MISMATCH: 155309493Sngie if (! xdr_rpcvers(xdrs, &(rr->rj_vers.low))) 1561901Swollman return (FALSE); 157309493Sngie return (xdr_rpcvers(xdrs, &(rr->rj_vers.high))); 1581901Swollman 1591901Swollman case AUTH_ERROR: 160173763Sjb prj_why = &rr->rj_why; 161173763Sjb return (xdr_enum(xdrs, (enum_t *) prj_why)); 1621901Swollman } 16374462Salfred /* NOTREACHED */ 16474462Salfred assert(0); 1651901Swollman return (FALSE); 1661901Swollman} 1671901Swollman 16874462Salfredstatic const struct xdr_discrim reply_dscrm[3] = { 16974462Salfred { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply }, 17074462Salfred { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply }, 1711901Swollman { __dontcare__, NULL_xdrproc_t } }; 1721901Swollman 1731901Swollman/* 1741901Swollman * XDR a reply message 1751901Swollman */ 1761901Swollmanbool_t 177309494Sngiexdr_replymsg(XDR *xdrs, struct rpc_msg *rmsg) 1781901Swollman{ 179173763Sjb enum msg_type *prm_direction; 180173763Sjb enum reply_stat *prp_stat; 181173763Sjb 18274462Salfred assert(xdrs != NULL); 18374462Salfred assert(rmsg != NULL); 18474462Salfred 185173763Sjb prm_direction = &rmsg->rm_direction; 186173763Sjb prp_stat = &rmsg->rm_reply.rp_stat; 187173763Sjb 1881901Swollman if ( 18974462Salfred xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) && 190173763Sjb xdr_enum(xdrs, (enum_t *) prm_direction) && 1911901Swollman (rmsg->rm_direction == REPLY) ) 192173763Sjb return (xdr_union(xdrs, (enum_t *) prp_stat, 19374462Salfred (caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm, 19474462Salfred NULL_xdrproc_t)); 1951901Swollman return (FALSE); 1961901Swollman} 1971901Swollman 1981901Swollman 1991901Swollman/* 2001901Swollman * Serializes the "static part" of a call message header. 2011901Swollman * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. 2021901Swollman * The rm_xid is not really static, but the user can easily munge on the fly. 2031901Swollman */ 2041901Swollmanbool_t 205309494Sngiexdr_callhdr(XDR *xdrs, struct rpc_msg *cmsg) 2061901Swollman{ 207173763Sjb enum msg_type *prm_direction; 2081901Swollman 20974462Salfred assert(xdrs != NULL); 21074462Salfred assert(cmsg != NULL); 21174462Salfred 212173763Sjb prm_direction = &cmsg->rm_direction; 213173763Sjb 2141901Swollman cmsg->rm_direction = CALL; 2151901Swollman cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; 2161901Swollman if ( 2171901Swollman (xdrs->x_op == XDR_ENCODE) && 21821086Speter xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && 219173763Sjb xdr_enum(xdrs, (enum_t *) prm_direction) && 220309493Sngie xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 221309493Sngie xdr_rpcprog(xdrs, &(cmsg->rm_call.cb_prog)) ) 22274462Salfred return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers))); 2231901Swollman return (FALSE); 2241901Swollman} 2251901Swollman 2261901Swollman/* ************************** Client utility routine ************* */ 2271901Swollman 2281901Swollmanstatic void 229309494Sngieaccepted(enum accept_stat acpt_stat, struct rpc_err *error) 2301901Swollman{ 2311901Swollman 23274462Salfred assert(error != NULL); 23374462Salfred 2341901Swollman switch (acpt_stat) { 2351901Swollman 2361901Swollman case PROG_UNAVAIL: 2371901Swollman error->re_status = RPC_PROGUNAVAIL; 2381901Swollman return; 2391901Swollman 2401901Swollman case PROG_MISMATCH: 2411901Swollman error->re_status = RPC_PROGVERSMISMATCH; 2421901Swollman return; 2431901Swollman 2441901Swollman case PROC_UNAVAIL: 2451901Swollman error->re_status = RPC_PROCUNAVAIL; 2461901Swollman return; 2471901Swollman 2481901Swollman case GARBAGE_ARGS: 2491901Swollman error->re_status = RPC_CANTDECODEARGS; 2501901Swollman return; 2511901Swollman 2521901Swollman case SYSTEM_ERR: 2531901Swollman error->re_status = RPC_SYSTEMERROR; 2541901Swollman return; 2551901Swollman 2561901Swollman case SUCCESS: 2571901Swollman error->re_status = RPC_SUCCESS; 2581901Swollman return; 2591901Swollman } 26074462Salfred /* NOTREACHED */ 2611901Swollman /* something's wrong, but we don't know what ... */ 2621901Swollman error->re_status = RPC_FAILED; 26374462Salfred error->re_lb.s1 = (int32_t)MSG_ACCEPTED; 26474462Salfred error->re_lb.s2 = (int32_t)acpt_stat; 2651901Swollman} 2661901Swollman 26774462Salfredstatic void 268309487Sngierejected(enum reject_stat rjct_stat, struct rpc_err *error) 2691901Swollman{ 2701901Swollman 27174462Salfred assert(error != NULL); 27274462Salfred 2731901Swollman switch (rjct_stat) { 27474462Salfred case RPC_MISMATCH: 2751901Swollman error->re_status = RPC_VERSMISMATCH; 2761901Swollman return; 2771901Swollman 2781901Swollman case AUTH_ERROR: 2791901Swollman error->re_status = RPC_AUTHERROR; 2801901Swollman return; 2811901Swollman } 2821901Swollman /* something's wrong, but we don't know what ... */ 28374462Salfred /* NOTREACHED */ 2841901Swollman error->re_status = RPC_FAILED; 28574462Salfred error->re_lb.s1 = (int32_t)MSG_DENIED; 28674462Salfred error->re_lb.s2 = (int32_t)rjct_stat; 2871901Swollman} 2881901Swollman 2891901Swollman/* 2901901Swollman * given a reply message, fills in the error 2911901Swollman */ 2921901Swollmanvoid 293309487Sngie_seterr_reply(struct rpc_msg *msg, struct rpc_err *error) 2941901Swollman{ 2951901Swollman 29674462Salfred assert(msg != NULL); 29774462Salfred assert(error != NULL); 29874462Salfred 2991901Swollman /* optimized for normal, SUCCESSful case */ 3001901Swollman switch (msg->rm_reply.rp_stat) { 3011901Swollman 3021901Swollman case MSG_ACCEPTED: 3031901Swollman if (msg->acpted_rply.ar_stat == SUCCESS) { 3041901Swollman error->re_status = RPC_SUCCESS; 3051901Swollman return; 30674462Salfred } 3071901Swollman accepted(msg->acpted_rply.ar_stat, error); 3081901Swollman break; 3091901Swollman 3101901Swollman case MSG_DENIED: 3111901Swollman rejected(msg->rjcted_rply.rj_stat, error); 3121901Swollman break; 3131901Swollman 3141901Swollman default: 3151901Swollman error->re_status = RPC_FAILED; 31674462Salfred error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat); 3171901Swollman break; 3181901Swollman } 3191901Swollman switch (error->re_status) { 3201901Swollman 3211901Swollman case RPC_VERSMISMATCH: 3221901Swollman error->re_vers.low = msg->rjcted_rply.rj_vers.low; 3231901Swollman error->re_vers.high = msg->rjcted_rply.rj_vers.high; 3241901Swollman break; 3251901Swollman 3261901Swollman case RPC_AUTHERROR: 3271901Swollman error->re_why = msg->rjcted_rply.rj_why; 3281901Swollman break; 3291901Swollman 3301901Swollman case RPC_PROGVERSMISMATCH: 3311901Swollman error->re_vers.low = msg->acpted_rply.ar_vers.low; 3321901Swollman error->re_vers.high = msg->acpted_rply.ar_vers.high; 3331901Swollman break; 33474462Salfred 33574462Salfred case RPC_FAILED: 33674462Salfred case RPC_SUCCESS: 33774462Salfred case RPC_PROGNOTREGISTERED: 33874462Salfred case RPC_PMAPFAILURE: 33974462Salfred case RPC_UNKNOWNPROTO: 34074462Salfred case RPC_UNKNOWNHOST: 34174462Salfred case RPC_SYSTEMERROR: 34274462Salfred case RPC_CANTDECODEARGS: 34374462Salfred case RPC_PROCUNAVAIL: 34474462Salfred case RPC_PROGUNAVAIL: 34574462Salfred case RPC_TIMEDOUT: 34674462Salfred case RPC_CANTRECV: 34774462Salfred case RPC_CANTSEND: 34874462Salfred case RPC_CANTDECODERES: 34974462Salfred case RPC_CANTENCODEARGS: 35016283Sjraynard default: 35116283Sjraynard break; 3521901Swollman } 3531901Swollman} 354