1177633Sdfr/*	$NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $	*/
2177633Sdfr
3261057Smav/*-
4261057Smav * Copyright (c) 2009, Sun Microsystems, Inc.
5261057Smav * All rights reserved.
6261057Smav *
7261057Smav * Redistribution and use in source and binary forms, with or without
8261057Smav * modification, are permitted provided that the following conditions are met:
9261057Smav * - Redistributions of source code must retain the above copyright notice,
10261057Smav *   this list of conditions and the following disclaimer.
11261057Smav * - Redistributions in binary form must reproduce the above copyright notice,
12261057Smav *   this list of conditions and the following disclaimer in the documentation
13261057Smav *   and/or other materials provided with the distribution.
14261057Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its
15261057Smav *   contributors may be used to endorse or promote products derived
16261057Smav *   from this software without specific prior written permission.
17177633Sdfr *
18261057Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19261057Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20261057Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21261057Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22261057Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23261057Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24261057Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25261057Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26261057Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27261057Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28261057Smav * POSSIBILITY OF SUCH DAMAGE.
29177633Sdfr */
30177633Sdfr/*
31177633Sdfr * Copyright (c) 1986-1991 by Sun Microsystems Inc.
32177633Sdfr */
33177633Sdfr
34177633Sdfr#if defined(LIBC_SCCS) && !defined(lint)
35177633Sdfr#ident	"@(#)svc_auth.c	1.16	94/04/24 SMI"
36177633Sdfrstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
37177633Sdfr#endif
38177633Sdfr#include <sys/cdefs.h>
39177633Sdfr__FBSDID("$FreeBSD$");
40177633Sdfr
41177633Sdfr/*
42177633Sdfr * svc_auth.c, Server-side rpc authenticator interface.
43177633Sdfr *
44177633Sdfr */
45177633Sdfr
46177633Sdfr#include <sys/param.h>
47177633Sdfr#include <sys/lock.h>
48177633Sdfr#include <sys/mutex.h>
49177633Sdfr#include <sys/systm.h>
50193650Srwatson#include <sys/jail.h>
51177633Sdfr#include <sys/ucred.h>
52177633Sdfr
53177633Sdfr#include <rpc/rpc.h>
54177633Sdfr
55184588Sdfrstatic enum auth_stat (*_svcauth_rpcsec_gss)(struct svc_req *,
56184588Sdfr    struct rpc_msg *) = NULL;
57184588Sdfrstatic int (*_svcauth_rpcsec_gss_getcred)(struct svc_req *,
58184588Sdfr    struct ucred **, int *);
59184588Sdfr
60184588Sdfrstatic struct svc_auth_ops svc_auth_null_ops;
61184588Sdfr
62177633Sdfr/*
63177633Sdfr * The call rpc message, msg has been obtained from the wire.  The msg contains
64177633Sdfr * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
65177633Sdfr * if the msg is successfully authenticated.  If AUTH_OK then the routine also
66177633Sdfr * does the following things:
67177633Sdfr * set rqst->rq_xprt->verf to the appropriate response verifier;
68177633Sdfr * sets rqst->rq_client_cred to the "cooked" form of the credentials.
69177633Sdfr *
70177633Sdfr * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
71177633Sdfr * its length is set appropriately.
72177633Sdfr *
73177633Sdfr * The caller still owns and is responsible for msg->u.cmb.cred and
74177633Sdfr * msg->u.cmb.verf.  The authentication system retains ownership of
75177633Sdfr * rqst->rq_client_cred, the cooked credentials.
76177633Sdfr *
77177633Sdfr * There is an assumption that any flavour less than AUTH_NULL is
78177633Sdfr * invalid.
79177633Sdfr */
80177633Sdfrenum auth_stat
81177633Sdfr_authenticate(struct svc_req *rqst, struct rpc_msg *msg)
82177633Sdfr{
83177633Sdfr	int cred_flavor;
84177633Sdfr	enum auth_stat dummy;
85177633Sdfr
86177633Sdfr	rqst->rq_cred = msg->rm_call.cb_cred;
87184588Sdfr	rqst->rq_auth.svc_ah_ops = &svc_auth_null_ops;
88184588Sdfr	rqst->rq_auth.svc_ah_private = NULL;
89177633Sdfr	cred_flavor = rqst->rq_cred.oa_flavor;
90177633Sdfr	switch (cred_flavor) {
91177633Sdfr	case AUTH_NULL:
92177633Sdfr		dummy = _svcauth_null(rqst, msg);
93177633Sdfr		return (dummy);
94177633Sdfr	case AUTH_SYS:
95177633Sdfr		dummy = _svcauth_unix(rqst, msg);
96177633Sdfr		return (dummy);
97177633Sdfr	case AUTH_SHORT:
98177633Sdfr		dummy = _svcauth_short(rqst, msg);
99177633Sdfr		return (dummy);
100184588Sdfr	case RPCSEC_GSS:
101184588Sdfr		if (!_svcauth_rpcsec_gss)
102184588Sdfr			return (AUTH_REJECTEDCRED);
103184588Sdfr		dummy = _svcauth_rpcsec_gss(rqst, msg);
104184588Sdfr		return (dummy);
105177633Sdfr	default:
106177633Sdfr		break;
107177633Sdfr	}
108177633Sdfr
109177633Sdfr	return (AUTH_REJECTEDCRED);
110177633Sdfr}
111177633Sdfr
112184588Sdfr/*
113184588Sdfr * A set of null auth methods used by any authentication protocols
114184588Sdfr * that don't need to inspect or modify the message body.
115184588Sdfr */
116184588Sdfrstatic bool_t
117184588Sdfrsvcauth_null_wrap(SVCAUTH *auth, struct mbuf **mp)
118184588Sdfr{
119184588Sdfr
120184588Sdfr	return (TRUE);
121184588Sdfr}
122184588Sdfr
123184588Sdfrstatic bool_t
124184588Sdfrsvcauth_null_unwrap(SVCAUTH *auth, struct mbuf **mp)
125184588Sdfr{
126184588Sdfr
127184588Sdfr	return (TRUE);
128184588Sdfr}
129184588Sdfr
130184588Sdfrstatic void
131184588Sdfrsvcauth_null_release(SVCAUTH *auth)
132184588Sdfr{
133184588Sdfr
134184588Sdfr}
135184588Sdfr
136184588Sdfrstatic struct svc_auth_ops svc_auth_null_ops = {
137184588Sdfr	svcauth_null_wrap,
138184588Sdfr	svcauth_null_unwrap,
139184588Sdfr	svcauth_null_release,
140184588Sdfr};
141184588Sdfr
142177633Sdfr/*ARGSUSED*/
143177633Sdfrenum auth_stat
144177633Sdfr_svcauth_null(struct svc_req *rqst, struct rpc_msg *msg)
145177633Sdfr{
146184588Sdfr
147184588Sdfr	rqst->rq_verf = _null_auth;
148177633Sdfr	return (AUTH_OK);
149177633Sdfr}
150177633Sdfr
151177633Sdfrint
152184588Sdfrsvc_auth_reg(int flavor,
153184588Sdfr    enum auth_stat (*svcauth)(struct svc_req *, struct rpc_msg *),
154184588Sdfr    int (*getcred)(struct svc_req *, struct ucred **, int *))
155177633Sdfr{
156184588Sdfr
157184588Sdfr	if (flavor == RPCSEC_GSS) {
158184588Sdfr		_svcauth_rpcsec_gss = svcauth;
159184588Sdfr		_svcauth_rpcsec_gss_getcred = getcred;
160184588Sdfr	}
161184588Sdfr	return (TRUE);
162184588Sdfr}
163184588Sdfr
164184588Sdfrint
165184588Sdfrsvc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
166184588Sdfr{
167184588Sdfr	struct ucred *cr = NULL;
168194498Sbrooks	int flavor;
169177633Sdfr	struct xucred *xcr;
170177633Sdfr
171177633Sdfr	flavor = rqst->rq_cred.oa_flavor;
172177633Sdfr	if (flavorp)
173177633Sdfr		*flavorp = flavor;
174177633Sdfr
175177633Sdfr	switch (flavor) {
176177633Sdfr	case AUTH_UNIX:
177177633Sdfr		xcr = (struct xucred *) rqst->rq_clntcred;
178184588Sdfr		cr = crget();
179177633Sdfr		cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
180194498Sbrooks		crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
181184588Sdfr		cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
182193650Srwatson		cr->cr_prison = &prison0;
183193650Srwatson		prison_hold(cr->cr_prison);
184184588Sdfr		*crp = cr;
185177633Sdfr		return (TRUE);
186177633Sdfr
187184588Sdfr	case RPCSEC_GSS:
188184588Sdfr		if (!_svcauth_rpcsec_gss_getcred)
189184588Sdfr			return (FALSE);
190184588Sdfr		return (_svcauth_rpcsec_gss_getcred(rqst, crp, flavorp));
191184588Sdfr
192177633Sdfr	default:
193177633Sdfr		return (FALSE);
194177633Sdfr	}
195177633Sdfr}
196177633Sdfr
197