svc_auth.c revision 261057
1133362Sobrien/*	$NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $	*/
2133362Sobrien
3284193Sdelphij/*-
4284193Sdelphij * Copyright (c) 2009, Sun Microsystems, Inc.
5284193Sdelphij * All rights reserved.
6284193Sdelphij *
7284193Sdelphij * Redistribution and use in source and binary forms, with or without
8284193Sdelphij * modification, are permitted provided that the following conditions are met:
9284193Sdelphij * - Redistributions of source code must retain the above copyright notice,
10284193Sdelphij *   this list of conditions and the following disclaimer.
11175299Sobrien * - Redistributions in binary form must reproduce the above copyright notice,
12208341Smarius *   this list of conditions and the following disclaimer in the documentation
13133362Sobrien *   and/or other materials provided with the distribution.
14268515Sdelphij * - Neither the name of Sun Microsystems, Inc. nor the names of its
15268515Sdelphij *   contributors may be used to endorse or promote products derived
16268515Sdelphij *   from this software without specific prior written permission.
17208341Smarius *
18133362Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19133362Sobrien * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20208341Smarius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21133362Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22133362Sobrien * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23268515Sdelphij * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24268515Sdelphij * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25268515Sdelphij * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26191771Sobrien * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27191771Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28191771Sobrien * POSSIBILITY OF SUCH DAMAGE.
29268515Sdelphij */
30268515Sdelphij/*
31268515Sdelphij * Copyright (c) 1986-1991 by Sun Microsystems Inc.
32208341Smarius */
33133362Sobrien
34133362Sobrien#if defined(LIBC_SCCS) && !defined(lint)
35234449Sobrien#ident	"@(#)svc_auth.c	1.16	94/04/24 SMI"
36234449Sobrienstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
37234449Sobrien#endif
38234449Sobrien#include <sys/cdefs.h>
39234449Sobrien__FBSDID("$FreeBSD: stable/9/sys/rpc/svc_auth.c 261057 2014-01-23 00:28:17Z mav $");
40234449Sobrien
41234449Sobrien/*
42234449Sobrien * svc_auth.c, Server-side rpc authenticator interface.
43159769Sobrien *
44159769Sobrien */
45133362Sobrien
46191771Sobrien#include <sys/param.h>
47191771Sobrien#include <sys/lock.h>
48191771Sobrien#include <sys/mutex.h>
49133362Sobrien#include <sys/systm.h>
50133362Sobrien#include <sys/jail.h>
51133362Sobrien#include <sys/ucred.h>
52268515Sdelphij
53268515Sdelphij#include <rpc/rpc.h>
54268515Sdelphij
55234449Sobrienstatic enum auth_stat (*_svcauth_rpcsec_gss)(struct svc_req *,
56234449Sobrien    struct rpc_msg *) = NULL;
57234449Sobrienstatic int (*_svcauth_rpcsec_gss_getcred)(struct svc_req *,
58284193Sdelphij    struct ucred **, int *);
59284193Sdelphij
60284193Sdelphijstatic struct svc_auth_ops svc_auth_null_ops;
61284193Sdelphij
62284193Sdelphij/*
63191771Sobrien * The call rpc message, msg has been obtained from the wire.  The msg contains
64191771Sobrien * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
65191771Sobrien * if the msg is successfully authenticated.  If AUTH_OK then the routine also
66234449Sobrien * does the following things:
67234449Sobrien * set rqst->rq_xprt->verf to the appropriate response verifier;
68234449Sobrien * sets rqst->rq_client_cred to the "cooked" form of the credentials.
69133362Sobrien *
70133362Sobrien * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
71133362Sobrien * its length is set appropriately.
72133362Sobrien *
73133362Sobrien * The caller still owns and is responsible for msg->u.cmb.cred and
74133362Sobrien * msg->u.cmb.verf.  The authentication system retains ownership of
75268515Sdelphij * rqst->rq_client_cred, the cooked credentials.
76268515Sdelphij *
77191771Sobrien * There is an assumption that any flavour less than AUTH_NULL is
78268515Sdelphij * invalid.
79268515Sdelphij */
80191771Sobrienenum auth_stat
81133362Sobrien_authenticate(struct svc_req *rqst, struct rpc_msg *msg)
82133362Sobrien{
83133362Sobrien	int cred_flavor;
84234449Sobrien	enum auth_stat dummy;
85234449Sobrien
86234449Sobrien	rqst->rq_cred = msg->rm_call.cb_cred;
87133362Sobrien	rqst->rq_auth.svc_ah_ops = &svc_auth_null_ops;
88133362Sobrien	rqst->rq_auth.svc_ah_private = NULL;
89133362Sobrien	cred_flavor = rqst->rq_cred.oa_flavor;
90169967Sobrien	switch (cred_flavor) {
91169967Sobrien	case AUTH_NULL:
92169967Sobrien		dummy = _svcauth_null(rqst, msg);
93133362Sobrien		return (dummy);
94133362Sobrien	case AUTH_SYS:
95133362Sobrien		dummy = _svcauth_unix(rqst, msg);
96268515Sdelphij		return (dummy);
97133362Sobrien	case AUTH_SHORT:
98133362Sobrien		dummy = _svcauth_short(rqst, msg);
99159769Sobrien		return (dummy);
100159769Sobrien	case RPCSEC_GSS:
101159769Sobrien		if (!_svcauth_rpcsec_gss)
102133362Sobrien			return (AUTH_REJECTEDCRED);
103133362Sobrien		dummy = _svcauth_rpcsec_gss(rqst, msg);
104133362Sobrien		return (dummy);
105268515Sdelphij	default:
106268515Sdelphij		break;
107268515Sdelphij	}
108133362Sobrien
109133362Sobrien	return (AUTH_REJECTEDCRED);
110133362Sobrien}
111268515Sdelphij
112133362Sobrien/*
113133362Sobrien * A set of null auth methods used by any authentication protocols
114284193Sdelphij * that don't need to inspect or modify the message body.
115284193Sdelphij */
116284193Sdelphijstatic bool_t
117284193Sdelphijsvcauth_null_wrap(SVCAUTH *auth, struct mbuf **mp)
118284193Sdelphij{
119268515Sdelphij
120268515Sdelphij	return (TRUE);
121234449Sobrien}
122284193Sdelphij
123284193Sdelphijstatic bool_t
124284193Sdelphijsvcauth_null_unwrap(SVCAUTH *auth, struct mbuf **mp)
125268515Sdelphij{
126268515Sdelphij
127268515Sdelphij	return (TRUE);
128133362Sobrien}
129133362Sobrien
130133362Sobrienstatic void
131133362Sobriensvcauth_null_release(SVCAUTH *auth)
132133362Sobrien{
133133362Sobrien
134268515Sdelphij}
135268515Sdelphij
136268515Sdelphijstatic struct svc_auth_ops svc_auth_null_ops = {
137133362Sobrien	svcauth_null_wrap,
138133362Sobrien	svcauth_null_unwrap,
139133362Sobrien	svcauth_null_release,
140133362Sobrien};
141133362Sobrien
142133362Sobrien/*ARGSUSED*/
143133362Sobrienenum auth_stat
144133362Sobrien_svcauth_null(struct svc_req *rqst, struct rpc_msg *msg)
145133362Sobrien{
146191771Sobrien
147191771Sobrien	rqst->rq_verf = _null_auth;
148191771Sobrien	return (AUTH_OK);
149191771Sobrien}
150191771Sobrien
151191771Sobrienint
152169946Sobriensvc_auth_reg(int flavor,
153185777Skib    enum auth_stat (*svcauth)(struct svc_req *, struct rpc_msg *),
154169946Sobrien    int (*getcred)(struct svc_req *, struct ucred **, int *))
155175299Sobrien{
156175299Sobrien
157175299Sobrien	if (flavor == RPCSEC_GSS) {
158133362Sobrien		_svcauth_rpcsec_gss = svcauth;
159133362Sobrien		_svcauth_rpcsec_gss_getcred = getcred;
160133362Sobrien	}
161208341Smarius	return (TRUE);
162208341Smarius}
163208341Smarius
164234449Sobrienint
165133362Sobriensvc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
166133362Sobrien{
167234449Sobrien	struct ucred *cr = NULL;
168191771Sobrien	int flavor;
169191771Sobrien	struct xucred *xcr;
170234449Sobrien
171191771Sobrien	flavor = rqst->rq_cred.oa_flavor;
172191771Sobrien	if (flavorp)
173133362Sobrien		*flavorp = flavor;
174133362Sobrien
175133362Sobrien	switch (flavor) {
176268515Sdelphij	case AUTH_UNIX:
177268515Sdelphij		xcr = (struct xucred *) rqst->rq_clntcred;
178268515Sdelphij		cr = crget();
179133362Sobrien		cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
180133362Sobrien		crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
181133362Sobrien		cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
182169946Sobrien		cr->cr_prison = &prison0;
183169946Sobrien		prison_hold(cr->cr_prison);
184169946Sobrien		*crp = cr;
185133362Sobrien		return (TRUE);
186133362Sobrien
187133362Sobrien	case RPCSEC_GSS:
188133362Sobrien		if (!_svcauth_rpcsec_gss_getcred)
189133362Sobrien			return (FALSE);
190133362Sobrien		return (_svcauth_rpcsec_gss_getcred(rqst, crp, flavorp));
191133362Sobrien
192133362Sobrien	default:
193133362Sobrien		return (FALSE);
194208341Smarius	}
195159769Sobrien}
196159769Sobrien
197133362Sobrien