1*7f2fe78bSCy Schubert /* lib/rpc/svc_auth_gss.c */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert Copyright (c) 2000 The Regents of the University of Michigan.
4*7f2fe78bSCy Schubert All rights reserved.
5*7f2fe78bSCy Schubert
6*7f2fe78bSCy Schubert Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
7*7f2fe78bSCy Schubert All rights reserved, all wrongs reversed.
8*7f2fe78bSCy Schubert
9*7f2fe78bSCy Schubert Redistribution and use in source and binary forms, with or without
10*7f2fe78bSCy Schubert modification, are permitted provided that the following conditions
11*7f2fe78bSCy Schubert are met:
12*7f2fe78bSCy Schubert
13*7f2fe78bSCy Schubert 1. Redistributions of source code must retain the above copyright
14*7f2fe78bSCy Schubert notice, this list of conditions and the following disclaimer.
15*7f2fe78bSCy Schubert 2. Redistributions in binary form must reproduce the above copyright
16*7f2fe78bSCy Schubert notice, this list of conditions and the following disclaimer in the
17*7f2fe78bSCy Schubert documentation and/or other materials provided with the distribution.
18*7f2fe78bSCy Schubert 3. Neither the name of the University nor the names of its
19*7f2fe78bSCy Schubert contributors may be used to endorse or promote products derived
20*7f2fe78bSCy Schubert from this software without specific prior written permission.
21*7f2fe78bSCy Schubert
22*7f2fe78bSCy Schubert THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23*7f2fe78bSCy Schubert WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24*7f2fe78bSCy Schubert MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25*7f2fe78bSCy Schubert DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*7f2fe78bSCy Schubert FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27*7f2fe78bSCy Schubert CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28*7f2fe78bSCy Schubert SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29*7f2fe78bSCy Schubert BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert
34*7f2fe78bSCy Schubert Id: svc_auth_gss.c,v 1.28 2002/10/15 21:29:36 kwc Exp
35*7f2fe78bSCy Schubert */
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert #include "k5-platform.h"
38*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
39*7f2fe78bSCy Schubert #include <gssrpc/auth_gssapi.h>
40*7f2fe78bSCy Schubert #ifdef HAVE_HEIMDAL
41*7f2fe78bSCy Schubert #include <gssapi.h>
42*7f2fe78bSCy Schubert #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
43*7f2fe78bSCy Schubert #else
44*7f2fe78bSCy Schubert #include <gssapi/gssapi.h>
45*7f2fe78bSCy Schubert #include <gssapi/gssapi_generic.h>
46*7f2fe78bSCy Schubert #endif
47*7f2fe78bSCy Schubert
48*7f2fe78bSCy Schubert #ifdef DEBUG_GSSAPI
49*7f2fe78bSCy Schubert int svc_debug_gss = DEBUG_GSSAPI;
50*7f2fe78bSCy Schubert #endif
51*7f2fe78bSCy Schubert
52*7f2fe78bSCy Schubert #ifdef SPKM
53*7f2fe78bSCy Schubert
54*7f2fe78bSCy Schubert #ifndef OID_EQ
55*7f2fe78bSCy Schubert #define g_OID_equal(o1,o2) \
56*7f2fe78bSCy Schubert (((o1)->length == (o2)->length) && \
57*7f2fe78bSCy Schubert ((o1)->elements != 0) && ((o2)->elements != 0) && \
58*7f2fe78bSCy Schubert (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0))
59*7f2fe78bSCy Schubert #define OID_EQ 1
60*7f2fe78bSCy Schubert #endif /* OID_EQ */
61*7f2fe78bSCy Schubert
62*7f2fe78bSCy Schubert extern const gss_OID_desc * const gss_mech_spkm3;
63*7f2fe78bSCy Schubert
64*7f2fe78bSCy Schubert #endif /* SPKM */
65*7f2fe78bSCy Schubert
66*7f2fe78bSCy Schubert extern SVCAUTH svc_auth_none;
67*7f2fe78bSCy Schubert
68*7f2fe78bSCy Schubert static auth_gssapi_log_badauth_func log_badauth = NULL;
69*7f2fe78bSCy Schubert static caddr_t log_badauth_data = NULL;
70*7f2fe78bSCy Schubert static auth_gssapi_log_badauth2_func log_badauth2 = NULL;
71*7f2fe78bSCy Schubert static caddr_t log_badauth2_data = NULL;
72*7f2fe78bSCy Schubert static auth_gssapi_log_badverf_func log_badverf = NULL;
73*7f2fe78bSCy Schubert static caddr_t log_badverf_data = NULL;
74*7f2fe78bSCy Schubert static auth_gssapi_log_miscerr_func log_miscerr = NULL;
75*7f2fe78bSCy Schubert static caddr_t log_miscerr_data = NULL;
76*7f2fe78bSCy Schubert
77*7f2fe78bSCy Schubert #define LOG_MISCERR(arg) if (log_miscerr) \
78*7f2fe78bSCy Schubert (*log_miscerr)(rqst, msg, arg, log_miscerr_data)
79*7f2fe78bSCy Schubert
80*7f2fe78bSCy Schubert static bool_t svcauth_gss_destroy(SVCAUTH *);
81*7f2fe78bSCy Schubert static bool_t svcauth_gss_wrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t);
82*7f2fe78bSCy Schubert static bool_t svcauth_gss_unwrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t);
83*7f2fe78bSCy Schubert
84*7f2fe78bSCy Schubert static bool_t svcauth_gss_nextverf(struct svc_req *, u_int);
85*7f2fe78bSCy Schubert
86*7f2fe78bSCy Schubert struct svc_auth_ops svc_auth_gss_ops = {
87*7f2fe78bSCy Schubert svcauth_gss_wrap,
88*7f2fe78bSCy Schubert svcauth_gss_unwrap,
89*7f2fe78bSCy Schubert svcauth_gss_destroy
90*7f2fe78bSCy Schubert };
91*7f2fe78bSCy Schubert
92*7f2fe78bSCy Schubert struct svc_rpc_gss_data {
93*7f2fe78bSCy Schubert bool_t established; /* context established */
94*7f2fe78bSCy Schubert gss_cred_id_t cred; /* credential */
95*7f2fe78bSCy Schubert gss_ctx_id_t ctx; /* context id */
96*7f2fe78bSCy Schubert struct rpc_gss_sec sec; /* security triple */
97*7f2fe78bSCy Schubert gss_buffer_desc cname; /* GSS client name */
98*7f2fe78bSCy Schubert u_int seq; /* sequence number */
99*7f2fe78bSCy Schubert u_int win; /* sequence window */
100*7f2fe78bSCy Schubert u_int seqlast; /* last sequence number */
101*7f2fe78bSCy Schubert uint32_t seqmask; /* bitmask of seqnums */
102*7f2fe78bSCy Schubert gss_name_t client_name; /* unparsed name string */
103*7f2fe78bSCy Schubert gss_buffer_desc checksum; /* so we can free it */
104*7f2fe78bSCy Schubert };
105*7f2fe78bSCy Schubert
106*7f2fe78bSCy Schubert #define SVCAUTH_PRIVATE(auth) \
107*7f2fe78bSCy Schubert (*(struct svc_rpc_gss_data **)&(auth)->svc_ah_private)
108*7f2fe78bSCy Schubert
109*7f2fe78bSCy Schubert /* Global server credentials. */
110*7f2fe78bSCy Schubert static gss_name_t svcauth_gss_name = NULL;
111*7f2fe78bSCy Schubert
112*7f2fe78bSCy Schubert bool_t
svcauth_gss_set_svc_name(gss_name_t name)113*7f2fe78bSCy Schubert svcauth_gss_set_svc_name(gss_name_t name)
114*7f2fe78bSCy Schubert {
115*7f2fe78bSCy Schubert OM_uint32 maj_stat, min_stat;
116*7f2fe78bSCy Schubert
117*7f2fe78bSCy Schubert log_debug("in svcauth_gss_set_svc_name()");
118*7f2fe78bSCy Schubert
119*7f2fe78bSCy Schubert if (svcauth_gss_name != NULL) {
120*7f2fe78bSCy Schubert maj_stat = gss_release_name(&min_stat, &svcauth_gss_name);
121*7f2fe78bSCy Schubert
122*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
123*7f2fe78bSCy Schubert log_status("gss_release_name", maj_stat, min_stat);
124*7f2fe78bSCy Schubert return (FALSE);
125*7f2fe78bSCy Schubert }
126*7f2fe78bSCy Schubert svcauth_gss_name = NULL;
127*7f2fe78bSCy Schubert }
128*7f2fe78bSCy Schubert if (svcauth_gss_name == GSS_C_NO_NAME)
129*7f2fe78bSCy Schubert return (TRUE);
130*7f2fe78bSCy Schubert
131*7f2fe78bSCy Schubert maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name);
132*7f2fe78bSCy Schubert
133*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
134*7f2fe78bSCy Schubert log_status("gss_duplicate_name", maj_stat, min_stat);
135*7f2fe78bSCy Schubert return (FALSE);
136*7f2fe78bSCy Schubert }
137*7f2fe78bSCy Schubert
138*7f2fe78bSCy Schubert return (TRUE);
139*7f2fe78bSCy Schubert }
140*7f2fe78bSCy Schubert
141*7f2fe78bSCy Schubert static bool_t
svcauth_gss_acquire_cred(struct svc_rpc_gss_data * gd)142*7f2fe78bSCy Schubert svcauth_gss_acquire_cred(struct svc_rpc_gss_data *gd)
143*7f2fe78bSCy Schubert {
144*7f2fe78bSCy Schubert OM_uint32 maj_stat, min_stat;
145*7f2fe78bSCy Schubert
146*7f2fe78bSCy Schubert log_debug("in svcauth_gss_acquire_cred()");
147*7f2fe78bSCy Schubert
148*7f2fe78bSCy Schubert /* We don't need to acquire a credential if using the default name. */
149*7f2fe78bSCy Schubert if (svcauth_gss_name == GSS_C_NO_NAME)
150*7f2fe78bSCy Schubert return (TRUE);
151*7f2fe78bSCy Schubert
152*7f2fe78bSCy Schubert /* Only acquire a credential once per authentication. */
153*7f2fe78bSCy Schubert if (gd->cred != GSS_C_NO_CREDENTIAL)
154*7f2fe78bSCy Schubert return (TRUE);
155*7f2fe78bSCy Schubert
156*7f2fe78bSCy Schubert maj_stat = gss_acquire_cred(&min_stat, svcauth_gss_name, 0,
157*7f2fe78bSCy Schubert GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
158*7f2fe78bSCy Schubert &gd->cred, NULL, NULL);
159*7f2fe78bSCy Schubert
160*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
161*7f2fe78bSCy Schubert log_status("gss_acquire_cred", maj_stat, min_stat);
162*7f2fe78bSCy Schubert return (FALSE);
163*7f2fe78bSCy Schubert }
164*7f2fe78bSCy Schubert return (TRUE);
165*7f2fe78bSCy Schubert }
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert /* Invoke log_badauth callbacks for an authentication failure. */
168*7f2fe78bSCy Schubert static void
badauth(OM_uint32 maj,OM_uint32 minor,SVCXPRT * xprt)169*7f2fe78bSCy Schubert badauth(OM_uint32 maj, OM_uint32 minor, SVCXPRT *xprt)
170*7f2fe78bSCy Schubert {
171*7f2fe78bSCy Schubert if (log_badauth != NULL)
172*7f2fe78bSCy Schubert (*log_badauth)(maj, minor, &xprt->xp_raddr, log_badauth_data);
173*7f2fe78bSCy Schubert if (log_badauth2 != NULL)
174*7f2fe78bSCy Schubert (*log_badauth2)(maj, minor, xprt, log_badauth2_data);
175*7f2fe78bSCy Schubert }
176*7f2fe78bSCy Schubert
177*7f2fe78bSCy Schubert static bool_t
svcauth_gss_accept_sec_context(struct svc_req * rqst,struct rpc_gss_init_res * gr)178*7f2fe78bSCy Schubert svcauth_gss_accept_sec_context(struct svc_req *rqst,
179*7f2fe78bSCy Schubert struct rpc_gss_init_res *gr)
180*7f2fe78bSCy Schubert {
181*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
182*7f2fe78bSCy Schubert struct rpc_gss_cred *gc;
183*7f2fe78bSCy Schubert gss_buffer_desc recv_tok, seqbuf;
184*7f2fe78bSCy Schubert gss_OID mech;
185*7f2fe78bSCy Schubert OM_uint32 maj_stat = 0, min_stat = 0, ret_flags, seq;
186*7f2fe78bSCy Schubert
187*7f2fe78bSCy Schubert log_debug("in svcauth_gss_accept_context()");
188*7f2fe78bSCy Schubert
189*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth);
190*7f2fe78bSCy Schubert gc = (struct rpc_gss_cred *)rqst->rq_clntcred;
191*7f2fe78bSCy Schubert memset(gr, 0, sizeof(*gr));
192*7f2fe78bSCy Schubert
193*7f2fe78bSCy Schubert /* Deserialize arguments. */
194*7f2fe78bSCy Schubert memset(&recv_tok, 0, sizeof(recv_tok));
195*7f2fe78bSCy Schubert
196*7f2fe78bSCy Schubert if (!svc_getargs(rqst->rq_xprt, xdr_rpc_gss_init_args,
197*7f2fe78bSCy Schubert (caddr_t)&recv_tok))
198*7f2fe78bSCy Schubert return (FALSE);
199*7f2fe78bSCy Schubert
200*7f2fe78bSCy Schubert gr->gr_major = gss_accept_sec_context(&gr->gr_minor,
201*7f2fe78bSCy Schubert &gd->ctx,
202*7f2fe78bSCy Schubert gd->cred,
203*7f2fe78bSCy Schubert &recv_tok,
204*7f2fe78bSCy Schubert GSS_C_NO_CHANNEL_BINDINGS,
205*7f2fe78bSCy Schubert &gd->client_name,
206*7f2fe78bSCy Schubert &mech,
207*7f2fe78bSCy Schubert &gr->gr_token,
208*7f2fe78bSCy Schubert &ret_flags,
209*7f2fe78bSCy Schubert NULL,
210*7f2fe78bSCy Schubert NULL);
211*7f2fe78bSCy Schubert
212*7f2fe78bSCy Schubert svc_freeargs(rqst->rq_xprt, xdr_rpc_gss_init_args, (caddr_t)&recv_tok);
213*7f2fe78bSCy Schubert
214*7f2fe78bSCy Schubert log_status("accept_sec_context", gr->gr_major, gr->gr_minor);
215*7f2fe78bSCy Schubert if (gr->gr_major != GSS_S_COMPLETE &&
216*7f2fe78bSCy Schubert gr->gr_major != GSS_S_CONTINUE_NEEDED) {
217*7f2fe78bSCy Schubert badauth(gr->gr_major, gr->gr_minor, rqst->rq_xprt);
218*7f2fe78bSCy Schubert gd->ctx = GSS_C_NO_CONTEXT;
219*7f2fe78bSCy Schubert goto errout;
220*7f2fe78bSCy Schubert }
221*7f2fe78bSCy Schubert gr->gr_ctx.value = "xxxx";
222*7f2fe78bSCy Schubert gr->gr_ctx.length = 4;
223*7f2fe78bSCy Schubert
224*7f2fe78bSCy Schubert /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version... */
225*7f2fe78bSCy Schubert gr->gr_win = sizeof(gd->seqmask) * 8;
226*7f2fe78bSCy Schubert
227*7f2fe78bSCy Schubert /* Save client info. */
228*7f2fe78bSCy Schubert gd->sec.mech = mech;
229*7f2fe78bSCy Schubert gd->sec.qop = GSS_C_QOP_DEFAULT;
230*7f2fe78bSCy Schubert gd->sec.svc = gc->gc_svc;
231*7f2fe78bSCy Schubert gd->seq = gc->gc_seq;
232*7f2fe78bSCy Schubert gd->win = gr->gr_win;
233*7f2fe78bSCy Schubert
234*7f2fe78bSCy Schubert if (gr->gr_major == GSS_S_COMPLETE) {
235*7f2fe78bSCy Schubert #ifdef SPKM
236*7f2fe78bSCy Schubert /* spkm3: no src_name (anonymous) */
237*7f2fe78bSCy Schubert if(!g_OID_equal(gss_mech_spkm3, mech)) {
238*7f2fe78bSCy Schubert #endif
239*7f2fe78bSCy Schubert maj_stat = gss_display_name(&min_stat, gd->client_name,
240*7f2fe78bSCy Schubert &gd->cname, &gd->sec.mech);
241*7f2fe78bSCy Schubert #ifdef SPKM
242*7f2fe78bSCy Schubert }
243*7f2fe78bSCy Schubert #endif
244*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
245*7f2fe78bSCy Schubert log_status("display_name", maj_stat, min_stat);
246*7f2fe78bSCy Schubert goto errout;
247*7f2fe78bSCy Schubert }
248*7f2fe78bSCy Schubert #ifdef DEBUG
249*7f2fe78bSCy Schubert #ifdef HAVE_HEIMDAL
250*7f2fe78bSCy Schubert log_debug("accepted context for %.*s with "
251*7f2fe78bSCy Schubert "<mech {}, qop %d, svc %d>",
252*7f2fe78bSCy Schubert gd->cname.length, (char *)gd->cname.value,
253*7f2fe78bSCy Schubert gd->sec.qop, gd->sec.svc);
254*7f2fe78bSCy Schubert #else
255*7f2fe78bSCy Schubert {
256*7f2fe78bSCy Schubert gss_buffer_desc mechname;
257*7f2fe78bSCy Schubert
258*7f2fe78bSCy Schubert gss_oid_to_str(&min_stat, mech, &mechname);
259*7f2fe78bSCy Schubert
260*7f2fe78bSCy Schubert log_debug("accepted context for %.*s with "
261*7f2fe78bSCy Schubert "<mech %.*s, qop %d, svc %d>",
262*7f2fe78bSCy Schubert gd->cname.length, (char *)gd->cname.value,
263*7f2fe78bSCy Schubert mechname.length, (char *)mechname.value,
264*7f2fe78bSCy Schubert gd->sec.qop, gd->sec.svc);
265*7f2fe78bSCy Schubert
266*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &mechname);
267*7f2fe78bSCy Schubert }
268*7f2fe78bSCy Schubert #endif
269*7f2fe78bSCy Schubert #endif /* DEBUG */
270*7f2fe78bSCy Schubert seq = htonl(gr->gr_win);
271*7f2fe78bSCy Schubert seqbuf.value = &seq;
272*7f2fe78bSCy Schubert seqbuf.length = sizeof(seq);
273*7f2fe78bSCy Schubert
274*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gd->checksum);
275*7f2fe78bSCy Schubert maj_stat = gss_sign(&min_stat, gd->ctx, GSS_C_QOP_DEFAULT,
276*7f2fe78bSCy Schubert &seqbuf, &gd->checksum);
277*7f2fe78bSCy Schubert
278*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
279*7f2fe78bSCy Schubert goto errout;
280*7f2fe78bSCy Schubert }
281*7f2fe78bSCy Schubert
282*7f2fe78bSCy Schubert
283*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
284*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_base = gd->checksum.value;
285*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_length = gd->checksum.length;
286*7f2fe78bSCy Schubert }
287*7f2fe78bSCy Schubert return (TRUE);
288*7f2fe78bSCy Schubert errout:
289*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gr->gr_token);
290*7f2fe78bSCy Schubert return (FALSE);
291*7f2fe78bSCy Schubert }
292*7f2fe78bSCy Schubert
293*7f2fe78bSCy Schubert static bool_t
svcauth_gss_validate(struct svc_req * rqst,struct svc_rpc_gss_data * gd,struct rpc_msg * msg)294*7f2fe78bSCy Schubert svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct rpc_msg *msg)
295*7f2fe78bSCy Schubert {
296*7f2fe78bSCy Schubert struct opaque_auth *oa;
297*7f2fe78bSCy Schubert gss_buffer_desc rpcbuf, checksum;
298*7f2fe78bSCy Schubert OM_uint32 maj_stat, min_stat, qop_state;
299*7f2fe78bSCy Schubert u_char rpchdr[128];
300*7f2fe78bSCy Schubert int32_t *buf;
301*7f2fe78bSCy Schubert
302*7f2fe78bSCy Schubert log_debug("in svcauth_gss_validate()");
303*7f2fe78bSCy Schubert
304*7f2fe78bSCy Schubert memset(rpchdr, 0, sizeof(rpchdr));
305*7f2fe78bSCy Schubert
306*7f2fe78bSCy Schubert /* XXX - Reconstruct RPC header for signing (from xdr_callmsg). */
307*7f2fe78bSCy Schubert oa = &msg->rm_call.cb_cred;
308*7f2fe78bSCy Schubert if (oa->oa_length > MAX_AUTH_BYTES)
309*7f2fe78bSCy Schubert return (FALSE);
310*7f2fe78bSCy Schubert
311*7f2fe78bSCy Schubert /* 8 XDR units from the IXDR macro calls. */
312*7f2fe78bSCy Schubert if (sizeof(rpchdr) < (8 * BYTES_PER_XDR_UNIT +
313*7f2fe78bSCy Schubert RNDUP(oa->oa_length)))
314*7f2fe78bSCy Schubert return (FALSE);
315*7f2fe78bSCy Schubert
316*7f2fe78bSCy Schubert buf = (int32_t *)(void *)rpchdr;
317*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, msg->rm_xid);
318*7f2fe78bSCy Schubert IXDR_PUT_ENUM(buf, msg->rm_direction);
319*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
320*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
321*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
322*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
323*7f2fe78bSCy Schubert IXDR_PUT_ENUM(buf, oa->oa_flavor);
324*7f2fe78bSCy Schubert IXDR_PUT_LONG(buf, oa->oa_length);
325*7f2fe78bSCy Schubert if (oa->oa_length) {
326*7f2fe78bSCy Schubert memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
327*7f2fe78bSCy Schubert buf += RNDUP(oa->oa_length) / sizeof(int32_t);
328*7f2fe78bSCy Schubert }
329*7f2fe78bSCy Schubert rpcbuf.value = rpchdr;
330*7f2fe78bSCy Schubert rpcbuf.length = (u_char *)buf - rpchdr;
331*7f2fe78bSCy Schubert
332*7f2fe78bSCy Schubert checksum.value = msg->rm_call.cb_verf.oa_base;
333*7f2fe78bSCy Schubert checksum.length = msg->rm_call.cb_verf.oa_length;
334*7f2fe78bSCy Schubert
335*7f2fe78bSCy Schubert maj_stat = gss_verify_mic(&min_stat, gd->ctx, &rpcbuf, &checksum,
336*7f2fe78bSCy Schubert &qop_state);
337*7f2fe78bSCy Schubert
338*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
339*7f2fe78bSCy Schubert log_status("gss_verify_mic", maj_stat, min_stat);
340*7f2fe78bSCy Schubert if (log_badverf != NULL)
341*7f2fe78bSCy Schubert (*log_badverf)(gd->client_name,
342*7f2fe78bSCy Schubert svcauth_gss_name,
343*7f2fe78bSCy Schubert rqst, msg, log_badverf_data);
344*7f2fe78bSCy Schubert return (FALSE);
345*7f2fe78bSCy Schubert }
346*7f2fe78bSCy Schubert return (TRUE);
347*7f2fe78bSCy Schubert }
348*7f2fe78bSCy Schubert
349*7f2fe78bSCy Schubert static bool_t
svcauth_gss_nextverf(struct svc_req * rqst,u_int num)350*7f2fe78bSCy Schubert svcauth_gss_nextverf(struct svc_req *rqst, u_int num)
351*7f2fe78bSCy Schubert {
352*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
353*7f2fe78bSCy Schubert gss_buffer_desc signbuf;
354*7f2fe78bSCy Schubert OM_uint32 maj_stat, min_stat;
355*7f2fe78bSCy Schubert
356*7f2fe78bSCy Schubert log_debug("in svcauth_gss_nextverf()");
357*7f2fe78bSCy Schubert
358*7f2fe78bSCy Schubert if (rqst->rq_xprt->xp_auth == NULL)
359*7f2fe78bSCy Schubert return (FALSE);
360*7f2fe78bSCy Schubert
361*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth);
362*7f2fe78bSCy Schubert
363*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gd->checksum);
364*7f2fe78bSCy Schubert
365*7f2fe78bSCy Schubert signbuf.value = #
366*7f2fe78bSCy Schubert signbuf.length = sizeof(num);
367*7f2fe78bSCy Schubert
368*7f2fe78bSCy Schubert maj_stat = gss_get_mic(&min_stat, gd->ctx, gd->sec.qop,
369*7f2fe78bSCy Schubert &signbuf, &gd->checksum);
370*7f2fe78bSCy Schubert
371*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
372*7f2fe78bSCy Schubert log_status("gss_get_mic", maj_stat, min_stat);
373*7f2fe78bSCy Schubert return (FALSE);
374*7f2fe78bSCy Schubert }
375*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
376*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_base = (caddr_t)gd->checksum.value;
377*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf.oa_length = (u_int)gd->checksum.length;
378*7f2fe78bSCy Schubert
379*7f2fe78bSCy Schubert return (TRUE);
380*7f2fe78bSCy Schubert }
381*7f2fe78bSCy Schubert
382*7f2fe78bSCy Schubert enum auth_stat
gssrpc__svcauth_gss(struct svc_req * rqst,struct rpc_msg * msg,bool_t * no_dispatch)383*7f2fe78bSCy Schubert gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
384*7f2fe78bSCy Schubert bool_t *no_dispatch)
385*7f2fe78bSCy Schubert {
386*7f2fe78bSCy Schubert enum auth_stat retstat;
387*7f2fe78bSCy Schubert XDR xdrs;
388*7f2fe78bSCy Schubert SVCAUTH *auth;
389*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
390*7f2fe78bSCy Schubert struct rpc_gss_cred *gc;
391*7f2fe78bSCy Schubert struct rpc_gss_init_res gr;
392*7f2fe78bSCy Schubert int call_stat, offset;
393*7f2fe78bSCy Schubert OM_uint32 min_stat;
394*7f2fe78bSCy Schubert
395*7f2fe78bSCy Schubert log_debug("in svcauth_gss()");
396*7f2fe78bSCy Schubert
397*7f2fe78bSCy Schubert /* Initialize reply. */
398*7f2fe78bSCy Schubert rqst->rq_xprt->xp_verf = gssrpc__null_auth;
399*7f2fe78bSCy Schubert
400*7f2fe78bSCy Schubert /* Allocate and set up server auth handle. */
401*7f2fe78bSCy Schubert if (rqst->rq_xprt->xp_auth == NULL ||
402*7f2fe78bSCy Schubert rqst->rq_xprt->xp_auth == &svc_auth_none) {
403*7f2fe78bSCy Schubert if ((auth = calloc(sizeof(*auth), 1)) == NULL) {
404*7f2fe78bSCy Schubert fprintf(stderr, "svcauth_gss: out_of_memory\n");
405*7f2fe78bSCy Schubert return (AUTH_FAILED);
406*7f2fe78bSCy Schubert }
407*7f2fe78bSCy Schubert if ((gd = calloc(sizeof(*gd), 1)) == NULL) {
408*7f2fe78bSCy Schubert fprintf(stderr, "svcauth_gss: out_of_memory\n");
409*7f2fe78bSCy Schubert return (AUTH_FAILED);
410*7f2fe78bSCy Schubert }
411*7f2fe78bSCy Schubert auth->svc_ah_ops = &svc_auth_gss_ops;
412*7f2fe78bSCy Schubert SVCAUTH_PRIVATE(auth) = gd;
413*7f2fe78bSCy Schubert rqst->rq_xprt->xp_auth = auth;
414*7f2fe78bSCy Schubert }
415*7f2fe78bSCy Schubert else gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth);
416*7f2fe78bSCy Schubert
417*7f2fe78bSCy Schubert log_debug("xp_auth=%p, gd=%p", rqst->rq_xprt->xp_auth, gd);
418*7f2fe78bSCy Schubert
419*7f2fe78bSCy Schubert /* Deserialize client credentials. */
420*7f2fe78bSCy Schubert if (rqst->rq_cred.oa_length <= 0)
421*7f2fe78bSCy Schubert return (AUTH_BADCRED);
422*7f2fe78bSCy Schubert
423*7f2fe78bSCy Schubert gc = (struct rpc_gss_cred *)rqst->rq_clntcred;
424*7f2fe78bSCy Schubert memset(gc, 0, sizeof(*gc));
425*7f2fe78bSCy Schubert
426*7f2fe78bSCy Schubert log_debug("calling xdrmem_create()");
427*7f2fe78bSCy Schubert log_debug("oa_base=%p, oa_length=%u", rqst->rq_cred.oa_base,
428*7f2fe78bSCy Schubert rqst->rq_cred.oa_length);
429*7f2fe78bSCy Schubert xdrmem_create(&xdrs, rqst->rq_cred.oa_base,
430*7f2fe78bSCy Schubert rqst->rq_cred.oa_length, XDR_DECODE);
431*7f2fe78bSCy Schubert log_debug("xdrmem_create() returned");
432*7f2fe78bSCy Schubert
433*7f2fe78bSCy Schubert if (!xdr_rpc_gss_cred(&xdrs, gc)) {
434*7f2fe78bSCy Schubert log_debug("xdr_rpc_gss_cred() failed");
435*7f2fe78bSCy Schubert XDR_DESTROY(&xdrs);
436*7f2fe78bSCy Schubert return (AUTH_BADCRED);
437*7f2fe78bSCy Schubert }
438*7f2fe78bSCy Schubert XDR_DESTROY(&xdrs);
439*7f2fe78bSCy Schubert
440*7f2fe78bSCy Schubert retstat = AUTH_FAILED;
441*7f2fe78bSCy Schubert
442*7f2fe78bSCy Schubert #define ret_freegc(code) do { retstat = code; goto freegc; } while (0)
443*7f2fe78bSCy Schubert
444*7f2fe78bSCy Schubert /* Check version. */
445*7f2fe78bSCy Schubert if (gc->gc_v != RPCSEC_GSS_VERSION)
446*7f2fe78bSCy Schubert ret_freegc (AUTH_BADCRED);
447*7f2fe78bSCy Schubert
448*7f2fe78bSCy Schubert /* Check RPCSEC_GSS service. */
449*7f2fe78bSCy Schubert if (gc->gc_svc != RPCSEC_GSS_SVC_NONE &&
450*7f2fe78bSCy Schubert gc->gc_svc != RPCSEC_GSS_SVC_INTEGRITY &&
451*7f2fe78bSCy Schubert gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY)
452*7f2fe78bSCy Schubert ret_freegc (AUTH_BADCRED);
453*7f2fe78bSCy Schubert
454*7f2fe78bSCy Schubert /* Check sequence number. */
455*7f2fe78bSCy Schubert if (gd->established) {
456*7f2fe78bSCy Schubert if (gc->gc_seq > MAXSEQ)
457*7f2fe78bSCy Schubert ret_freegc (RPCSEC_GSS_CTXPROBLEM);
458*7f2fe78bSCy Schubert
459*7f2fe78bSCy Schubert if ((offset = gd->seqlast - gc->gc_seq) < 0) {
460*7f2fe78bSCy Schubert gd->seqlast = gc->gc_seq;
461*7f2fe78bSCy Schubert offset = 0 - offset;
462*7f2fe78bSCy Schubert gd->seqmask <<= offset;
463*7f2fe78bSCy Schubert offset = 0;
464*7f2fe78bSCy Schubert } else if ((u_int)offset >= gd->win ||
465*7f2fe78bSCy Schubert (gd->seqmask & (1 << offset))) {
466*7f2fe78bSCy Schubert *no_dispatch = 1;
467*7f2fe78bSCy Schubert ret_freegc (RPCSEC_GSS_CTXPROBLEM);
468*7f2fe78bSCy Schubert }
469*7f2fe78bSCy Schubert gd->seq = gc->gc_seq;
470*7f2fe78bSCy Schubert gd->seqmask |= (1 << offset);
471*7f2fe78bSCy Schubert }
472*7f2fe78bSCy Schubert
473*7f2fe78bSCy Schubert if (gd->established) {
474*7f2fe78bSCy Schubert rqst->rq_clntname = (char *)gd->client_name;
475*7f2fe78bSCy Schubert rqst->rq_svccred = (char *)gd->ctx;
476*7f2fe78bSCy Schubert }
477*7f2fe78bSCy Schubert
478*7f2fe78bSCy Schubert /* Handle RPCSEC_GSS control procedure. */
479*7f2fe78bSCy Schubert switch (gc->gc_proc) {
480*7f2fe78bSCy Schubert
481*7f2fe78bSCy Schubert case RPCSEC_GSS_INIT:
482*7f2fe78bSCy Schubert case RPCSEC_GSS_CONTINUE_INIT:
483*7f2fe78bSCy Schubert if (rqst->rq_proc != NULLPROC)
484*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED); /* XXX ? */
485*7f2fe78bSCy Schubert
486*7f2fe78bSCy Schubert if (!svcauth_gss_acquire_cred(gd))
487*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED);
488*7f2fe78bSCy Schubert
489*7f2fe78bSCy Schubert if (!svcauth_gss_accept_sec_context(rqst, &gr))
490*7f2fe78bSCy Schubert ret_freegc (AUTH_REJECTEDCRED);
491*7f2fe78bSCy Schubert
492*7f2fe78bSCy Schubert if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
493*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gr.gr_token);
494*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED);
495*7f2fe78bSCy Schubert }
496*7f2fe78bSCy Schubert *no_dispatch = TRUE;
497*7f2fe78bSCy Schubert
498*7f2fe78bSCy Schubert call_stat = svc_sendreply(rqst->rq_xprt, xdr_rpc_gss_init_res,
499*7f2fe78bSCy Schubert (caddr_t)&gr);
500*7f2fe78bSCy Schubert
501*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gr.gr_token);
502*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gd->checksum);
503*7f2fe78bSCy Schubert if (!call_stat)
504*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED);
505*7f2fe78bSCy Schubert
506*7f2fe78bSCy Schubert if (gr.gr_major == GSS_S_COMPLETE)
507*7f2fe78bSCy Schubert gd->established = TRUE;
508*7f2fe78bSCy Schubert
509*7f2fe78bSCy Schubert break;
510*7f2fe78bSCy Schubert
511*7f2fe78bSCy Schubert case RPCSEC_GSS_DATA:
512*7f2fe78bSCy Schubert if (!svcauth_gss_validate(rqst, gd, msg))
513*7f2fe78bSCy Schubert ret_freegc (RPCSEC_GSS_CREDPROBLEM);
514*7f2fe78bSCy Schubert
515*7f2fe78bSCy Schubert if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
516*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED);
517*7f2fe78bSCy Schubert break;
518*7f2fe78bSCy Schubert
519*7f2fe78bSCy Schubert case RPCSEC_GSS_DESTROY:
520*7f2fe78bSCy Schubert if (rqst->rq_proc != NULLPROC)
521*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED); /* XXX ? */
522*7f2fe78bSCy Schubert
523*7f2fe78bSCy Schubert if (!svcauth_gss_validate(rqst, gd, msg))
524*7f2fe78bSCy Schubert ret_freegc (RPCSEC_GSS_CREDPROBLEM);
525*7f2fe78bSCy Schubert
526*7f2fe78bSCy Schubert if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
527*7f2fe78bSCy Schubert ret_freegc (AUTH_FAILED);
528*7f2fe78bSCy Schubert
529*7f2fe78bSCy Schubert *no_dispatch = TRUE;
530*7f2fe78bSCy Schubert
531*7f2fe78bSCy Schubert call_stat = svc_sendreply(rqst->rq_xprt,
532*7f2fe78bSCy Schubert xdr_void, (caddr_t)NULL);
533*7f2fe78bSCy Schubert
534*7f2fe78bSCy Schubert log_debug("sendreply in destroy: %d", call_stat);
535*7f2fe78bSCy Schubert
536*7f2fe78bSCy Schubert SVCAUTH_DESTROY(rqst->rq_xprt->xp_auth);
537*7f2fe78bSCy Schubert rqst->rq_xprt->xp_auth = &svc_auth_none;
538*7f2fe78bSCy Schubert
539*7f2fe78bSCy Schubert break;
540*7f2fe78bSCy Schubert
541*7f2fe78bSCy Schubert default:
542*7f2fe78bSCy Schubert ret_freegc (AUTH_REJECTEDCRED);
543*7f2fe78bSCy Schubert break;
544*7f2fe78bSCy Schubert }
545*7f2fe78bSCy Schubert retstat = AUTH_OK;
546*7f2fe78bSCy Schubert freegc:
547*7f2fe78bSCy Schubert xdr_free(xdr_rpc_gss_cred, gc);
548*7f2fe78bSCy Schubert log_debug("returning %d from svcauth_gss()", retstat);
549*7f2fe78bSCy Schubert return (retstat);
550*7f2fe78bSCy Schubert }
551*7f2fe78bSCy Schubert
552*7f2fe78bSCy Schubert static bool_t
svcauth_gss_destroy(SVCAUTH * auth)553*7f2fe78bSCy Schubert svcauth_gss_destroy(SVCAUTH *auth)
554*7f2fe78bSCy Schubert {
555*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
556*7f2fe78bSCy Schubert OM_uint32 min_stat;
557*7f2fe78bSCy Schubert
558*7f2fe78bSCy Schubert log_debug("in svcauth_gss_destroy()");
559*7f2fe78bSCy Schubert
560*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(auth);
561*7f2fe78bSCy Schubert
562*7f2fe78bSCy Schubert gss_delete_sec_context(&min_stat, &gd->ctx, GSS_C_NO_BUFFER);
563*7f2fe78bSCy Schubert gss_release_cred(&min_stat, &gd->cred);
564*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gd->cname);
565*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gd->checksum);
566*7f2fe78bSCy Schubert
567*7f2fe78bSCy Schubert if (gd->client_name)
568*7f2fe78bSCy Schubert gss_release_name(&min_stat, &gd->client_name);
569*7f2fe78bSCy Schubert
570*7f2fe78bSCy Schubert mem_free(gd, sizeof(*gd));
571*7f2fe78bSCy Schubert mem_free(auth, sizeof(*auth));
572*7f2fe78bSCy Schubert
573*7f2fe78bSCy Schubert return (TRUE);
574*7f2fe78bSCy Schubert }
575*7f2fe78bSCy Schubert
576*7f2fe78bSCy Schubert static bool_t
svcauth_gss_wrap(SVCAUTH * auth,XDR * xdrs,xdrproc_t xdr_func,caddr_t xdr_ptr)577*7f2fe78bSCy Schubert svcauth_gss_wrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr)
578*7f2fe78bSCy Schubert {
579*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
580*7f2fe78bSCy Schubert
581*7f2fe78bSCy Schubert log_debug("in svcauth_gss_wrap()");
582*7f2fe78bSCy Schubert
583*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(auth);
584*7f2fe78bSCy Schubert
585*7f2fe78bSCy Schubert if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) {
586*7f2fe78bSCy Schubert return ((*xdr_func)(xdrs, xdr_ptr));
587*7f2fe78bSCy Schubert }
588*7f2fe78bSCy Schubert return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr,
589*7f2fe78bSCy Schubert gd->ctx, gd->sec.qop,
590*7f2fe78bSCy Schubert gd->sec.svc, gd->seq));
591*7f2fe78bSCy Schubert }
592*7f2fe78bSCy Schubert
593*7f2fe78bSCy Schubert static bool_t
svcauth_gss_unwrap(SVCAUTH * auth,XDR * xdrs,xdrproc_t xdr_func,caddr_t xdr_ptr)594*7f2fe78bSCy Schubert svcauth_gss_unwrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr)
595*7f2fe78bSCy Schubert {
596*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
597*7f2fe78bSCy Schubert
598*7f2fe78bSCy Schubert log_debug("in svcauth_gss_unwrap()");
599*7f2fe78bSCy Schubert
600*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(auth);
601*7f2fe78bSCy Schubert
602*7f2fe78bSCy Schubert if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) {
603*7f2fe78bSCy Schubert return ((*xdr_func)(xdrs, xdr_ptr));
604*7f2fe78bSCy Schubert }
605*7f2fe78bSCy Schubert return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr,
606*7f2fe78bSCy Schubert gd->ctx, gd->sec.qop,
607*7f2fe78bSCy Schubert gd->sec.svc, gd->seq));
608*7f2fe78bSCy Schubert }
609*7f2fe78bSCy Schubert
610*7f2fe78bSCy Schubert char *
svcauth_gss_get_principal(SVCAUTH * auth)611*7f2fe78bSCy Schubert svcauth_gss_get_principal(SVCAUTH *auth)
612*7f2fe78bSCy Schubert {
613*7f2fe78bSCy Schubert struct svc_rpc_gss_data *gd;
614*7f2fe78bSCy Schubert char *pname;
615*7f2fe78bSCy Schubert
616*7f2fe78bSCy Schubert gd = SVCAUTH_PRIVATE(auth);
617*7f2fe78bSCy Schubert
618*7f2fe78bSCy Schubert if (gd->cname.length == 0 || gd->cname.length >= SIZE_MAX)
619*7f2fe78bSCy Schubert return (NULL);
620*7f2fe78bSCy Schubert
621*7f2fe78bSCy Schubert if ((pname = malloc(gd->cname.length + 1)) == NULL)
622*7f2fe78bSCy Schubert return (NULL);
623*7f2fe78bSCy Schubert
624*7f2fe78bSCy Schubert memcpy(pname, gd->cname.value, gd->cname.length);
625*7f2fe78bSCy Schubert pname[gd->cname.length] = '\0';
626*7f2fe78bSCy Schubert
627*7f2fe78bSCy Schubert return (pname);
628*7f2fe78bSCy Schubert }
629*7f2fe78bSCy Schubert
630*7f2fe78bSCy Schubert /*
631*7f2fe78bSCy Schubert * Function: svcauth_gss_set_log_badauth_func
632*7f2fe78bSCy Schubert *
633*7f2fe78bSCy Schubert * Purpose: sets the logging function called when an invalid RPC call
634*7f2fe78bSCy Schubert * arrives
635*7f2fe78bSCy Schubert *
636*7f2fe78bSCy Schubert * See functional specifications.
637*7f2fe78bSCy Schubert */
svcauth_gss_set_log_badauth_func(auth_gssapi_log_badauth_func func,caddr_t data)638*7f2fe78bSCy Schubert void svcauth_gss_set_log_badauth_func(
639*7f2fe78bSCy Schubert auth_gssapi_log_badauth_func func,
640*7f2fe78bSCy Schubert caddr_t data)
641*7f2fe78bSCy Schubert {
642*7f2fe78bSCy Schubert log_badauth = func;
643*7f2fe78bSCy Schubert log_badauth_data = data;
644*7f2fe78bSCy Schubert }
645*7f2fe78bSCy Schubert
646*7f2fe78bSCy Schubert void
svcauth_gss_set_log_badauth2_func(auth_gssapi_log_badauth2_func func,caddr_t data)647*7f2fe78bSCy Schubert svcauth_gss_set_log_badauth2_func(auth_gssapi_log_badauth2_func func,
648*7f2fe78bSCy Schubert caddr_t data)
649*7f2fe78bSCy Schubert {
650*7f2fe78bSCy Schubert log_badauth2 = func;
651*7f2fe78bSCy Schubert log_badauth2_data = data;
652*7f2fe78bSCy Schubert }
653*7f2fe78bSCy Schubert
654*7f2fe78bSCy Schubert /*
655*7f2fe78bSCy Schubert * Function: svcauth_gss_set_log_badverf_func
656*7f2fe78bSCy Schubert *
657*7f2fe78bSCy Schubert * Purpose: sets the logging function called when an invalid RPC call
658*7f2fe78bSCy Schubert * arrives
659*7f2fe78bSCy Schubert *
660*7f2fe78bSCy Schubert * See functional specifications.
661*7f2fe78bSCy Schubert */
svcauth_gss_set_log_badverf_func(auth_gssapi_log_badverf_func func,caddr_t data)662*7f2fe78bSCy Schubert void svcauth_gss_set_log_badverf_func(
663*7f2fe78bSCy Schubert auth_gssapi_log_badverf_func func,
664*7f2fe78bSCy Schubert caddr_t data)
665*7f2fe78bSCy Schubert {
666*7f2fe78bSCy Schubert log_badverf = func;
667*7f2fe78bSCy Schubert log_badverf_data = data;
668*7f2fe78bSCy Schubert }
669*7f2fe78bSCy Schubert
670*7f2fe78bSCy Schubert /*
671*7f2fe78bSCy Schubert * Function: svcauth_gss_set_log_miscerr_func
672*7f2fe78bSCy Schubert *
673*7f2fe78bSCy Schubert * Purpose: sets the logging function called when a miscellaneous
674*7f2fe78bSCy Schubert * AUTH_GSSAPI error occurs
675*7f2fe78bSCy Schubert *
676*7f2fe78bSCy Schubert * See functional specifications.
677*7f2fe78bSCy Schubert */
svcauth_gss_set_log_miscerr_func(auth_gssapi_log_miscerr_func func,caddr_t data)678*7f2fe78bSCy Schubert void svcauth_gss_set_log_miscerr_func(
679*7f2fe78bSCy Schubert auth_gssapi_log_miscerr_func func,
680*7f2fe78bSCy Schubert caddr_t data)
681*7f2fe78bSCy Schubert {
682*7f2fe78bSCy Schubert log_miscerr = func;
683*7f2fe78bSCy Schubert log_miscerr_data = data;
684*7f2fe78bSCy Schubert }
685