|
|
1.1 ! root 1: /* ! 2: * Sun RPC is a product of Sun Microsystems, Inc. and is provided for ! 3: * unrestricted use provided that this legend is included on all tape ! 4: * media and as a part of the software program in whole or part. Users ! 5: * may copy or modify Sun RPC without charge, but are not authorized ! 6: * to license or distribute it to anyone else except as part of a product or ! 7: * program developed by the user. ! 8: * ! 9: * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE ! 10: * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR ! 11: * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. ! 12: * ! 13: * Sun RPC is provided with no support and without any obligation on the ! 14: * part of Sun Microsystems, Inc. to assist in its use, correction, ! 15: * modification or enhancement. ! 16: * ! 17: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE ! 18: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC ! 19: * OR ANY PART THEREOF. ! 20: * ! 21: * In no event will Sun Microsystems, Inc. be liable for any lost revenue ! 22: * or profits or other special, indirect and consequential damages, even if ! 23: * Sun has been advised of the possibility of such damages. ! 24: * ! 25: * Sun Microsystems, Inc. ! 26: * 2550 Garcia Avenue ! 27: * Mountain View, California 94043 ! 28: */ ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)rpc_prot.c 1.5 85/03/20 Copyr 1984 Sun Micro"; ! 31: #endif ! 32: ! 33: /* ! 34: * rpc_prot.c ! 35: * ! 36: * Copyright (C) 1984, Sun Microsystems, Inc. ! 37: * ! 38: * This set of routines implements the rpc message definition, ! 39: * its serializer and some common rpc utility routines. ! 40: * The routines are meant for various implementations of rpc - ! 41: * they are NOT for the rpc client or rpc service implementations! ! 42: * Because authentication stuff is easy and is part of rpc, the opaque ! 43: * routines are also in this program. ! 44: */ ! 45: ! 46: #include "types.h" ! 47: #include "xdr.h" ! 48: #include "auth.h" ! 49: #include "clnt.h" ! 50: #include "rpc_msg.h" ! 51: ! 52: /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ ! 53: ! 54: struct opaque_auth _null_auth; ! 55: ! 56: /* ! 57: * XDR an opaque authentication struct ! 58: * (see auth.h) ! 59: */ ! 60: bool_t ! 61: xdr_opaque_auth(xdrs, ap) ! 62: register XDR *xdrs; ! 63: register struct opaque_auth *ap; ! 64: { ! 65: ! 66: if (xdr_enum(xdrs, &(ap->oa_flavor))) ! 67: return (xdr_bytes(xdrs, &ap->oa_base, ! 68: &ap->oa_length, MAX_AUTH_BYTES)); ! 69: return (FALSE); ! 70: } ! 71: ! 72: /* ! 73: * XDR a DES key. ! 74: */ ! 75: bool_t ! 76: xdr_deskey(xdrs, blkp) ! 77: register XDR *xdrs; ! 78: register union des_block *blkp; ! 79: { ! 80: ! 81: if (! xdr_u_long(xdrs, &(blkp->key.high))) ! 82: return (FALSE); ! 83: return (xdr_u_long(xdrs, &(blkp->key.low))); ! 84: } ! 85: ! 86: /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ ! 87: ! 88: /* ! 89: * XDR the MSG_ACCEPTED part of a reply message union ! 90: */ ! 91: bool_t ! 92: xdr_accepted_reply(xdrs, ar) ! 93: register XDR *xdrs; ! 94: register struct accepted_reply *ar; ! 95: { ! 96: ! 97: /* personalized union, rather than calling xdr_union */ ! 98: if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) ! 99: return (FALSE); ! 100: if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) ! 101: return (FALSE); ! 102: switch (ar->ar_stat) { ! 103: ! 104: case SUCCESS: ! 105: return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); ! 106: ! 107: case PROG_MISMATCH: ! 108: if (! xdr_u_long(xdrs, &(ar->ar_vers.low))) ! 109: return (FALSE); ! 110: return (xdr_u_long(xdrs, &(ar->ar_vers.high))); ! 111: } ! 112: return (TRUE); /* TRUE => open ended set of problems */ ! 113: } ! 114: ! 115: /* ! 116: * XDR the MSG_DENIED part of a reply message union ! 117: */ ! 118: bool_t ! 119: xdr_rejected_reply(xdrs, rr) ! 120: register XDR *xdrs; ! 121: register struct rejected_reply *rr; ! 122: { ! 123: ! 124: /* personalized union, rather than calling xdr_union */ ! 125: if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) ! 126: return (FALSE); ! 127: switch (rr->rj_stat) { ! 128: ! 129: case RPC_MISMATCH: ! 130: if (! xdr_u_long(xdrs, &(rr->rj_vers.low))) ! 131: return (FALSE); ! 132: return (xdr_u_long(xdrs, &(rr->rj_vers.high))); ! 133: ! 134: case AUTH_ERROR: ! 135: return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); ! 136: } ! 137: return (FALSE); ! 138: } ! 139: ! 140: static struct xdr_discrim reply_dscrm[3] = { ! 141: { (int)MSG_ACCEPTED, xdr_accepted_reply }, ! 142: { (int)MSG_DENIED, xdr_rejected_reply }, ! 143: { __dontcare__, NULL_xdrproc_t } }; ! 144: ! 145: /* ! 146: * XDR a reply message ! 147: */ ! 148: bool_t ! 149: xdr_replymsg(xdrs, rmsg) ! 150: register XDR *xdrs; ! 151: register struct rpc_msg *rmsg; ! 152: { ! 153: ! 154: if ( ! 155: xdr_u_long(xdrs, &(rmsg->rm_xid)) && ! 156: xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && ! 157: (rmsg->rm_direction == REPLY) ) ! 158: return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), ! 159: (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); ! 160: return (FALSE); ! 161: } ! 162: ! 163: /* ! 164: * XDR a call message ! 165: */ ! 166: bool_t ! 167: xdr_callmsg(xdrs, cmsg) ! 168: register XDR *xdrs; ! 169: register struct rpc_msg *cmsg; ! 170: { ! 171: ! 172: if ( ! 173: xdr_u_long(xdrs, &(cmsg->rm_xid)) && ! 174: xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && ! 175: (cmsg->rm_direction == CALL) && ! 176: xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && ! 177: (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && ! 178: xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) && ! 179: xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) && ! 180: xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) && ! 181: xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) ! 182: return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); ! 183: return (FALSE); ! 184: } ! 185: ! 186: /* ! 187: * Serializes the "static part" of a call message header. ! 188: * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. ! 189: * The rm_xid is not really static, but the user can easily munge on the fly. ! 190: */ ! 191: bool_t ! 192: xdr_callhdr(xdrs, cmsg) ! 193: register XDR *xdrs; ! 194: register struct rpc_msg *cmsg; ! 195: { ! 196: ! 197: cmsg->rm_direction = CALL; ! 198: cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; ! 199: if ( ! 200: (xdrs->x_op == XDR_ENCODE) && ! 201: xdr_u_long(xdrs, &(cmsg->rm_xid)) && ! 202: xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && ! 203: xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && ! 204: xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) ) ! 205: return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers))); ! 206: return (FALSE); ! 207: } ! 208: ! 209: /* ************************** Client utility routine ************* */ ! 210: ! 211: static void ! 212: accepted(acpt_stat, error) ! 213: register enum accept_stat acpt_stat; ! 214: register struct rpc_err *error; ! 215: { ! 216: ! 217: switch (acpt_stat) { ! 218: ! 219: case PROG_UNAVAIL: ! 220: error->re_status = RPC_PROGUNAVAIL; ! 221: return; ! 222: ! 223: case PROG_MISMATCH: ! 224: error->re_status = RPC_PROGVERSMISMATCH; ! 225: return; ! 226: ! 227: case PROC_UNAVAIL: ! 228: error->re_status = RPC_PROCUNAVAIL; ! 229: return; ! 230: ! 231: case GARBAGE_ARGS: ! 232: error->re_status = RPC_CANTDECODEARGS; ! 233: return; ! 234: ! 235: case SYSTEM_ERR: ! 236: error->re_status = RPC_SYSTEMERROR; ! 237: return; ! 238: ! 239: case SUCCESS: ! 240: error->re_status = RPC_SUCCESS; ! 241: return; ! 242: } ! 243: /* something's wrong, but we don't know what ... */ ! 244: error->re_status = RPC_FAILED; ! 245: error->re_lb.s1 = (long)MSG_ACCEPTED; ! 246: error->re_lb.s2 = (long)acpt_stat; ! 247: } ! 248: ! 249: static void ! 250: rejected(rjct_stat, error) ! 251: register enum reject_stat rjct_stat; ! 252: register struct rpc_err *error; ! 253: { ! 254: ! 255: switch (rjct_stat) { ! 256: ! 257: case RPC_VERSMISMATCH: ! 258: error->re_status = RPC_VERSMISMATCH; ! 259: return; ! 260: ! 261: case AUTH_ERROR: ! 262: error->re_status = RPC_AUTHERROR; ! 263: return; ! 264: } ! 265: /* something's wrong, but we don't know what ... */ ! 266: error->re_status = RPC_FAILED; ! 267: error->re_lb.s1 = (long)MSG_DENIED; ! 268: error->re_lb.s2 = (long)rjct_stat; ! 269: } ! 270: ! 271: /* ! 272: * given a reply message, fills in the error ! 273: */ ! 274: void ! 275: _seterr_reply(msg, error) ! 276: register struct rpc_msg *msg; ! 277: register struct rpc_err *error; ! 278: { ! 279: ! 280: /* optimized for normal, SUCCESSful case */ ! 281: switch (msg->rm_reply.rp_stat) { ! 282: ! 283: case MSG_ACCEPTED: ! 284: if (msg->acpted_rply.ar_stat == SUCCESS) { ! 285: error->re_status = RPC_SUCCESS; ! 286: return; ! 287: }; ! 288: accepted(msg->acpted_rply.ar_stat, error); ! 289: break; ! 290: ! 291: case MSG_DENIED: ! 292: rejected(msg->rjcted_rply.rj_stat, error); ! 293: break; ! 294: ! 295: default: ! 296: error->re_status = RPC_FAILED; ! 297: error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); ! 298: break; ! 299: } ! 300: switch (error->re_status) { ! 301: ! 302: case RPC_VERSMISMATCH: ! 303: error->re_vers.low = msg->rjcted_rply.rj_vers.low; ! 304: error->re_vers.high = msg->rjcted_rply.rj_vers.high; ! 305: break; ! 306: ! 307: case RPC_AUTHERROR: ! 308: error->re_why = msg->rjcted_rply.rj_why; ! 309: break; ! 310: ! 311: case RPC_PROGVERSMISMATCH: ! 312: error->re_vers.low = msg->acpted_rply.ar_vers.low; ! 313: error->re_vers.high = msg->acpted_rply.ar_vers.high; ! 314: break; ! 315: } ! 316: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.