1dfdcada3SDoug Rabson /* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ 2dfdcada3SDoug Rabson 32e322d37SHiroki Sato /*- 451369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 551369649SPedro F. Giffuni * 62e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 72e322d37SHiroki Sato * All rights reserved. 8dfdcada3SDoug Rabson * 92e322d37SHiroki Sato * Redistribution and use in source and binary forms, with or without 102e322d37SHiroki Sato * modification, are permitted provided that the following conditions are met: 112e322d37SHiroki Sato * - Redistributions of source code must retain the above copyright notice, 122e322d37SHiroki Sato * this list of conditions and the following disclaimer. 132e322d37SHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice, 142e322d37SHiroki Sato * this list of conditions and the following disclaimer in the documentation 152e322d37SHiroki Sato * and/or other materials provided with the distribution. 162e322d37SHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its 172e322d37SHiroki Sato * contributors may be used to endorse or promote products derived 182e322d37SHiroki Sato * from this software without specific prior written permission. 19dfdcada3SDoug Rabson * 202e322d37SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 212e322d37SHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 222e322d37SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 232e322d37SHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 242e322d37SHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 252e322d37SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 262e322d37SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 272e322d37SHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 282e322d37SHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 292e322d37SHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 302e322d37SHiroki Sato * POSSIBILITY OF SUCH DAMAGE. 31dfdcada3SDoug Rabson */ 32dfdcada3SDoug Rabson /* 33dfdcada3SDoug Rabson * Copyright (c) 1986-1991 by Sun Microsystems Inc. 34dfdcada3SDoug Rabson */ 35dfdcada3SDoug Rabson 36dfdcada3SDoug Rabson /* 37dfdcada3SDoug Rabson * svc_auth.c, Server-side rpc authenticator interface. 38dfdcada3SDoug Rabson * 39dfdcada3SDoug Rabson */ 40dfdcada3SDoug Rabson 41dfdcada3SDoug Rabson #include <sys/param.h> 42dfdcada3SDoug Rabson #include <sys/lock.h> 43dfdcada3SDoug Rabson #include <sys/mutex.h> 446a76d35cSRick Macklem #include <sys/proc.h> 45dfdcada3SDoug Rabson #include <sys/systm.h> 46dab07fbcSRobert Watson #include <sys/jail.h> 47dfdcada3SDoug Rabson #include <sys/ucred.h> 48dfdcada3SDoug Rabson 49dfdcada3SDoug Rabson #include <rpc/rpc.h> 50ab0c29afSRick Macklem #include <rpc/rpcsec_tls.h> 51dfdcada3SDoug Rabson 52a9148abdSDoug Rabson static enum auth_stat (*_svcauth_rpcsec_gss)(struct svc_req *, 53a9148abdSDoug Rabson struct rpc_msg *) = NULL; 54a9148abdSDoug Rabson static int (*_svcauth_rpcsec_gss_getcred)(struct svc_req *, 55a9148abdSDoug Rabson struct ucred **, int *); 56a9148abdSDoug Rabson 5720d728b5SMark Johnston static const struct svc_auth_ops svc_auth_null_ops; 58a9148abdSDoug Rabson 59dfdcada3SDoug Rabson /* 60dfdcada3SDoug Rabson * The call rpc message, msg has been obtained from the wire. The msg contains 61dfdcada3SDoug Rabson * the raw form of credentials and verifiers. authenticate returns AUTH_OK 62dfdcada3SDoug Rabson * if the msg is successfully authenticated. If AUTH_OK then the routine also 63dfdcada3SDoug Rabson * does the following things: 64dfdcada3SDoug Rabson * set rqst->rq_xprt->verf to the appropriate response verifier; 65dfdcada3SDoug Rabson * sets rqst->rq_client_cred to the "cooked" form of the credentials. 66dfdcada3SDoug Rabson * 675c49e1cbSGordon Bergling * NB: rqst->rq_cxprt->verf must be pre-allocated; 68dfdcada3SDoug Rabson * its length is set appropriately. 69dfdcada3SDoug Rabson * 70dfdcada3SDoug Rabson * The caller still owns and is responsible for msg->u.cmb.cred and 71dfdcada3SDoug Rabson * msg->u.cmb.verf. The authentication system retains ownership of 72dfdcada3SDoug Rabson * rqst->rq_client_cred, the cooked credentials. 73dfdcada3SDoug Rabson * 74dfdcada3SDoug Rabson * There is an assumption that any flavour less than AUTH_NULL is 75dfdcada3SDoug Rabson * invalid. 76dfdcada3SDoug Rabson */ 77dfdcada3SDoug Rabson enum auth_stat 78dfdcada3SDoug Rabson _authenticate(struct svc_req *rqst, struct rpc_msg *msg) 79dfdcada3SDoug Rabson { 80dfdcada3SDoug Rabson int cred_flavor; 81dfdcada3SDoug Rabson enum auth_stat dummy; 82dfdcada3SDoug Rabson 83dfdcada3SDoug Rabson rqst->rq_cred = msg->rm_call.cb_cred; 84a9148abdSDoug Rabson rqst->rq_auth.svc_ah_ops = &svc_auth_null_ops; 85a9148abdSDoug Rabson rqst->rq_auth.svc_ah_private = NULL; 86dfdcada3SDoug Rabson cred_flavor = rqst->rq_cred.oa_flavor; 87dfdcada3SDoug Rabson switch (cred_flavor) { 88dfdcada3SDoug Rabson case AUTH_NULL: 89dfdcada3SDoug Rabson dummy = _svcauth_null(rqst, msg); 90dfdcada3SDoug Rabson return (dummy); 91dfdcada3SDoug Rabson case AUTH_SYS: 92ab0c29afSRick Macklem if ((rqst->rq_xprt->xp_tls & RPCTLS_FLAGS_DISABLED) != 0) 93ab0c29afSRick Macklem return (AUTH_REJECTEDCRED); 94dfdcada3SDoug Rabson dummy = _svcauth_unix(rqst, msg); 95dfdcada3SDoug Rabson return (dummy); 96dfdcada3SDoug Rabson case AUTH_SHORT: 97ab0c29afSRick Macklem if ((rqst->rq_xprt->xp_tls & RPCTLS_FLAGS_DISABLED) != 0) 98ab0c29afSRick Macklem return (AUTH_REJECTEDCRED); 99dfdcada3SDoug Rabson dummy = _svcauth_short(rqst, msg); 100dfdcada3SDoug Rabson return (dummy); 101a9148abdSDoug Rabson case RPCSEC_GSS: 102ab0c29afSRick Macklem if ((rqst->rq_xprt->xp_tls & RPCTLS_FLAGS_DISABLED) != 0) 103ab0c29afSRick Macklem return (AUTH_REJECTEDCRED); 104a9148abdSDoug Rabson if (!_svcauth_rpcsec_gss) 105a9148abdSDoug Rabson return (AUTH_REJECTEDCRED); 106a9148abdSDoug Rabson dummy = _svcauth_rpcsec_gss(rqst, msg); 107a9148abdSDoug Rabson return (dummy); 108ab0c29afSRick Macklem case AUTH_TLS: 109ab0c29afSRick Macklem dummy = _svcauth_rpcsec_tls(rqst, msg); 110ab0c29afSRick Macklem return (dummy); 111dfdcada3SDoug Rabson default: 112dfdcada3SDoug Rabson break; 113dfdcada3SDoug Rabson } 114dfdcada3SDoug Rabson 115dfdcada3SDoug Rabson return (AUTH_REJECTEDCRED); 116dfdcada3SDoug Rabson } 117dfdcada3SDoug Rabson 118a9148abdSDoug Rabson /* 119a9148abdSDoug Rabson * A set of null auth methods used by any authentication protocols 120a9148abdSDoug Rabson * that don't need to inspect or modify the message body. 121a9148abdSDoug Rabson */ 122a9148abdSDoug Rabson static bool_t 123a9148abdSDoug Rabson svcauth_null_wrap(SVCAUTH *auth, struct mbuf **mp) 124a9148abdSDoug Rabson { 125a9148abdSDoug Rabson 126a9148abdSDoug Rabson return (TRUE); 127a9148abdSDoug Rabson } 128a9148abdSDoug Rabson 129a9148abdSDoug Rabson static bool_t 130a9148abdSDoug Rabson svcauth_null_unwrap(SVCAUTH *auth, struct mbuf **mp) 131a9148abdSDoug Rabson { 132a9148abdSDoug Rabson 133a9148abdSDoug Rabson return (TRUE); 134a9148abdSDoug Rabson } 135a9148abdSDoug Rabson 136a9148abdSDoug Rabson static void 137a9148abdSDoug Rabson svcauth_null_release(SVCAUTH *auth) 138a9148abdSDoug Rabson { 139a9148abdSDoug Rabson 140a9148abdSDoug Rabson } 141a9148abdSDoug Rabson 14220d728b5SMark Johnston static const struct svc_auth_ops svc_auth_null_ops = { 14320d728b5SMark Johnston .svc_ah_wrap = svcauth_null_wrap, 14420d728b5SMark Johnston .svc_ah_unwrap = svcauth_null_unwrap, 14520d728b5SMark Johnston .svc_ah_release = svcauth_null_release, 146a9148abdSDoug Rabson }; 147a9148abdSDoug Rabson 148dfdcada3SDoug Rabson /*ARGSUSED*/ 149dfdcada3SDoug Rabson enum auth_stat 150dfdcada3SDoug Rabson _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg) 151dfdcada3SDoug Rabson { 152a9148abdSDoug Rabson 153a9148abdSDoug Rabson rqst->rq_verf = _null_auth; 154dfdcada3SDoug Rabson return (AUTH_OK); 155dfdcada3SDoug Rabson } 156dfdcada3SDoug Rabson 157dfdcada3SDoug Rabson int 158a9148abdSDoug Rabson svc_auth_reg(int flavor, 159a9148abdSDoug Rabson enum auth_stat (*svcauth)(struct svc_req *, struct rpc_msg *), 160a9148abdSDoug Rabson int (*getcred)(struct svc_req *, struct ucred **, int *)) 161dfdcada3SDoug Rabson { 162a9148abdSDoug Rabson 163a9148abdSDoug Rabson if (flavor == RPCSEC_GSS) { 164a9148abdSDoug Rabson _svcauth_rpcsec_gss = svcauth; 165a9148abdSDoug Rabson _svcauth_rpcsec_gss_getcred = getcred; 166a9148abdSDoug Rabson } 167a9148abdSDoug Rabson return (TRUE); 168a9148abdSDoug Rabson } 169a9148abdSDoug Rabson 170a9148abdSDoug Rabson int 171a9148abdSDoug Rabson svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp) 172a9148abdSDoug Rabson { 173a9148abdSDoug Rabson struct ucred *cr = NULL; 174838d9858SBrooks Davis int flavor; 175dfdcada3SDoug Rabson struct xucred *xcr; 176ab0c29afSRick Macklem SVCXPRT *xprt = rqst->rq_xprt; 177dfdcada3SDoug Rabson 178dfdcada3SDoug Rabson flavor = rqst->rq_cred.oa_flavor; 179dfdcada3SDoug Rabson if (flavorp) 180dfdcada3SDoug Rabson *flavorp = flavor; 181dfdcada3SDoug Rabson 182ab0c29afSRick Macklem /* 183ab0c29afSRick Macklem * If there are credentials acquired via a TLS 184ab0c29afSRick Macklem * certificate for this TCP connection, use those 185ab0c29afSRick Macklem * instead of what is in the RPC header. 186ab0c29afSRick Macklem */ 187ab0c29afSRick Macklem if ((xprt->xp_tls & (RPCTLS_FLAGS_CERTUSER | 188ab0c29afSRick Macklem RPCTLS_FLAGS_DISABLED)) == RPCTLS_FLAGS_CERTUSER && 189ab0c29afSRick Macklem flavor == AUTH_UNIX) { 190*cfbe7a62SOlivier Certner if (xprt->xp_ngrps <= 0) 191*cfbe7a62SOlivier Certner return (FALSE); 192ab0c29afSRick Macklem cr = crget(); 193ab0c29afSRick Macklem cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xprt->xp_uid; 194ab0c29afSRick Macklem crsetgroups(cr, xprt->xp_ngrps, xprt->xp_gidp); 195*cfbe7a62SOlivier Certner cr->cr_rgid = cr->cr_svgid = cr->cr_gid; 1966a76d35cSRick Macklem cr->cr_prison = curthread->td_ucred->cr_prison; 197ab0c29afSRick Macklem prison_hold(cr->cr_prison); 198ab0c29afSRick Macklem *crp = cr; 199ab0c29afSRick Macklem return (TRUE); 200ab0c29afSRick Macklem } 201ab0c29afSRick Macklem 202dfdcada3SDoug Rabson switch (flavor) { 203dfdcada3SDoug Rabson case AUTH_UNIX: 204dfdcada3SDoug Rabson xcr = (struct xucred *) rqst->rq_clntcred; 205*cfbe7a62SOlivier Certner if (xcr->cr_ngroups <= 0) 206*cfbe7a62SOlivier Certner return (FALSE); 207a9148abdSDoug Rabson cr = crget(); 208dfdcada3SDoug Rabson cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid; 209838d9858SBrooks Davis crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups); 210*cfbe7a62SOlivier Certner cr->cr_rgid = cr->cr_svgid = cr->cr_gid; 2116a76d35cSRick Macklem cr->cr_prison = curthread->td_ucred->cr_prison; 212dab07fbcSRobert Watson prison_hold(cr->cr_prison); 213a9148abdSDoug Rabson *crp = cr; 214dfdcada3SDoug Rabson return (TRUE); 215dfdcada3SDoug Rabson 216a9148abdSDoug Rabson case RPCSEC_GSS: 217a9148abdSDoug Rabson if (!_svcauth_rpcsec_gss_getcred) 218a9148abdSDoug Rabson return (FALSE); 219a9148abdSDoug Rabson return (_svcauth_rpcsec_gss_getcred(rqst, crp, flavorp)); 220a9148abdSDoug Rabson 221dfdcada3SDoug Rabson default: 222dfdcada3SDoug Rabson return (FALSE); 223dfdcada3SDoug Rabson } 224dfdcada3SDoug Rabson } 225dfdcada3SDoug Rabson 226