summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc/clnt_vc.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-08-06 14:02:05 +0000
committerdfr <dfr@FreeBSD.org>2008-08-06 14:02:05 +0000
commitea3d7030c0c6118b636ea8909a5583b94d819e3a (patch)
treea928d209076dec713f636439ec8dc5be13863460 /lib/libc/rpc/clnt_vc.c
parent627a3ab3ef939e027409fe287f7e3c401c373003 (diff)
downloadFreeBSD-src-ea3d7030c0c6118b636ea8909a5583b94d819e3a.zip
FreeBSD-src-ea3d7030c0c6118b636ea8909a5583b94d819e3a.tar.gz
Add an implementation of the RPCSEC_GSS authentication protocol for RPC. This
is based on an old implementation from the University of Michigan with lots of changes and fixes by me and the addition of a Solaris-compatible API. Sponsored by: Isilon Systems Reviewed by: alfred
Diffstat (limited to 'lib/libc/rpc/clnt_vc.c')
-rw-r--r--lib/libc/rpc/clnt_vc.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c
index 414eb0b..07eff46 100644
--- a/lib/libc/rpc/clnt_vc.c
+++ b/lib/libc/rpc/clnt_vc.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <signal.h>
#include <rpc/rpc.h>
+#include <rpc/rpcsec_gss.h>
#include "un-namespace.h"
#include "rpc_com.h"
#include "mt_misc.h"
@@ -285,6 +286,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
+ assert(ct->ct_mpos + sizeof(uint32_t) <= MCALL_MSG_SIZE);
/*
* Create a client handle which uses xdrrec for serialization
@@ -331,6 +333,7 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
int refreshes = 2;
sigset_t mask, newmask;
int rpc_lock_value;
+ bool_t reply_stat;
assert(cl != NULL);
@@ -360,15 +363,28 @@ call_again:
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, &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);
+ 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);
@@ -419,9 +435,18 @@ call_again:
&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;
+ } 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) {
OpenPOWER on IntegriCloud