static enum clnt_stat clnttcp_call(struct client *clnt, uint32_t procnum, xdrproc_t inproc, char *in, xdrproc_t outproc, char *out, struct timeval timeout) { struct xdr xstream; struct rpc_msg msg_reply, msg_call; assert((clnt != NULL) && (inproc != NULL)); msg_call.xid = (uint32_t)rand(); msg_call.type = CALL; msg_call.b.call.rpcvers = RPC_VERSION; msg_call.b.call.prog = clnt->prognum; msg_call.b.call.vers = clnt->versnum; msg_call.b.call.proc = procnum; memcpy(&msg_call.b.call.cred, &clnt->ath->cred, sizeof clnt->ath->cred); memcpy(&msg_call.b.call.verf, &clnt->ath->verf, sizeof clnt->ath->verf); if (-1 == setsockopt(clnt->sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout)) { LOG_ERROR("clnttcp_call", "setsockopt error"); clnt->err.extra.error = errno; return clnt->err.status = RPC_SYSTEMERROR; } xdrrec_create(&xstream, clnt->extra.tcp.sendsz, clnt->extra.tcp.recvsz, (char *)clnt, (xdrrec_hnd_t)readtcp, (xdrrec_hnd_t)writetcp); xstream.oper = XDR_ENCODE; clnt->err.status = RPC_SUCCESS; if (!xdr_rpc_msg(&xstream, &msg_call) || !(*inproc)(&xstream, in)) { if (clnt->err.status == RPC_SUCCESS) { clnt->err.status = RPC_CANTENCODEARGS; } goto exit_with_status; } if (!xdrrec_endofrecord(&xstream, 1)) { clnt->err.status = RPC_CANTSEND; goto exit_with_status; } xstream.oper = XDR_DECODE; msg_reply.b.reply.r.accepted.d.result.decoder = outproc; msg_reply.b.reply.r.accepted.d.result.param = out; assert(clnt->err.status == RPC_SUCCESS); if (!xdr_rpc_msg(&xstream, &msg_reply)) { if (clnt->err.status == RPC_SUCCESS) { clnt->err.status = RPC_CANTDECODERES; } goto exit_with_status; } assert(clnt->err.status == RPC_SUCCESS); exit_with_status: xdr_destroy(&xstream); return clnt->err.status; }
static bool_t Svctcp_reply(SVCXPRT * xprt, register struct rpc_msg *msg) { register struct tcp_conn *cd = (struct tcp_conn *)(xprt->xp_p1); register XDR *xdrs = &(cd->xdrs); xdrproc_t xdr_proc; caddr_t xdr_where; xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; if(msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { xdr_proc = msg->acpted_rply.ar_results.proc; xdr_where = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; msg->acpted_rply.ar_results.where = NULL; if(!xdr_replymsg(xdrs, msg) || !SVCAUTH_WRAP(NULL, xdrs, xdr_proc, xdr_where)) return (FALSE); } else if(!xdr_replymsg(xdrs, msg)) { return (FALSE); } (void)xdrrec_endofrecord(xdrs, TRUE); return (TRUE); }
/* * ndmp_send_response * * Send an NDMP reply message. * * Parameters: * connection_handle (input) - connection pointer. * err (input) - error code to place in header. * reply (input) - reply message body. * * Returns: * 0 - successful send. * -1 - error. * * Notes: * - The body is only sent if the error code is NDMP_NO_ERR. */ int ndmp_send_response(ndmp_connection_t *connection_handle, ndmp_error err, void *reply) { ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle; ndmp_header header; struct timeval time; (void) gettimeofday(&time, 0); header.sequence = ++(connection->conn_my_sequence); header.time_stamp = time.tv_sec; header.message_type = NDMP_MESSAGE_REPLY; header.message = connection->conn_msginfo.mi_hdr.message; header.reply_sequence = connection->conn_msginfo.mi_hdr.sequence; header.error = err; connection->conn_xdrs.x_op = XDR_ENCODE; if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) { NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: " "encoding reply header", header.message); (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); return (-1); } if (err == NDMP_NO_ERR && connection->conn_msginfo.mi_handler->mh_xdr_reply && reply) { if (!(*connection->conn_msginfo.mi_handler->mh_xdr_reply)( &connection->conn_xdrs, reply)) { NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: encoding reply body", header.message); (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); return (-1); } } (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); return (0); }
static bool_t svctcp_reply (SVCXPRT *xprt, struct rpc_msg *msg) { struct tcp_conn *cd = (struct tcp_conn *) (xprt->xp_p1); XDR *xdrs = &(cd->xdrs); bool_t stat; xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; stat = xdr_replymsg (xdrs, msg); (void) xdrrec_endofrecord (xdrs, TRUE); return stat; }
int CMSendMessage(int communicationDescriptor, void *message) { if ( message == NULL ) return errno = EINVAL, -1; if ( CMInternalData.capacity < UINT_MAX && (unsigned int)communicationDescriptor >= CMInternalData.capacity) return errno = EINVAL, -1; CMCommunicationDescriptionContext *communicationContexts = CMInternalData.CMCommunicationContexts; CMCommunicationDescriptionContext *context = &(communicationContexts[communicationDescriptor]); if (context->communicationDescriptor != communicationDescriptor) return errno = EINVAL, -1; if (context->socket == -1) return errno = EINVAL, -1; if (context->converterf == NULL) return errno = EINVAL, -1; // CC_SHA1((const unsigned char *)line->content, size, line->id); // SHA1((const unsigned char *)line->content, size, line->id); XDR *xdrs = &(context->xdrs); xdrs->x_op = XDR_ENCODE; bool_t result = context->converterf(xdrs, message, 0); if ( result == (TRUE) ) return (xdrrec_endofrecord(xdrs, (TRUE) ) == 1) ? 0 : (errno = EINVAL, -1); return -1; }
static enum clnt_stat clnt_vc_call(CLIENT *cl, rpcproc_t proc, xdrproc_t xdr_args, void *args_ptr, xdrproc_t xdr_results, void *results_ptr, struct timeval timeout) { struct ct_data *ct = (struct ct_data *) cl->cl_private; XDR *xdrs = &(ct->ct_xdrs); struct rpc_msg reply_msg; u_int32_t x_id; u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */ bool_t shipnow; int refreshes = 2; sigset_t mask, newmask; int rpc_lock_value; bool_t reply_stat; assert(cl != NULL); sigfillset(&newmask); thr_sigsetmask(SIG_SETMASK, &newmask, &mask); mutex_lock(&clnt_fd_lock); while (vc_fd_locks[ct->ct_fd]) cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); if (__isthreaded) rpc_lock_value = 1; else rpc_lock_value = 0; vc_fd_locks[ct->ct_fd] = rpc_lock_value; mutex_unlock(&clnt_fd_lock); if (!ct->ct_waitset) { /* If time is not within limits, we ignore it. */ if (time_not_ok(&timeout) == FALSE) ct->ct_wait = timeout; } shipnow = (xdr_results == NULL && timeout.tv_sec == 0 && timeout.tv_usec == 0) ? FALSE : TRUE; call_again: xdrs->x_op = XDR_ENCODE; ct->ct_error.re_status = RPC_SUCCESS; x_id = ntohl(--(*msg_x_id)); if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) || (! XDR_PUTINT32(xdrs, &proc)) || (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || (! (*xdr_args)(xdrs, args_ptr))) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } } else { *(uint32_t *) &ct->ct_u.ct_mcallc[ct->ct_mpos] = htonl(proc); if (! __rpc_gss_wrap(cl->cl_auth, ct->ct_u.ct_mcallc, ct->ct_mpos + sizeof(uint32_t), xdrs, xdr_args, args_ptr)) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } } if (! xdrrec_endofrecord(xdrs, shipnow)) { release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status = RPC_CANTSEND); } if (! shipnow) { release_fd_lock(ct->ct_fd, mask); return (RPC_SUCCESS); } /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { release_fd_lock(ct->ct_fd, mask); return(ct->ct_error.re_status = RPC_TIMEDOUT); } /* * Keep receiving until we get a valid transaction id */ xdrs->x_op = XDR_DECODE; while (TRUE) { reply_msg.acpted_rply.ar_verf = _null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; if (! xdrrec_skiprecord(xdrs)) { release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } /* now decode and validate the response header */ if (! xdr_replymsg(xdrs, &reply_msg)) { if (ct->ct_error.re_status == RPC_SUCCESS) continue; release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } if (reply_msg.rm_xid == x_id) break; } /* * process header */ _seterr_reply(&reply_msg, &(ct->ct_error)); if (ct->ct_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(cl->cl_auth, &reply_msg.acpted_rply.ar_verf)) { ct->ct_error.re_status = RPC_AUTHERROR; ct->ct_error.re_why = AUTH_INVALIDRESP; } else { if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) { reply_stat = (*xdr_results)(xdrs, results_ptr); } else { reply_stat = __rpc_gss_unwrap(cl->cl_auth, xdrs, xdr_results, results_ptr); } if (! reply_stat) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTDECODERES; } } /* free verifier ... */ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg)) goto call_again; } /* end of unsuccessful completion */ release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); }
static enum clnt_stat clnttcp_call(CLIENT *h, u_long proc, xdrproc_t xdr_args, caddr_t args_ptr, xdrproc_t xdr_results, caddr_t results_ptr, struct timeval timeout) { struct ct_data *ct = (struct ct_data *) h->cl_private; XDR *xdrs = &(ct->ct_xdrs); struct rpc_msg reply_msg; u_long x_id; u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */ bool_t shipnow; int refreshes = 2; if (!ct->ct_waitset) { ct->ct_wait = timeout; } shipnow = (xdr_results == NULL && timeout.tv_sec == 0 && timeout.tv_usec == 0) ? FALSE : TRUE; call_again: xdrs->x_op = XDR_ENCODE; ct->ct_error.re_status = RPC_SUCCESS; x_id = ntohl(--(*msg_x_id)); if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || (! XDR_PUTLONG(xdrs, (long *)&proc)) || (! AUTH_MARSHALL(h->cl_auth, xdrs)) || (! (*xdr_args)(xdrs, args_ptr))) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); return (ct->ct_error.re_status); } if (! xdrrec_endofrecord(xdrs, shipnow)) return (ct->ct_error.re_status = RPC_CANTSEND); if (! shipnow) return (RPC_SUCCESS); /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { return(ct->ct_error.re_status = RPC_TIMEDOUT); } /* * Keep receiving until we get a valid transaction id */ xdrs->x_op = XDR_DECODE; while (TRUE) { reply_msg.acpted_rply.ar_verf = _null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = xdr_void; if (! xdrrec_skiprecord(xdrs)) return (ct->ct_error.re_status); /* now decode and validate the response header */ if (! xdr_replymsg(xdrs, &reply_msg)) { if (ct->ct_error.re_status == RPC_SUCCESS) continue; return (ct->ct_error.re_status); } if (reply_msg.rm_xid == x_id) break; } /* * process header */ _seterr_reply(&reply_msg, &(ct->ct_error)); if (ct->ct_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { ct->ct_error.re_status = RPC_AUTHERROR; ct->ct_error.re_why = AUTH_INVALIDRESP; } else if (! (*xdr_results)(xdrs, results_ptr)) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTDECODERES; } /* free verifier ... */ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (refreshes-- && AUTH_REFRESH(h->cl_auth)) goto call_again; } /* end of unsuccessful completion */ return (ct->ct_error.re_status); }
static enum clnt_stat clnt_vc_call( CLIENT *h, rpcproc_t proc, xdrproc_t xdr_args, const char *args_ptr, xdrproc_t xdr_results, caddr_t results_ptr, struct timeval timeout ) { struct ct_data *ct; XDR *xdrs; struct rpc_msg reply_msg; u_int32_t x_id; u_int32_t *msg_x_id; bool_t shipnow; int refreshes = 2; #ifdef _REENTRANT sigset_t mask, newmask; #endif _DIAGASSERT(h != NULL); ct = (struct ct_data *) h->cl_private; #ifdef _REENTRANT __clnt_sigfillset(&newmask); thr_sigsetmask(SIG_SETMASK, &newmask, &mask); mutex_lock(&clnt_fd_lock); while (vc_fd_locks[ct->ct_fd]) cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock); vc_fd_locks[ct->ct_fd] = __rpc_lock_value; mutex_unlock(&clnt_fd_lock); #endif xdrs = &(ct->ct_xdrs); msg_x_id = &ct->ct_u.ct_mcalli; if (!ct->ct_waitset) { if (time_not_ok(&timeout) == FALSE) ct->ct_wait = timeout; } shipnow = (xdr_results == NULL && timeout.tv_sec == 0 && timeout.tv_usec == 0) ? FALSE : TRUE; call_again: xdrs->x_op = XDR_ENCODE; ct->ct_error.re_status = RPC_SUCCESS; x_id = ntohl(--(*msg_x_id)); if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) || (! XDR_PUTINT32(xdrs, (int32_t *)&proc)) || (! AUTH_MARSHALL(h->cl_auth, xdrs)) || (! (*xdr_args)(xdrs, __UNCONST(args_ptr)))) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } if (! xdrrec_endofrecord(xdrs, shipnow)) { release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status = RPC_CANTSEND); } if (! shipnow) { release_fd_lock(ct->ct_fd, mask); return (RPC_SUCCESS); } /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { release_fd_lock(ct->ct_fd, mask); return(ct->ct_error.re_status = RPC_TIMEDOUT); } /* * Keep receiving until we get a valid transaction id */ xdrs->x_op = XDR_DECODE; for (;;) { reply_msg.acpted_rply.ar_verf = _null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; if (! xdrrec_skiprecord(xdrs)) { release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } /* now decode and validate the response header */ if (! xdr_replymsg(xdrs, &reply_msg)) { if (ct->ct_error.re_status == RPC_SUCCESS) continue; release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); } if (reply_msg.rm_xid == x_id) break; } /* * process header */ _seterr_reply(&reply_msg, &(ct->ct_error)); if (ct->ct_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { ct->ct_error.re_status = RPC_AUTHERROR; ct->ct_error.re_why = AUTH_INVALIDRESP; } else if (! (*xdr_results)(xdrs, results_ptr)) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTDECODERES; } /* free verifier ... */ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (refreshes-- && AUTH_REFRESH(h->cl_auth)) goto call_again; } /* end of unsuccessful completion */ release_fd_lock(ct->ct_fd, mask); return (ct->ct_error.re_status); }
/* * ndmp_send_request * * Send an NDMP request message. * * Parameters: * connection_handle (input) - connection pointer. * message (input) - message number. * err (input) - error code to place in header. * request_data (input) - message body. * reply (output) - reply message. If 0, reply will be * discarded. * * Returns: * 0 - successful send. * -1 - error. * otherwise - error from reply header. * * Notes: * - The reply body is only returned if the error code is NDMP_NO_ERR. */ int ndmp_send_request(ndmp_connection_t *connection_handle, ndmp_message message, ndmp_error err, void *request_data, void **reply) { ndmp_connection_t *connection = (ndmp_connection_t *)connection_handle; ndmp_header header; ndmp_msg_handler_t *handler; int r; struct timeval time; /* Lookup info necessary for processing this request. */ if (!(handler = ndmp_get_handler(connection, message))) { NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: not supported", message); return (-1); } (void) gettimeofday(&time, 0); header.sequence = ++(connection->conn_my_sequence); header.time_stamp = time.tv_sec; header.message_type = NDMP_MESSAGE_REQUEST; header.message = message; header.reply_sequence = 0; header.error = err; connection->conn_xdrs.x_op = XDR_ENCODE; if (!xdr_ndmp_header(&connection->conn_xdrs, &header)) { NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: encoding request header", message); (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); return (-1); } if (err == NDMP_NO_ERR && handler->mh_xdr_request && request_data) { if (!(*handler->mh_xdr_request)(&connection->conn_xdrs, request_data)) { NDMP_LOG(LOG_DEBUG, "Sending message 0x%x: encoding request body", message); (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); return (-1); } } (void) xdrrec_endofrecord(&connection->conn_xdrs, 1); if (handler->mh_xdr_reply == 0) { NDMP_LOG(LOG_DEBUG, "handler->mh_xdr_reply == 0"); return (0); } /* * Process messages until the reply to this request has been * processed. */ for (; ; ) { r = ndmp_process_messages(connection, TRUE); /* connection error? */ if (r < 0) return (-1); /* no reply received? */ if (r == 0) continue; /* reply received? */ if (r == 1) { if (message != connection->conn_msginfo.mi_hdr.message) { NDMP_LOG(LOG_DEBUG, "Received unexpected reply 0x%x", connection->conn_msginfo.mi_hdr.message); ndmp_free_message(connection_handle); return (-1); } if (reply != NULL) *reply = connection->conn_msginfo.mi_body; else ndmp_free_message(connection_handle); return (connection->conn_msginfo.mi_hdr.error); } /* error handling reply */ return (-1); } }
bool_t P_xdrrec_endofrecord(XDR *x, int now) {return (xdrrec_endofrecord(x, now));}
static enum clnt_stat clnttcp_call( CLIENT *h, rpcproc_t proc, xdrproc_t xdr_args, void * args_ptr, xdrproc_t xdr_results, void * results_ptr, struct timeval timeout) { struct ct_data *ct = h->cl_private; XDR *xdrs = &ct->ct_xdrs; struct rpc_msg reply_msg; uint32_t x_id; uint32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */ bool_t shipnow; int refreshes = 2; long procl = proc; if (!ct->ct_waitset) { ct->ct_wait = timeout; } shipnow = (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 && timeout.tv_usec == 0) ? FALSE : TRUE; call_again: xdrs->x_op = XDR_ENCODE; ct->ct_error.re_status = RPC_SUCCESS; x_id = ntohl(--(*msg_x_id)); if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcall, ct->ct_mpos)) || (! XDR_PUTLONG(xdrs, &procl)) || (! AUTH_MARSHALL(h->cl_auth, xdrs)) || (! AUTH_WRAP(h->cl_auth, xdrs, xdr_args, args_ptr))) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); return (ct->ct_error.re_status); } if (! xdrrec_endofrecord(xdrs, shipnow)) return (ct->ct_error.re_status = RPC_CANTSEND); if (! shipnow) return (RPC_SUCCESS); /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { return(ct->ct_error.re_status = RPC_TIMEDOUT); } /* * Keep receiving until we get a valid transaction id */ xdrs->x_op = XDR_DECODE; while (TRUE) { reply_msg.acpted_rply.ar_verf = gssrpc__null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = xdr_void; if (! xdrrec_skiprecord(xdrs)) return (ct->ct_error.re_status); /* now decode and validate the response header */ if (! xdr_replymsg(xdrs, &reply_msg)) { /* * Free some stuff allocated by xdr_replymsg() * to avoid leaks, since it may allocate * memory from partially successful decodes. */ enum xdr_op op = xdrs->x_op; xdrs->x_op = XDR_FREE; xdr_replymsg(xdrs, &reply_msg); xdrs->x_op = op; if (ct->ct_error.re_status == RPC_SUCCESS) continue; return (ct->ct_error.re_status); } if (reply_msg.rm_xid == x_id) break; } /* * process header */ gssrpc__seterr_reply(&reply_msg, &(ct->ct_error)); if (ct->ct_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { ct->ct_error.re_status = RPC_AUTHERROR; ct->ct_error.re_why = AUTH_INVALIDRESP; } else if (! AUTH_UNWRAP(h->cl_auth, xdrs, xdr_results, results_ptr)) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTDECODERES; } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (refreshes-- && AUTH_REFRESH(h->cl_auth, &reply_msg)) goto call_again; } /* end of unsuccessful completion */ /* free verifier ... */ if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && (reply_msg.acpted_rply.ar_verf.oa_base != NULL)) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } return (ct->ct_error.re_status); }