/* * XDR a call message */ bool_t xdr_callmsg( register XDR *xdrs, register struct rpc_msg *cmsg) { register uint32_t *buf; register struct opaque_auth *oa; if (xdrs->x_op == XDR_ENCODE) { if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { return (FALSE); } buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_cred.oa_length) + 2 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_verf.oa_length)); if (buf != NULL) { IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_xid); IXDR_PUT_ENUM(buf, (uint32_t)cmsg->rm_direction); if (cmsg->rm_direction != CALL) { return (FALSE); } IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_rpcvers); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { return (FALSE); } IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_prog); IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_vers); IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_proc); oa = &cmsg->rm_call.cb_cred; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_LONG(buf, oa->oa_length); if (oa->oa_length) { bcopy(oa->oa_base, (char*)buf, oa->oa_length); buf += RNDUP(oa->oa_length) / sizeof (*buf); } oa = &cmsg->rm_call.cb_verf; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_LONG(buf, oa->oa_length); if (oa->oa_length) { bcopy(oa->oa_base, (char*)buf, oa->oa_length); /* no real need.... buf += RNDUP(oa->oa_length) / sizeof (*buf); */ } return (TRUE); } } if (xdrs->x_op == XDR_DECODE) { buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); if (buf != NULL) { cmsg->rm_xid = IXDR_GET_LONG(buf); cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); if (cmsg->rm_direction != CALL) { return (FALSE); } cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { return (FALSE); } cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); oa = &cmsg->rm_call.cb_cred; oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_LONG(buf); if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (oa->oa_base == NULL) { oa->oa_base = (char*) mem_alloc(oa->oa_length); } buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) { return (FALSE); } } else { bcopy((char*)buf, oa->oa_base, oa->oa_length); /* no real need.... buf += RNDUP(oa->oa_length) / sizeof (*buf); */ } } oa = &cmsg->rm_call.cb_verf; buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); if (buf == NULL) { if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || xdr_u_int(xdrs, &oa->oa_length) == FALSE) { return (FALSE); } } else { oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_LONG(buf); } if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (oa->oa_base == NULL) { oa->oa_base = (char*) mem_alloc(oa->oa_length); } buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) { return (FALSE); } } else { bcopy((char*)buf, oa->oa_base, oa->oa_length); /* no real need... buf += RNDUP(oa->oa_length) / sizeof (*buf); */ } } return (TRUE); }
/* * XDR a call message */ bool_t xdr_callmsg (XDR *xdrs, struct rpc_msg *cmsg) { int32_t *buf; struct opaque_auth *oa; if (xdrs->x_op == XDR_ENCODE) { if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { return (FALSE); } buf = XDR_INLINE (xdrs, 8 * BYTES_PER_XDR_UNIT + RNDUP (cmsg->rm_call.cb_cred.oa_length) + 2 * BYTES_PER_XDR_UNIT + RNDUP (cmsg->rm_call.cb_verf.oa_length)); if (buf != NULL) { (void) IXDR_PUT_LONG (buf, cmsg->rm_xid); (void) IXDR_PUT_ENUM (buf, cmsg->rm_direction); if (cmsg->rm_direction != CALL) return FALSE; (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_rpcvers); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) return FALSE; (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_prog); (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_vers); (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_proc); oa = &cmsg->rm_call.cb_cred; (void) IXDR_PUT_ENUM (buf, oa->oa_flavor); (void) IXDR_PUT_INT32 (buf, oa->oa_length); if (oa->oa_length) { memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length); buf = (int32_t *) ((char *) buf + RNDUP (oa->oa_length)); } oa = &cmsg->rm_call.cb_verf; (void) IXDR_PUT_ENUM (buf, oa->oa_flavor); (void) IXDR_PUT_INT32 (buf, oa->oa_length); if (oa->oa_length) { memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length); /* no real need.... buf = (long *) ((char *) buf + RNDUP(oa->oa_length)); */ } return TRUE; } } if (xdrs->x_op == XDR_DECODE) { buf = XDR_INLINE (xdrs, 8 * BYTES_PER_XDR_UNIT); if (buf != NULL) { cmsg->rm_xid = IXDR_GET_LONG (buf); cmsg->rm_direction = IXDR_GET_ENUM (buf, enum msg_type); if (cmsg->rm_direction != CALL) { return FALSE; } cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG (buf); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { return FALSE; } cmsg->rm_call.cb_prog = IXDR_GET_LONG (buf); cmsg->rm_call.cb_vers = IXDR_GET_LONG (buf); cmsg->rm_call.cb_proc = IXDR_GET_LONG (buf); oa = &cmsg->rm_call.cb_cred; oa->oa_flavor = IXDR_GET_ENUM (buf, enum_t); oa->oa_length = IXDR_GET_INT32 (buf); if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) return FALSE; if (oa->oa_base == NULL) { oa->oa_base = (caddr_t) mem_alloc (oa->oa_length); } buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length)); if (buf == NULL) { if (INTUSE(xdr_opaque) (xdrs, oa->oa_base, oa->oa_length) == FALSE) return FALSE; } else { memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length); /* no real need.... buf = (long *) ((char *) buf + RNDUP(oa->oa_length)); */ } } oa = &cmsg->rm_call.cb_verf; buf = XDR_INLINE (xdrs, 2 * BYTES_PER_XDR_UNIT); if (buf == NULL) { if (INTUSE(xdr_enum) (xdrs, &oa->oa_flavor) == FALSE || INTUSE(xdr_u_int) (xdrs, &oa->oa_length) == FALSE) { return FALSE; } } else { oa->oa_flavor = IXDR_GET_ENUM (buf, enum_t); oa->oa_length = IXDR_GET_INT32 (buf); } if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) return FALSE; if (oa->oa_base == NULL) { oa->oa_base = (caddr_t) mem_alloc (oa->oa_length); } buf = XDR_INLINE (xdrs, RNDUP (oa->oa_length)); if (buf == NULL) { if (INTUSE(xdr_opaque) (xdrs, oa->oa_base, oa->oa_length) == FALSE) return FALSE; } else { memcpy (oa->oa_base, (caddr_t) buf, oa->oa_length); /* no real need... buf = (long *) ((char *) buf + RNDUP(oa->oa_length)); */ } } return TRUE; }
/* * XDR a call message */ bool_t xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) { rpc_inline_t *buf; struct opaque_auth *oa; if (xdrs->x_op == XDR_ENCODE) { if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) return (FALSE); if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) return (FALSE); buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_cred.oa_length) + 2 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_verf.oa_length)); if (buf != NULL) { IXDR_PUT_INT32(buf, cmsg->rm_xid); IXDR_PUT_ENUM(buf, cmsg->rm_direction); if (cmsg->rm_direction != CALL) return (FALSE); IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) return (FALSE); IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); oa = &cmsg->rm_call.cb_cred; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_INT32(buf, oa->oa_length); if (oa->oa_length) { (void) memcpy(buf, oa->oa_base, oa->oa_length); buf += RNDUP(oa->oa_length) / sizeof (int32_t); } oa = &cmsg->rm_call.cb_verf; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_INT32(buf, oa->oa_length); if (oa->oa_length) { (void) memcpy(buf, oa->oa_base, oa->oa_length); /* * no real need.... * buf += RNDUP(oa->oa_length) / sizeof * (int32_t); */ } return (TRUE); } } if (xdrs->x_op == XDR_DECODE) { buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); if (buf != NULL) { cmsg->rm_xid = IXDR_GET_INT32(buf); cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); if (cmsg->rm_direction != CALL) return (FALSE); cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) return (FALSE); cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf); cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf); cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf); oa = &cmsg->rm_call.cb_cred; oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_INT32(buf); if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) return (FALSE); if (oa->oa_base == NULL) { oa->oa_base = malloc(oa->oa_length); if (oa->oa_base == NULL) { syslog(LOG_ERR, "xdr_callmsg : " "out of memory."); return (FALSE); } } buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) return (FALSE); } else { (void) memcpy(oa->oa_base, buf, (size_t)oa->oa_length); /* * no real need.... * buf += RNDUP(oa->oa_length) / * (int)sizeof (int32_t); */ } } oa = &cmsg->rm_call.cb_verf; buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); if (buf == NULL) { if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || xdr_u_int(xdrs, &oa->oa_length) == FALSE) return (FALSE); } else { oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_INT32(buf); } if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) return (FALSE); if (oa->oa_base == NULL) { oa->oa_base = malloc(oa->oa_length); if (oa->oa_base == NULL) { syslog(LOG_ERR, "xdr_callmsg : " "out of memory."); return (FALSE); } } buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) return (FALSE); } else { (void) memcpy(oa->oa_base, buf, (size_t)oa->oa_length); /* * no real need... * buf += RNDUP(oa->oa_length) / * (int)sizeof (int32_t); */ } } return (TRUE); }
/* * decode a reply message * * param[IN] buf 3 more inline */ bool xdr_reply_decode(XDR *xdrs, struct rpc_msg *dmsg, int32_t *buf) { if (buf != NULL) { __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u INLINE", __func__, __LINE__); dmsg->rm_reply.rp_stat = IXDR_GET_ENUM(buf, enum_t); } else { __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u non-INLINE", __func__, __LINE__); if (!xdr_getenum(xdrs, (enum_t *)&(dmsg->rm_reply.rp_stat))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR rm_reply.rp_stat", __func__, __LINE__); return (false); } } switch (dmsg->rm_reply.rp_stat) { case MSG_ACCEPTED: { struct accepted_reply *ar = (struct accepted_reply *) &(dmsg->rm_reply.ru); if (!inline_auth_decode(xdrs, &ar->ar_verf, buf)) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR (return)", __func__, __LINE__); return (false); } if (!xdr_getenum(xdrs, (enum_t *)&(ar->ar_stat))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR ar_stat", __func__, __LINE__); return (false); } switch (ar->ar_stat) { case SUCCESS: __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u SUCCESS", __func__, __LINE__); return ((*(ar->ar_results.proc))(xdrs, &(ar->ar_results.where))); case PROG_MISMATCH: __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u MISMATCH", __func__, __LINE__); if (!xdr_getuint32(xdrs, &(ar->ar_vers.low))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR ar_vers.low", __func__, __LINE__); return (false); } if (!xdr_getuint32(xdrs, &(ar->ar_vers.high))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR ar_vers.high", __func__, __LINE__); return (false); } case GARBAGE_ARGS: case SYSTEM_ERR: case PROC_UNAVAIL: case PROG_UNAVAIL: /* true */ break; default: break; }; /* ar_stat */ return (true); } /* MSG_ACCEPTED */ case MSG_DENIED: { /* XXX branch not verified */ struct rejected_reply *rr = (struct rejected_reply *) &(dmsg->rm_reply.ru); __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u MSG_DENIED not verified", __func__, __LINE__); if (buf != NULL) { rr->rj_stat = IXDR_GET_ENUM(buf, enum_t); } else if (!xdr_getenum(xdrs, (enum_t *)&(rr->rj_stat))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR rj_stat", __func__, __LINE__); return (false); } switch (rr->rj_stat) { case RPC_MISMATCH: __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u DENIED MISMATCH", __func__, __LINE__); if (buf != NULL) { rr->rj_vers.low = IXDR_GET_U_INT32(buf); } else if (!xdr_getuint32(xdrs, &(rr->rj_vers.low))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR rj_vers.low", __func__, __LINE__); return (false); } if (!xdr_getuint32(xdrs, &(rr->rj_vers.high))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR rj_vers.high", __func__, __LINE__); return (false); } break; case AUTH_ERROR: __warnx(TIRPC_DEBUG_FLAG_RPC_MSG, "%s:%u DENIED AUTH", __func__, __LINE__); if (buf != NULL) { rr->rj_why = IXDR_GET_ENUM(buf, enum_t); } else if (!xdr_getenum(xdrs, (enum_t *)&(rr->rj_why))) { __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR rj_why", __func__, __LINE__); return (false); } break; }; return (true); } /* MSG_DENIED */ default: __warnx(TIRPC_DEBUG_FLAG_ERROR, "%s:%u ERROR dmsg->rm_reply.rp_stat %u", __func__, __LINE__, dmsg->rm_reply.rp_stat); break; }; /* rm_reply.rp_stat */ return (false); }