Ejemplo n.º 1
0
/*
 * XDR 32-bit integers
 * same as xdr_u_int32_t - open coded to save a proc call!
 */
bool_t
xdr_int32_t(XDR *xdrs, int32_t *int32_p)
{
	long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		l = (long) *int32_p;
		return (XDR_PUTLONG(xdrs, &l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, &l)) {
			return (FALSE);
		}
		*int32_p = (int32_t) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Ejemplo n.º 2
0
/*
 * XDR unsigned short integers
 */
bool_t
xdr_u_short(register XDR *xdrs, u_short *usp)
{
        long l;

        switch (xdrs->x_op) {

        case XDR_ENCODE:
                l = (long) *usp;
                return (XDR_PUTLONG(xdrs, &l));

        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
                *usp = (u_short) l;
                return (TRUE);

        case XDR_FREE:
                return (TRUE);
        }
        return (FALSE);
}
Ejemplo n.º 3
0
/*
 * XDR unsigned integers
 */
bool_t
xdr_u_int(XDR *xdrs, u_int *up)
{
	u_long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		l = (u_long) *up;
		return (XDR_PUTLONG(xdrs, (long *)&l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, (long *)&l)) {
			return (FALSE);
		}
		*up = (u_int) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Ejemplo n.º 4
0
/*
 * XDR short integers
 */
bool_t
xdr_short(XDR *xdrs, short int *sp)
{
	long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		l = (long) *sp;
		return (XDR_PUTLONG(xdrs, &l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, &l)) {
			return (FALSE);
		}
		*sp = (short) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Ejemplo n.º 5
0
/*
 * XDR booleans
 */
bool_t
xdr_bool(XDR *xdrs, int32_t *bp)
{
	long lb;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		lb = *bp ? XDR_TRUE : XDR_FALSE;
		return (XDR_PUTLONG(xdrs, &lb));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, &lb)) {
			return (FALSE);
		}
		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Ejemplo n.º 6
0
Archivo: xdr.c Proyecto: Pieter-was/osv
/*
 * XDR integers
 */
bool_t
xdr_int(XDR *xdrs, int *ip)
{
	long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		l = (long) *ip;
		return (XDR_PUTLONG(xdrs, &l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, &l)) {
			return (FALSE);
		}
		*ip = (int) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	/* NOTREACHED */
	return (FALSE);
}
Ejemplo n.º 7
0
Archivo: xdr.c Proyecto: Pieter-was/osv
/*
 * XDR unsigned 16-bit integers
 */
bool_t
xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p)
{
	u_long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		l = (u_long) *uint16_p;
		return (XDR_PUTLONG(xdrs, (long *)&l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, (long *)&l)) {
			return (FALSE);
		}
		*uint16_p = (uint16_t) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	/* NOTREACHED */
	return (FALSE);
}
Ejemplo n.º 8
0
Archivo: xdr.c Proyecto: PADL/krb5
/*
 * XDR unsigned short integers
 */
bool_t
xdr_u_short(XDR *xdrs, u_short *usp)
{
	u_long l;

	switch (xdrs->x_op) {

	case XDR_ENCODE:
		VALGRIND_CHECK_DEFINED(*usp);
		l = (u_long) *usp;
		return (XDR_PUTLONG(xdrs, (long *) &l));

	case XDR_DECODE:
		if (!XDR_GETLONG(xdrs, (long *) &l)) {
			return (FALSE);
		}
		*usp = (u_short) l;
		return (TRUE);

	case XDR_FREE:
		return (TRUE);
	}
	return (FALSE);
}
Ejemplo n.º 9
0
/*
 * XDR unsigned long integers
 * same as xdr_long - open coded to save a proc call!
 */
bool_t xdr_u_long(XDR* xdrs, unsigned long* ulp)
{

  if (xdrs->x_op == XDR_DECODE) {
	long l;
	if (XDR_GETLONG(xdrs, &l) == FALSE)
	  return FALSE;
	*ulp = (uint32_t) l;
	return TRUE;
  }

  if (xdrs->x_op == XDR_ENCODE) {
	if (sizeof(uint32_t) != sizeof(unsigned long)
		&& (uint32_t) *ulp != *ulp)
	  return FALSE;

		return (XDR_PUTLONG(xdrs, (long *) ulp));
  }

	if (xdrs->x_op == XDR_FREE)
		return (TRUE);

	return (FALSE);
}
Ejemplo n.º 10
0
/*
 * XDR unsigned short integers
 */
bool
xdr_u_short(XDR *xdrs, u_short *usp)
{
    u_long l;

    switch (xdrs->x_op) {

    case XDR_ENCODE:
        l = (u_long) *usp;
        return (XDR_PUTLONG(xdrs, (long *)&l));

    case XDR_DECODE:
        if (!XDR_GETLONG(xdrs, (long *)&l)) {
            return (FALSE);
        }
        *usp = (u_short) l;
        return (TRUE);

    case XDR_FREE:
        return (TRUE);
    }
    /* NOTREACHED */
    return (FALSE);
}
Ejemplo n.º 11
0
enum clnt_stat qrpc_clnt_raw_call(CLIENT *cl, u_long proc, xdrproc_t xargs, caddr_t argsp,
					xdrproc_t xresults, caddr_t resultsp,
					struct timeval utimeout)
{
	struct qrpc_clnt_raw_priv *priv = (struct qrpc_clnt_raw_priv *)cl->cl_private;
	XDR *xdrs_out = &priv->xdrs_out;
	XDR *xdrs_in = &priv->xdrs_in;
	struct rpc_msg reply_msg;
	struct timeval curr_time;
	struct qrpc_frame_hdr *hdr;
	uint16_t tmp;

	if (xargs) {
		xdrs_out->x_op = XDR_ENCODE;
		XDR_SETPOS(xdrs_out, priv->xdrs_outpos);

		if ((!XDR_PUTLONG(xdrs_out, (long *)&proc)) ||
				(!AUTH_MARSHALL(cl->cl_auth, xdrs_out)) ||
				(!(*xargs) (xdrs_out, argsp))) {
			priv->rpc_error.re_status = RPC_CANTENCODEARGS;
			return priv->rpc_error.re_status;
		}
		tmp = ntohs(priv->out_hdr.seq);
		priv->out_hdr.seq = htons(tmp + 1);
		if (qrpc_clnt_raw_call_send(priv, XDR_GETPOS(xdrs_out)) < 0) {
			return priv->rpc_error.re_status;
		}
	}

	if (gettimeofday(&curr_time, NULL) < 0) {
		priv->rpc_error.re_status = RPC_SYSTEMERROR;
		return priv->rpc_error.re_status;
	}
	utimeout.tv_sec += curr_time.tv_sec;
	/* Waiting for reply */
	do {
		if (qrpc_clnt_raw_call_recv(priv) < 0) {
			if (priv->rpc_error.re_status == RPC_TIMEDOUT)
				continue;
			else
				break;
		}

		hdr = (struct qrpc_frame_hdr *)priv->inbuf;
		if (xargs && priv->out_hdr.seq != hdr->seq) {
			continue;
		}

		xdrs_in->x_op = XDR_DECODE;
		XDR_SETPOS(xdrs_in, 0);

		reply_msg.acpted_rply.ar_verf = _null_auth;
		reply_msg.acpted_rply.ar_results.where = resultsp;
		reply_msg.acpted_rply.ar_results.proc = xresults;

		if (xdr_replymsg(xdrs_in, &reply_msg)) {
			if (reply_msg.rm_xid != (unsigned long)getpid()) {
				continue;
			}
			_seterr_reply(&reply_msg, &priv->rpc_error);
			if (priv->rpc_error.re_status == RPC_SUCCESS) {
				if (!AUTH_VALIDATE(cl->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
					priv->rpc_error.re_status = RPC_AUTHERROR;
					priv->rpc_error.re_why = AUTH_INVALIDRESP;
				}
				break;
			}
		} else {
			priv->rpc_error.re_status = RPC_CANTDECODERES;
		}
	} while ((gettimeofday(&curr_time, NULL) == 0) && (curr_time.tv_sec < utimeout.tv_sec));

	return priv->rpc_error.re_status;
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
static enum clnt_stat clntudp_call(CLIENT *cl, unsigned long proc, 
	xdrproc_t xargs, char* argsp, 
	xdrproc_t xresults, char* resultsp, 
	struct timeval utimeout)
{
	register struct cu_data *cu = (struct cu_data *) cl->cl_private;
	register XDR *xdrs;
	register int outlen;
	register int inlen;
	socklen_t fromlen;

	struct sockaddr_in from;
	struct rpc_msg reply_msg;
	XDR reply_xdrs;
	bool_t ok;
	int nrefreshes = 2;			/* number of times to refresh cred */

call_again:
	xdrs = &(cu->cu_outxdrs);
	xdrs->x_op = XDR_ENCODE;
	XDR_SETPOS(xdrs, cu->cu_xdrpos);

	/*
	 * the transaction is the first thing in the out buffer
	 */
	(*(unsigned long *) (cu->cu_outbuf))++;

	if ((!XDR_PUTLONG(xdrs, (long *) &proc)) ||
			(!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
	outlen = (int) XDR_GETPOS(xdrs);

send_again:
	if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
			   (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
			!= outlen)
	{
		cu->cu_error.re_errno = errno;
		return (cu->cu_error.re_status = RPC_CANTSEND);
	}

	/*
	 * sub-optimal code appears here because we have
	 * some clock time to spare while the packets are in flight.
	 * (We assume that this is actually only executed once.)
	 */
	reply_msg.acpted_rply.ar_verf = _null_auth;
	reply_msg.acpted_rply.ar_results.where = resultsp;
	reply_msg.acpted_rply.ar_results.proc = xresults;

	/* do recv */
	do
	{
		fromlen = sizeof(struct sockaddr);

		inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
						 (int) cu->cu_recvsz, 0,
						 (struct sockaddr *) &from, &fromlen);
	}while (inlen < 0 && errno == EINTR);

	if (inlen < 4)
	{
		rt_kprintf("recv error, len %d\n", inlen);
		cu->cu_error.re_errno = errno;
		return (cu->cu_error.re_status = RPC_CANTRECV);
	}

	/* see if reply transaction id matches sent id */
	if (*((uint32_t *) (cu->cu_inbuf)) != *((uint32_t *) (cu->cu_outbuf)))
		goto send_again;

	/* we now assume we have the proper reply */

	/*
	 * now decode and validate the response
	 */
	xdrmem_create(&reply_xdrs, cu->cu_inbuf, (unsigned int) inlen, XDR_DECODE);
	ok = xdr_replymsg(&reply_xdrs, &reply_msg);
	/* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
	if (ok)
	{
		_seterr_reply(&reply_msg, &(cu->cu_error));
		if (cu->cu_error.re_status == RPC_SUCCESS)
		{
			if (!AUTH_VALIDATE(cl->cl_auth,
							   &reply_msg.acpted_rply.ar_verf))
			{
				cu->cu_error.re_status = RPC_AUTHERROR;
				cu->cu_error.re_why = AUTH_INVALIDRESP;
			}
			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 (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth))
			{
				nrefreshes--;
				goto call_again;
			}
		} /* end of unsuccessful completion */
	} /* end of valid reply message */
	else
	{
		cu->cu_error.re_status = RPC_CANTDECODERES;
	}

	return (cu->cu_error.re_status);
}
static enum clnt_stat
clntudp_call (
     CLIENT *cl,	/* client handle */
     u_long proc,		/* procedure number */
     xdrproc_t xargs,		/* xdr routine for args */
     caddr_t argsp,		/* pointer to args */
     xdrproc_t xresults,	/* xdr routine for results */
     caddr_t resultsp,		/* pointer to results */
     struct timeval utimeout	/* seconds to wait before giving up */)
{
  struct cu_data *cu = (struct cu_data *) cl->cl_private;
  XDR *xdrs;
  int outlen = 0;
  int inlen;
  socklen_t fromlen;
  struct pollfd fd;
  int milliseconds = (cu->cu_wait.tv_sec * 1000) +
    (cu->cu_wait.tv_usec / 1000);
  struct sockaddr_in from;
  struct rpc_msg reply_msg;
  XDR reply_xdrs;
  struct timeval time_waited;
  bool_t ok;
  int nrefreshes = 2;		/* number of times to refresh cred */
  struct timeval timeout;
  int anyup;			/* any network interface up */

  if (cu->cu_total.tv_usec == -1)
    {
      timeout = utimeout;	/* use supplied timeout */
    }
  else
    {
      timeout = cu->cu_total;	/* use default timeout */
    }

  time_waited.tv_sec = 0;
  time_waited.tv_usec = 0;
call_again:
  xdrs = &(cu->cu_outxdrs);
  if (xargs == NULL)
    goto get_reply;
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, cu->cu_xdrpos);
  /*
   * the transaction is the first thing in the out buffer
   */
  (*(uint32_t *) (cu->cu_outbuf))++;
  if ((!XDR_PUTLONG (xdrs, (long *) &proc)) ||
      (!AUTH_MARSHALL (cl->cl_auth, xdrs)) ||
      (!(*xargs) (xdrs, argsp)))
    return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  outlen = (int) XDR_GETPOS (xdrs);

send_again:
  if (sendto (cu->cu_sock, cu->cu_outbuf, outlen, 0,
	      (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
      != outlen)
    {
      cu->cu_error.re_errno = errno;
      return (cu->cu_error.re_status = RPC_CANTSEND);
    }

  /*
   * Hack to provide rpc-based message passing
   */
  if (timeout.tv_sec == 0 && timeout.tv_usec == 0)
    {
      return (cu->cu_error.re_status = RPC_TIMEDOUT);
    }
 get_reply:
  /*
   * sub-optimal code appears here because we have
   * some clock time to spare while the packets are in flight.
   * (We assume that this is actually only executed once.)
   */
  reply_msg.acpted_rply.ar_verf = _null_auth;
  reply_msg.acpted_rply.ar_results.where = resultsp;
  reply_msg.acpted_rply.ar_results.proc = xresults;
  fd.fd = cu->cu_sock;
  fd.events = POLLIN;
  anyup = 0;
  for (;;)
    {
      switch (poll (&fd, 1, milliseconds))
	{

	case 0:
	  if (anyup == 0)
	    {
	      anyup = is_network_up (cu->cu_sock);
	      if (!anyup)
		return (cu->cu_error.re_status = RPC_CANTRECV);
	    }

	  time_waited.tv_sec += cu->cu_wait.tv_sec;
	  time_waited.tv_usec += cu->cu_wait.tv_usec;
	  while (time_waited.tv_usec >= 1000000)
	    {
	      time_waited.tv_sec++;
	      time_waited.tv_usec -= 1000000;
	    }
	  if ((time_waited.tv_sec < timeout.tv_sec) ||
	      ((time_waited.tv_sec == timeout.tv_sec) &&
	       (time_waited.tv_usec < timeout.tv_usec)))
	    goto send_again;
	  return (cu->cu_error.re_status = RPC_TIMEDOUT);

	  /*
	   * buggy in other cases because time_waited is not being
	   * updated.
	   */
	case -1:
	  if (errno == EINTR)
	    continue;
	  cu->cu_error.re_errno = errno;
	  return (cu->cu_error.re_status = RPC_CANTRECV);
	}
#ifdef IP_RECVERR
      if (fd.revents & POLLERR)
	{
	  struct msghdr msg;
	  struct cmsghdr *cmsg;
	  struct sock_extended_err *e;
	  struct sockaddr_in err_addr;
	  struct iovec iov;
	  char *cbuf = (char *) alloca (outlen + 256);
	  int ret;

	  iov.iov_base = cbuf + 256;
	  iov.iov_len = outlen;
	  msg.msg_name = (void *) &err_addr;
	  msg.msg_namelen = sizeof (err_addr);
	  msg.msg_iov = &iov;
	  msg.msg_iovlen = 1;
	  msg.msg_flags = 0;
	  msg.msg_control = cbuf;
	  msg.msg_controllen = 256;
	  ret = recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE);
	  if (ret >= 0
	      && memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0
	      && (msg.msg_flags & MSG_ERRQUEUE)
	      && ((msg.msg_namelen == 0
		   && ret >= 12)
		  || (msg.msg_namelen == sizeof (err_addr)
		      && err_addr.sin_family == AF_INET
		      && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr,
				 sizeof (err_addr.sin_addr)) == 0
		      && err_addr.sin_port == cu->cu_raddr.sin_port)))
	    for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;
		 cmsg = CMSG_NXTHDR (&msg, cmsg))
	      if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
		{
		  e = (struct sock_extended_err *) CMSG_DATA(cmsg);
		  cu->cu_error.re_errno = e->ee_errno;
		  return (cu->cu_error.re_status = RPC_CANTRECV);
		}
	}
#endif
      do
	{
	  fromlen = sizeof (struct sockaddr);
	  inlen = recvfrom (cu->cu_sock, cu->cu_inbuf,
			    (int) cu->cu_recvsz, 0,
			    (struct sockaddr *) &from, &fromlen);
	}
      while (inlen < 0 && errno == EINTR);
      if (inlen < 0)
	{
	  if (errno == EWOULDBLOCK)
	    continue;
	  cu->cu_error.re_errno = errno;
	  return (cu->cu_error.re_status = RPC_CANTRECV);
	}
      if (inlen < 4)
	continue;

      /* see if reply transaction id matches sent id.
        Don't do this if we only wait for a replay */
      if (xargs != NULL
	  && (*((u_int32_t *) (cu->cu_inbuf))
	      != *((u_int32_t *) (cu->cu_outbuf))))
	continue;
      /* we now assume we have the proper reply */
      break;
    }

  /*
   * now decode and validate the response
   */
  xdrmem_create (&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE);
  ok = xdr_replymsg (&reply_xdrs, &reply_msg);
  /* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
  if (ok)
    {
      _seterr_reply (&reply_msg, &(cu->cu_error));
      if (cu->cu_error.re_status == RPC_SUCCESS)
	{
	  if (!AUTH_VALIDATE (cl->cl_auth,
			      &reply_msg.acpted_rply.ar_verf))
	    {
	      cu->cu_error.re_status = RPC_AUTHERROR;
	      cu->cu_error.re_why = AUTH_INVALIDRESP;
	    }
	  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 (nrefreshes > 0 && AUTH_REFRESH (cl->cl_auth))
	    {
	      nrefreshes--;
	      goto call_again;
	    }
	}			/* end of unsuccessful completion */
    }				/* end of valid reply message */
  else
    {
      cu->cu_error.re_status = RPC_CANTDECODERES;
    }
  return cu->cu_error.re_status;
}
Ejemplo n.º 15
0
static enum clnt_stat
clntraw_call (CLIENT *h, u_long proc, xdrproc_t xargs, caddr_t argsp,
	      xdrproc_t xresults, caddr_t resultsp, struct timeval timeout)
{
  struct clntraw_private_s *clp = clntraw_private;
  XDR *xdrs = &clp->xdr_stream;
  struct rpc_msg msg;
  enum clnt_stat status;
  struct rpc_err error;

  if (clp == NULL)
    return RPC_FAILED;
call_again:
  /*
   * send request
   */
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, 0);
  /* Just checking the union definition to access rm_xid is correct.  */
  if (offsetof (struct rpc_msg, rm_xid) != 0)
    abort ();
  clp->mashl_callmsg.rm_xid++;
  if ((!XDR_PUTBYTES (xdrs, clp->mashl_callmsg.msg, clp->mcnt)) ||
      (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
      (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
      (!(*xargs) (xdrs, argsp)))
    {
      return (RPC_CANTENCODEARGS);
    }
  (void) XDR_GETPOS (xdrs);	/* called just to cause overhead */

  /*
   * We have to call server input routine here because this is
   * all going on in one process. Yuk.
   */
  svc_getreq (1);

  /*
   * get results
   */
  xdrs->x_op = XDR_DECODE;
  XDR_SETPOS (xdrs, 0);
  msg.acpted_rply.ar_verf = _null_auth;
  msg.acpted_rply.ar_results.where = resultsp;
  msg.acpted_rply.ar_results.proc = xresults;
  if (!xdr_replymsg (xdrs, &msg))
    return RPC_CANTDECODERES;
  _seterr_reply (&msg, &error);
  status = error.re_status;

  if (status == RPC_SUCCESS)
    {
      if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
	{
	  status = RPC_AUTHERROR;
	}
    }				/* end successful completion */
  else
    {
      if (AUTH_REFRESH (h->cl_auth))
	goto call_again;
    }				/* end of unsuccessful completion */

  if (status == RPC_SUCCESS)
    {
      if (!AUTH_VALIDATE (h->cl_auth, &msg.acpted_rply.ar_verf))
	{
	  status = RPC_AUTHERROR;
	}
      if (msg.acpted_rply.ar_verf.oa_base != NULL)
	{
	  xdrs->x_op = XDR_FREE;
	  (void) xdr_opaque_auth (xdrs, &(msg.acpted_rply.ar_verf));
	}
    }

  return status;
}
Ejemplo n.º 16
0
Archivo: clnt_tcp.c Proyecto: PADL/krb5
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);
}