summaryrefslogtreecommitdiffstats
path: root/lib/libc/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/rpc')
-rw-r--r--lib/libc/rpc/Makefile.inc5
-rw-r--r--lib/libc/rpc/Symbol.map4
-rw-r--r--lib/libc/rpc/clnt_dg.c112
-rw-r--r--lib/libc/rpc/clnt_perror.c9
-rw-r--r--lib/libc/rpc/clnt_vc.c49
-rw-r--r--lib/libc/rpc/rpcsec_gss_stub.c48
-rw-r--r--lib/libc/rpc/svc.c58
-rw-r--r--lib/libc/rpc/svc_auth.c24
-rw-r--r--lib/libc/rpc/svc_dg.c34
-rw-r--r--lib/libc/rpc/svc_raw.c38
-rw-r--r--lib/libc/rpc/svc_vc.c45
11 files changed, 347 insertions, 79 deletions
diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc
index dceecc7..db0b8ad 100644
--- a/lib/libc/rpc/Makefile.inc
+++ b/lib/libc/rpc/Makefile.inc
@@ -8,8 +8,9 @@ SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
- rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \
- svc_raw.c svc_run.c svc_simple.c svc_vc.c
+ rpcb_st_xdr.c rpcsec_gss_stub.c svc.c svc_auth.c svc_dg.c \
+ svc_auth_unix.c svc_generic.c svc_raw.c svc_run.c svc_simple.c \
+ svc_vc.c
# Secure-RPC
SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \
diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map
index e3ac6a6..ccf0bfa 100644
--- a/lib/libc/rpc/Symbol.map
+++ b/lib/libc/rpc/Symbol.map
@@ -244,4 +244,8 @@ FBSDprivate_1.0 {
* Remove this hack if rpcinfo stops building with it.
*/
__svc_clean_idle;
+ __rpc_gss_unwrap;
+ __rpc_gss_unwrap_stub;
+ __rpc_gss_wrap;
+ __rpc_gss_wrap_stub;
};
diff --git a/lib/libc/rpc/clnt_dg.c b/lib/libc/rpc/clnt_dg.c
index 27296ab..3014155 100644
--- a/lib/libc/rpc/clnt_dg.c
+++ b/lib/libc/rpc/clnt_dg.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
+#include <rpc/rpcsec_gss.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -113,6 +114,8 @@ static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory";
/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
+#define MCALL_MSG_SIZE 24
+
/*
* Private data kept per client handle
*/
@@ -127,6 +130,7 @@ struct cu_data {
XDR cu_outxdrs;
u_int cu_xdrpos;
u_int cu_sendsz; /* send size */
+ char cu_outhdr[MCALL_MSG_SIZE];
char *cu_outbuf;
u_int cu_recvsz; /* recv size */
int cu_async;
@@ -253,13 +257,16 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz)
call_msg.rm_xid = __RPC_GETXID(&now);
call_msg.rm_call.cb_prog = program;
call_msg.rm_call.cb_vers = version;
- xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
- if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+ xdrmem_create(&(cu->cu_outxdrs), cu->cu_outhdr, MCALL_MSG_SIZE,
+ XDR_ENCODE);
+ if (! xdr_callhdr(&cu->cu_outxdrs, &call_msg)) {
rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */
rpc_createerr.cf_error.re_errno = 0;
goto err2;
}
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+ XDR_DESTROY(&cu->cu_outxdrs);
+ xdrmem_create(&cu->cu_outxdrs, cu->cu_outbuf, sendsz, XDR_ENCODE);
/* XXX fvdl - do we still want this? */
#if 0
@@ -312,6 +319,7 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
XDR reply_xdrs;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
+ int nretries = 0; /* number of times we retransmitted */
struct timeval timeout;
struct timeval retransmit_time;
struct timeval next_sendtime, starttime, time_waited, tv;
@@ -375,25 +383,37 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
kin_len = 1;
call_again:
- xdrs = &(cu->cu_outxdrs);
- if (cu->cu_async == TRUE && 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
* XXX Yes, and it's in network byte order, so we should to
* be careful when we increment it, shouldn't we.
*/
- xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf));
+ xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr));
xid++;
- *(u_int32_t *)(void *)(cu->cu_outbuf) = htonl(xid);
-
- if ((! XDR_PUTINT32(xdrs, &proc)) ||
- (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
- (! (*xargs)(xdrs, argsp))) {
- cu->cu_error.re_status = RPC_CANTENCODEARGS;
- goto out;
+ *(u_int32_t *)(void *)(cu->cu_outhdr) = htonl(xid);
+call_again_same_xid:
+ xdrs = &(cu->cu_outxdrs);
+ if (cu->cu_async == TRUE && xargs == NULL)
+ goto get_reply;
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+
+ if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+ if ((! XDR_PUTBYTES(xdrs, cu->cu_outhdr, cu->cu_xdrpos)) ||
+ (! XDR_PUTINT32(xdrs, &proc)) ||
+ (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ cu->cu_error.re_status = RPC_CANTENCODEARGS;
+ goto out;
+ }
+ } else {
+ *(uint32_t *) &cu->cu_outhdr[cu->cu_xdrpos] = htonl(proc);
+ if (!__rpc_gss_wrap(cl->cl_auth, cu->cu_outhdr,
+ cu->cu_xdrpos + sizeof(uint32_t),
+ xdrs, xargs, argsp)) {
+ cu->cu_error.re_status = RPC_CANTENCODEARGS;
+ goto out;
+ }
}
outlen = (size_t)XDR_GETPOS(xdrs);
@@ -420,8 +440,13 @@ get_reply:
* (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;
+ if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
+ reply_msg.acpted_rply.ar_results.where = resultsp;
+ reply_msg.acpted_rply.ar_results.proc = xresults;
+ } else {
+ reply_msg.acpted_rply.ar_results.where = NULL;
+ reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+ }
for (;;) {
/* Decide how long to wait. */
@@ -483,7 +508,17 @@ get_reply:
&retransmit_time);
timeradd(&next_sendtime, &retransmit_time,
&next_sendtime);
- goto send_again;
+ nretries++;
+
+ /*
+ * When retransmitting a RPCSEC_GSS message,
+ * we must use a new sequence number (handled
+ * by __rpc_gss_wrap above).
+ */
+ if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS)
+ goto send_again;
+ else
+ goto call_again_same_xid;
}
}
inlen = (socklen_t)recvlen;
@@ -505,8 +540,37 @@ get_reply:
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
+ if (nretries &&
+ cl->cl_auth->ah_cred.oa_flavor
+ == RPCSEC_GSS)
+ /*
+ * If we retransmitted, its
+ * possible that we will
+ * receive a reply for one of
+ * the earlier transmissions
+ * (which will use an older
+ * RPCSEC_GSS sequence
+ * number). In this case, just
+ * go back and listen for a
+ * new reply. We could keep a
+ * record of all the seq
+ * numbers we have transmitted
+ * so far so that we could
+ * accept a reply for any of
+ * them here.
+ */
+ goto get_reply;
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
+ } else {
+ if (cl->cl_auth->ah_cred.oa_flavor
+ == RPCSEC_GSS) {
+ if (!__rpc_gss_unwrap(cl->cl_auth,
+ &reply_xdrs, xresults,
+ resultsp))
+ cu->cu_error.re_status =
+ RPC_CANTDECODERES;
+ }
}
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
@@ -670,12 +734,12 @@ clnt_dg_control(cl, request, info)
* This will get the xid of the PREVIOUS call
*/
*(u_int32_t *)info =
- ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
+ ntohl(*(u_int32_t *)(void *)cu->cu_outhdr);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
- *(u_int32_t *)(void *)cu->cu_outbuf =
+ *(u_int32_t *)(void *)cu->cu_outhdr =
htonl(*(u_int32_t *)info - 1);
/* decrement by 1 as clnt_dg_call() increments once */
break;
@@ -688,12 +752,12 @@ clnt_dg_control(cl, request, info)
* call_struct is changed
*/
*(u_int32_t *)info =
- ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
+ ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
- *(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
+ *(u_int32_t *)(void *)(cu->cu_outhdr + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)info);
break;
@@ -705,12 +769,12 @@ clnt_dg_control(cl, request, info)
* call_struct is changed
*/
*(u_int32_t *)info =
- ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
+ ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
- *(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
+ *(u_int32_t *)(void *)(cu->cu_outhdr + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)info);
break;
case CLSET_ASYNC:
diff --git a/lib/libc/rpc/clnt_perror.c b/lib/libc/rpc/clnt_perror.c
index 4b6d6b1..efe9043 100644
--- a/lib/libc/rpc/clnt_perror.c
+++ b/lib/libc/rpc/clnt_perror.c
@@ -309,7 +309,14 @@ static const char *const auth_errlist[] = {
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
- "Failed (unspecified error)" /* 7 - AUTH_FAILED */
+ "Failed (unspecified error)", /* 7 - AUTH_FAILED */
+ "Kerberos generic error", /* 8 - AUTH_KERB_GENERIC*/
+ "Kerberos credential expired", /* 9 - AUTH_TIMEEXPIRE */
+ "Bad kerberos ticket file", /* 10 - AUTH_TKT_FILE */
+ "Can't decode kerberos authenticator", /* 11 - AUTH_DECODE */
+ "Address wrong in kerberos ticket", /* 12 - AUTH_NET_ADDR */
+ "GSS-API crediential problem", /* 13 - RPCSEC_GSS_CREDPROBLEM */
+ "GSS-API context problem" /* 14 - RPCSEC_GSS_CTXPROBLEM */
};
static char *
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) {
diff --git a/lib/libc/rpc/rpcsec_gss_stub.c b/lib/libc/rpc/rpcsec_gss_stub.c
new file mode 100644
index 0000000..55eb106
--- /dev/null
+++ b/lib/libc/rpc/rpcsec_gss_stub.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2006 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/rpcsec_gss.h>
+
+bool_t
+__rpc_gss_wrap_stub(AUTH *auth, void *header, size_t headerlen, XDR* xdrs,
+ xdrproc_t xdr_args, void *args_ptr)
+{
+
+ return (FALSE);
+}
+
+bool_t
+__rpc_gss_unwrap_stub(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args, void *args_ptr)
+{
+
+ return (FALSE);
+}
+
+__weak_reference(__rpc_gss_wrap_stub, __rpc_gss_wrap);
+__weak_reference(__rpc_gss_unwrap_stub, __rpc_gss_unwrap);
diff --git a/lib/libc/rpc/svc.c b/lib/libc/rpc/svc.c
index b924bde..f5654b1 100644
--- a/lib/libc/rpc/svc.c
+++ b/lib/libc/rpc/svc.c
@@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#define RQCRED_SIZE 400 /* this size is excessive */
#define SVC_VERSQUIET 0x0001 /* keep quiet about vers mismatch */
-#define version_keepquiet(xp) ((u_long)(xp)->xp_p3 & SVC_VERSQUIET)
+#define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET)
#define max(a, b) (a > b ? a : b)
@@ -452,20 +452,16 @@ void
__svc_versquiet_on(xprt)
SVCXPRT *xprt;
{
- u_long tmp;
- tmp = ((u_long) xprt->xp_p3) | SVC_VERSQUIET;
- xprt->xp_p3 = tmp;
+ SVC_EXT(xprt)->xp_flags |= SVC_VERSQUIET;
}
void
__svc_versquiet_off(xprt)
SVCXPRT *xprt;
{
- u_long tmp;
- tmp = ((u_long) xprt->xp_p3) & ~SVC_VERSQUIET;
- xprt->xp_p3 = tmp;
+ SVC_EXT(xprt)->xp_flags &= ~SVC_VERSQUIET;
}
void
@@ -479,7 +475,8 @@ int
__svc_versquiet_get(xprt)
SVCXPRT *xprt;
{
- return ((int) xprt->xp_p3) & SVC_VERSQUIET;
+
+ return (SVC_EXT(xprt)->xp_flags & SVC_VERSQUIET);
}
#endif
@@ -555,6 +552,39 @@ svcerr_progvers(xprt, low_vers, high_vers)
SVC_REPLY(xprt, &rply);
}
+/*
+ * Allocate a new server transport structure. All fields are
+ * initialized to zero and xp_p3 is initialized to point at an
+ * extension structure to hold various flags and authentication
+ * parameters.
+ */
+SVCXPRT *
+svc_xprt_alloc()
+{
+ SVCXPRT *xprt;
+ SVCXPRT_EXT *ext;
+
+ xprt = mem_alloc(sizeof(SVCXPRT));
+ memset(xprt, 0, sizeof(SVCXPRT));
+ ext = mem_alloc(sizeof(SVCXPRT_EXT));
+ memset(ext, 0, sizeof(SVCXPRT_EXT));
+ xprt->xp_p3 = ext;
+
+ return (xprt);
+}
+
+/*
+ * Free a server transport structure.
+ */
+void
+svc_xprt_free(xprt)
+ SVCXPRT *xprt;
+{
+
+ mem_free(xprt->xp_p3, sizeof(SVCXPRT_EXT));
+ mem_free(xprt, sizeof(SVCXPRT));
+}
+
/* ******************* SERVER INPUT STUFF ******************* */
/*
@@ -643,7 +673,15 @@ svc_getreq_common(fd)
r.rq_cred = msg.rm_call.cb_cred;
/* first authenticate the message */
if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
- svcerr_auth(xprt, why);
+ /*
+ * RPCSEC_GSS uses this return code
+ * for requests that form part of its
+ * context establishment protocol and
+ * should not be dispatched to the
+ * application.
+ */
+ if (why != RPCSEC_GSS_NODISPATCH)
+ svcerr_auth(xprt, why);
goto call_done;
}
/* now match message with a registered service*/
@@ -670,7 +708,7 @@ svc_getreq_common(fd)
if (prog_found)
svcerr_progvers(xprt, low_vers, high_vers);
else
- svcerr_noprog(xprt);
+ svcerr_noprog(xprt);
/* Fall through to ... */
}
/*
diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c
index eb1a5f2..4e27ccd 100644
--- a/lib/libc/rpc/svc_auth.c
+++ b/lib/libc/rpc/svc_auth.c
@@ -75,6 +75,8 @@ struct authsvc {
};
static struct authsvc *Auths = NULL;
+static struct svc_auth_ops svc_auth_null_ops;
+
/*
* The call rpc message, msg has been obtained from the wire. The msg contains
* the raw form of credentials and verifiers. authenticate returns AUTH_OK
@@ -105,6 +107,8 @@ _authenticate(rqst, msg)
/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
rqst->rq_cred = msg->rm_call.cb_cred;
+ SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops;
+ SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL;
rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
rqst->rq_xprt->xp_verf.oa_length = 0;
cred_flavor = rqst->rq_cred.oa_flavor;
@@ -143,6 +147,26 @@ _authenticate(rqst, msg)
return (AUTH_REJECTEDCRED);
}
+/*
+ * A set of null auth methods used by any authentication protocols
+ * that don't need to inspect or modify the message body.
+ */
+static bool_t
+svcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr)
+ SVCAUTH *auth;
+ XDR *xdrs;
+ xdrproc_t xdr_func;
+ caddr_t xdr_ptr;
+{
+
+ return (xdr_func(xdrs, xdr_ptr));
+}
+
+static struct svc_auth_ops svc_auth_null_ops = {
+ svcauth_null_wrap,
+ svcauth_null_wrap,
+};
+
/*ARGSUSED*/
enum auth_stat
_svcauth_null(rqst, msg)
diff --git a/lib/libc/rpc/svc_dg.c b/lib/libc/rpc/svc_dg.c
index 1c602bc..51facd2 100644
--- a/lib/libc/rpc/svc_dg.c
+++ b/lib/libc/rpc/svc_dg.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <rpc/svc_dg.h>
+#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@@ -125,10 +126,9 @@ svc_dg_create(fd, sendsize, recvsize)
return (NULL);
}
- xprt = mem_alloc(sizeof (SVCXPRT));
+ xprt = svc_xprt_alloc();
if (xprt == NULL)
goto freedata;
- memset(xprt, 0, sizeof (SVCXPRT));
su = mem_alloc(sizeof (*su));
if (su == NULL)
@@ -160,7 +160,7 @@ freedata:
if (xprt) {
if (su)
(void) mem_free(su, sizeof (*su));
- (void) mem_free(xprt, sizeof (SVCXPRT));
+ svc_xprt_free(xprt);
}
return (NULL);
}
@@ -230,13 +230,28 @@ svc_dg_reply(xprt, msg)
{
struct svc_dg_data *su = su_data(xprt);
XDR *xdrs = &(su->su_xdrs);
- bool_t stat = FALSE;
+ bool_t stat = TRUE;
size_t slen;
+ xdrproc_t xdr_proc;
+ caddr_t xdr_where;
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
msg->rm_xid = su->su_xid;
- if (xdr_replymsg(xdrs, msg)) {
+ 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(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
+ stat = FALSE;
+ } else {
+ stat = xdr_replymsg(xdrs, msg);
+ }
+ if (stat) {
slen = XDR_GETPOS(xdrs);
if (_sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0,
(struct sockaddr *)xprt->xp_rtaddr.buf,
@@ -255,7 +270,12 @@ svc_dg_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args;
void *args_ptr;
{
- return (*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr);
+ struct svc_dg_data *su;
+
+ assert(xprt != NULL);
+ su = su_data(xprt);
+ return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
+ &su->su_xdrs, xdr_args, args_ptr));
}
static bool_t
@@ -288,7 +308,7 @@ svc_dg_destroy(xprt)
(void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen);
if (xprt->xp_tp)
(void) free(xprt->xp_tp);
- (void) mem_free(xprt, sizeof (SVCXPRT));
+ svc_xprt_free(xprt);
}
static bool_t
diff --git a/lib/libc/rpc/svc_raw.c b/lib/libc/rpc/svc_raw.c
index 32d1ff7..7492046 100644
--- a/lib/libc/rpc/svc_raw.c
+++ b/lib/libc/rpc/svc_raw.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
*/
static struct svc_raw_private {
char *raw_buf; /* should be shared with the cl handle */
- SVCXPRT server;
+ SVCXPRT *server;
XDR xdr_stream;
char verf_body[MAX_AUTH_BYTES];
} *svc_raw_private;
@@ -99,17 +99,17 @@ svc_raw_create()
if (__rpc_rawcombuf == NULL)
__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
+ srp->server = svc_xprt_alloc();
svc_raw_private = srp;
}
- srp->server.xp_fd = FD_SETSIZE;
- srp->server.xp_port = 0;
- srp->server.xp_p3 = NULL;
- svc_raw_ops(&srp->server);
- srp->server.xp_verf.oa_base = srp->verf_body;
+ srp->server->xp_fd = FD_SETSIZE;
+ srp->server->xp_port = 0;
+ svc_raw_ops(srp->server);
+ srp->server->xp_verf.oa_base = srp->verf_body;
xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
- xprt_register(&srp->server);
+ xprt_register(srp->server);
mutex_unlock(&svcraw_lock);
- return (&srp->server);
+ return (srp->server);
}
/*ARGSUSED*/
@@ -154,6 +154,9 @@ svc_raw_reply(xprt, msg)
{
struct svc_raw_private *srp;
XDR *xdrs;
+ bool_t stat;
+ xdrproc_t xdr_proc;
+ caddr_t xdr_where;
mutex_lock(&svcraw_lock);
srp = svc_raw_private;
@@ -166,7 +169,20 @@ svc_raw_reply(xprt, msg)
xdrs = &srp->xdr_stream;
xdrs->x_op = XDR_ENCODE;
(void) XDR_SETPOS(xdrs, 0);
- if (! xdr_replymsg(xdrs, msg)) {
+ 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(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
+ stat = FALSE;
+ } else {
+ stat = xdr_replymsg(xdrs, msg);
+ }
+ if (!stat) {
return (FALSE);
}
(void) XDR_GETPOS(xdrs); /* called just for overhead */
@@ -189,7 +205,9 @@ svc_raw_getargs(xprt, xdr_args, args_ptr)
return (FALSE);
}
mutex_unlock(&svcraw_lock);
- return (*xdr_args)(&srp->xdr_stream, args_ptr);
+
+ return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
+ xdr_args, args_ptr));
}
/*ARGSUSED*/
diff --git a/lib/libc/rpc/svc_vc.c b/lib/libc/rpc/svc_vc.c
index 6370aad..3fd8b7e 100644
--- a/lib/libc/rpc/svc_vc.c
+++ b/lib/libc/rpc/svc_vc.c
@@ -146,15 +146,12 @@ svc_vc_create(fd, sendsize, recvsize)
r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
r->maxrec = __svc_maxrec;
- xprt = mem_alloc(sizeof(SVCXPRT));
+ xprt = svc_xprt_alloc();
if (xprt == NULL) {
warnx("svc_vc_create: out of memory");
goto cleanup_svc_vc_create;
}
- xprt->xp_tp = NULL;
xprt->xp_p1 = r;
- xprt->xp_p2 = NULL;
- xprt->xp_p3 = NULL;
xprt->xp_verf = _null_auth;
svc_vc_rendezvous_ops(xprt);
xprt->xp_port = (u_short)-1; /* It is the rendezvouser */
@@ -259,16 +256,15 @@ makefd_xprt(fd, sendsize, recvsize)
assert(fd != -1);
- xprt = mem_alloc(sizeof(SVCXPRT));
+ xprt = svc_xprt_alloc();
if (xprt == NULL) {
warnx("svc_vc: makefd_xprt: out of memory");
goto done;
}
- memset(xprt, 0, sizeof *xprt);
cd = mem_alloc(sizeof(struct cf_conn));
if (cd == NULL) {
warnx("svc_tcp: makefd_xprt: out of memory");
- mem_free(xprt, sizeof(SVCXPRT));
+ svc_xprt_free(xprt);
xprt = NULL;
goto done;
}
@@ -417,7 +413,7 @@ __svc_vc_dodestroy(xprt)
free(xprt->xp_tp);
if (xprt->xp_netid)
free(xprt->xp_netid);
- mem_free(xprt, sizeof(SVCXPRT));
+ svc_xprt_free(xprt);
}
/*ARGSUSED*/
@@ -623,11 +619,12 @@ svc_vc_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args;
void *args_ptr;
{
+ struct cf_conn *cd;
assert(xprt != NULL);
- /* args_ptr may be NULL */
- return ((*xdr_args)(&(((struct cf_conn *)(xprt->xp_p1))->xdrs),
- args_ptr));
+ cd = (struct cf_conn *)(xprt->xp_p1);
+ return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
+ &cd->xdrs, xdr_args, args_ptr));
}
static bool_t
@@ -655,6 +652,9 @@ svc_vc_reply(xprt, msg)
struct cf_conn *cd;
XDR *xdrs;
bool_t rstat;
+ xdrproc_t xdr_proc;
+ caddr_t xdr_where;
+ u_int pos;
assert(xprt != NULL);
assert(msg != NULL);
@@ -664,8 +664,27 @@ svc_vc_reply(xprt, msg)
xdrs->x_op = XDR_ENCODE;
msg->rm_xid = cd->x_id;
- rstat = xdr_replymsg(xdrs, msg);
- (void)xdrrec_endofrecord(xdrs, TRUE);
+ rstat = TRUE;
+ 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;
+
+ pos = XDR_GETPOS(xdrs);
+ if (!xdr_replymsg(xdrs, msg) ||
+ !SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) {
+ XDR_SETPOS(xdrs, pos);
+ rstat = FALSE;
+ }
+ } else {
+ rstat = xdr_replymsg(xdrs, msg);
+ }
+
+ if (rstat)
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+
return (rstat);
}
OpenPOWER on IntegriCloud