From: Chuck Lever Date: Wed, 9 Apr 2014 18:00:56 +0000 (-0400) Subject: Pre-register server side RPCSEC GSS support X-Git-Tag: libtirpc-0-2-5-rc2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03de41be57684b4a4017120ae3d3e8dba2d29b23;p=libtirpc Pre-register server side RPCSEC GSS support When --enable-gss is specified on the ./configure command line, have the library automatically register server-side support for the RPCSEC_GSS auth flavor. The complication is that specific interaction is required with the RPC client if GSS authentication fails. GSS authentication sometimes has to squelch the normal reply done by svc_getreq(), and substitute its own. _svcauth_gss() already has a boolean argument to do this. But _authenticate() is an official API (see rpc/svc_auth.h). We can't alter its synopsis. Instead of adding a "no_dispatch" argument to our existing _authenticate() API, preserve its synopsis for backwards compatibility, and introduce a second external authentication API for the dispatcher. This matches a similar API change done in the Solaris libtirpc. Signed-off-by: Chuck Lever Signed-off-by: Steve Dickson --- diff --git a/src/svc.c b/src/svc.c index 08cd6c9..8afd15d 100644 --- a/src/svc.c +++ b/src/svc.c @@ -649,6 +649,7 @@ svc_getreq_common (fd) { if (SVC_RECV (xprt, &msg)) { + bool_t no_dispatch; /* now find the exported program and call it */ struct svc_callout *s; @@ -660,11 +661,14 @@ svc_getreq_common (fd) r.rq_proc = msg.rm_call.cb_proc; r.rq_cred = msg.rm_call.cb_cred; /* first authenticate the message */ - if ((why = _authenticate (&r, &msg)) != AUTH_OK) + why = _gss_authenticate(&r, &msg, &no_dispatch); + if (why != AUTH_OK) { svcerr_auth (xprt, why); goto call_done; } + if (no_dispatch) + goto call_done; /* now match message with a registered service */ prog_found = FALSE; low_vers = (rpcvers_t) - 1L; diff --git a/src/svc_auth.c b/src/svc_auth.c index e80d5f9..31241c9 100644 --- a/src/svc_auth.c +++ b/src/svc_auth.c @@ -82,9 +82,10 @@ static struct authsvc *Auths = NULL; * invalid. */ enum auth_stat -_authenticate(rqst, msg) +_gss_authenticate(rqst, msg, no_dispatch) struct svc_req *rqst; struct rpc_msg *msg; + bool_t *no_dispatch; { int cred_flavor; struct authsvc *asp; @@ -97,6 +98,7 @@ _authenticate(rqst, msg) 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; + *no_dispatch = FALSE; switch (cred_flavor) { case AUTH_NONE: dummy = _svcauth_none(rqst, msg); @@ -111,6 +113,11 @@ _authenticate(rqst, msg) case AUTH_DES: dummy = _svcauth_des(rqst, msg); return (dummy); +#endif +#ifdef HAVE_RPCSEC_GSS + case RPCSEC_GSS: + dummy = _svcauth_gss(rqst, msg, no_dispatch); + return (dummy); #endif default: break; @@ -132,6 +139,13 @@ _authenticate(rqst, msg) return (AUTH_REJECTEDCRED); } +enum auth_stat +_authenticate(struct svc_req *rqst, struct rpc_msg *msg) +{ + bool_t no_dispatch; + return _gss_authenticate(rqst, msg, &no_dispatch); +} + /* * Allow the rpc service to register new authentication types that it is * prepared to handle. When an authentication flavor is registered, @@ -160,6 +174,9 @@ svc_auth_reg(cred_flavor, handler) case AUTH_SHORT: #ifdef DES_BUILTIN case AUTH_DES: +#endif +#ifdef HAVE_RPCSEC_GSS + case RPCSEC_GSS: #endif /* already registered */ return (1); diff --git a/tirpc/rpc/auth.h b/tirpc/rpc/auth.h index 4ce11f0..7c8f813 100644 --- a/tirpc/rpc/auth.h +++ b/tirpc/rpc/auth.h @@ -399,6 +399,7 @@ struct rpc_msg; enum auth_stat _svcauth_none (struct svc_req *, struct rpc_msg *); enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *); enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *); +enum auth_stat _svcauth_gss (struct svc_req *, struct rpc_msg *, bool_t *); __END_DECLS #define AUTH_NONE 0 /* no authentication */ diff --git a/tirpc/rpc/svc_auth.h b/tirpc/rpc/svc_auth.h index 14269d1..723c989 100644 --- a/tirpc/rpc/svc_auth.h +++ b/tirpc/rpc/svc_auth.h @@ -66,6 +66,8 @@ typedef struct SVCAUTH { * Server side authenticator */ __BEGIN_DECLS +extern enum auth_stat _gss_authenticate(struct svc_req *, struct rpc_msg *, + bool_t *); extern enum auth_stat _authenticate(struct svc_req *, struct rpc_msg *); extern int svc_auth_reg(int, enum auth_stat (*)(struct svc_req *, struct rpc_msg *));