18360efbdSAlfred Perlstein /* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ 28360efbdSAlfred Perlstein 32e322d37SHiroki Sato /*- 4*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 5*8a16b7a1SPedro F. Giffuni * 62e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 72e322d37SHiroki Sato * All rights reserved. 899064799SGarrett Wollman * 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. 1999064799SGarrett Wollman * 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. 3199064799SGarrett Wollman */ 32ad133ed6SBill Paul /* 33ad133ed6SBill Paul * Copyright (c) 1986-1991 by Sun Microsystems Inc. 34ad133ed6SBill Paul */ 3599064799SGarrett Wollman 36a986ef57SDavid E. O'Brien #if defined(LIBC_SCCS) && !defined(lint) 37a986ef57SDavid E. O'Brien #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" 38ad133ed6SBill Paul static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; 39c4473420SPeter Wemm #endif 40d3d20c82SDavid E. O'Brien #include <sys/cdefs.h> 41d3d20c82SDavid E. O'Brien __FBSDID("$FreeBSD$"); 4299064799SGarrett Wollman 4399064799SGarrett Wollman /* 44ad133ed6SBill Paul * svc_auth.c, Server-side rpc authenticator interface. 4599064799SGarrett Wollman * 4699064799SGarrett Wollman */ 4799064799SGarrett Wollman 488360efbdSAlfred Perlstein #include "namespace.h" 499f5afc13SIan Dowse #include "reentrant.h" 50ad133ed6SBill Paul #include <sys/types.h> 518360efbdSAlfred Perlstein #include <rpc/rpc.h> 528360efbdSAlfred Perlstein #include <stdlib.h> 538360efbdSAlfred Perlstein #include "un-namespace.h" 54235baf26SDaniel Eischen #include "mt_misc.h" 5599064799SGarrett Wollman 5699064799SGarrett Wollman /* 5799064799SGarrett Wollman * svcauthsw is the bdevsw of server side authentication. 5899064799SGarrett Wollman * 5999064799SGarrett Wollman * Server side authenticators are called from authenticate by 6099064799SGarrett Wollman * using the client auth struct flavor field to index into svcauthsw. 6199064799SGarrett Wollman * The server auth flavors must implement a routine that looks 6299064799SGarrett Wollman * like: 6399064799SGarrett Wollman * 6499064799SGarrett Wollman * enum auth_stat 6599064799SGarrett Wollman * flavorx_auth(rqst, msg) 668360efbdSAlfred Perlstein * struct svc_req *rqst; 678360efbdSAlfred Perlstein * struct rpc_msg *msg; 6899064799SGarrett Wollman * 6999064799SGarrett Wollman */ 7099064799SGarrett Wollman 71ad133ed6SBill Paul /* declarations to allow servers to specify new authentication flavors */ 72ad133ed6SBill Paul struct authsvc { 73ad133ed6SBill Paul int flavor; 74c05ac53bSDavid E. O'Brien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 75ad133ed6SBill Paul struct authsvc *next; 7699064799SGarrett Wollman }; 77ad133ed6SBill Paul static struct authsvc *Auths = NULL; 7899064799SGarrett Wollman 794efa8f3eSDoug Rabson struct svc_auth_ops svc_auth_null_ops; 808f55a568SDoug Rabson 8199064799SGarrett Wollman /* 8299064799SGarrett Wollman * The call rpc message, msg has been obtained from the wire. The msg contains 8399064799SGarrett Wollman * the raw form of credentials and verifiers. authenticate returns AUTH_OK 8499064799SGarrett Wollman * if the msg is successfully authenticated. If AUTH_OK then the routine also 8599064799SGarrett Wollman * does the following things: 8699064799SGarrett Wollman * set rqst->rq_xprt->verf to the appropriate response verifier; 8799064799SGarrett Wollman * sets rqst->rq_client_cred to the "cooked" form of the credentials. 8899064799SGarrett Wollman * 8999064799SGarrett Wollman * NB: rqst->rq_cxprt->verf must be pre-alloctaed; 9099064799SGarrett Wollman * its length is set appropriately. 9199064799SGarrett Wollman * 9299064799SGarrett Wollman * The caller still owns and is responsible for msg->u.cmb.cred and 9399064799SGarrett Wollman * msg->u.cmb.verf. The authentication system retains ownership of 9499064799SGarrett Wollman * rqst->rq_client_cred, the cooked credentials. 9599064799SGarrett Wollman * 9699064799SGarrett Wollman * There is an assumption that any flavour less than AUTH_NULL is 9799064799SGarrett Wollman * invalid. 9899064799SGarrett Wollman */ 9999064799SGarrett Wollman enum auth_stat 100587cf682SCraig Rodrigues _authenticate(struct svc_req *rqst, struct rpc_msg *msg) 10199064799SGarrett Wollman { 1028360efbdSAlfred Perlstein int cred_flavor; 1038360efbdSAlfred Perlstein struct authsvc *asp; 1048360efbdSAlfred Perlstein enum auth_stat dummy; 1058360efbdSAlfred Perlstein 1068360efbdSAlfred Perlstein /* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ 10799064799SGarrett Wollman 10899064799SGarrett Wollman rqst->rq_cred = msg->rm_call.cb_cred; 1098f55a568SDoug Rabson SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops; 1108f55a568SDoug Rabson SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL; 11199064799SGarrett Wollman rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 11299064799SGarrett Wollman rqst->rq_xprt->xp_verf.oa_length = 0; 11399064799SGarrett Wollman cred_flavor = rqst->rq_cred.oa_flavor; 114ad133ed6SBill Paul switch (cred_flavor) { 115ad133ed6SBill Paul case AUTH_NULL: 1168360efbdSAlfred Perlstein dummy = _svcauth_null(rqst, msg); 1178360efbdSAlfred Perlstein return (dummy); 1188360efbdSAlfred Perlstein case AUTH_SYS: 1198360efbdSAlfred Perlstein dummy = _svcauth_unix(rqst, msg); 1208360efbdSAlfred Perlstein return (dummy); 121ad133ed6SBill Paul case AUTH_SHORT: 1228360efbdSAlfred Perlstein dummy = _svcauth_short(rqst, msg); 1238360efbdSAlfred Perlstein return (dummy); 124ad133ed6SBill Paul #ifdef DES_BUILTIN 125ad133ed6SBill Paul case AUTH_DES: 1268360efbdSAlfred Perlstein dummy = _svcauth_des(rqst, msg); 1278360efbdSAlfred Perlstein return (dummy); 128ad133ed6SBill Paul #endif 1298360efbdSAlfred Perlstein default: 1308360efbdSAlfred Perlstein break; 131ad133ed6SBill Paul } 132ad133ed6SBill Paul 133ad133ed6SBill Paul /* flavor doesn't match any of the builtin types, so try new ones */ 1348360efbdSAlfred Perlstein mutex_lock(&authsvc_lock); 135ad133ed6SBill Paul for (asp = Auths; asp; asp = asp->next) { 136ad133ed6SBill Paul if (asp->flavor == cred_flavor) { 137ad133ed6SBill Paul enum auth_stat as; 138ad133ed6SBill Paul 139ad133ed6SBill Paul as = (*asp->handler)(rqst, msg); 1408360efbdSAlfred Perlstein mutex_unlock(&authsvc_lock); 141ad133ed6SBill Paul return (as); 142ad133ed6SBill Paul } 14399064799SGarrett Wollman } 1448360efbdSAlfred Perlstein mutex_unlock(&authsvc_lock); 14599064799SGarrett Wollman 14699064799SGarrett Wollman return (AUTH_REJECTEDCRED); 14799064799SGarrett Wollman } 14899064799SGarrett Wollman 1498f55a568SDoug Rabson /* 1508f55a568SDoug Rabson * A set of null auth methods used by any authentication protocols 1518f55a568SDoug Rabson * that don't need to inspect or modify the message body. 1528f55a568SDoug Rabson */ 1538f55a568SDoug Rabson static bool_t 15468895e38SCraig Rodrigues svcauth_null_wrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) 1558f55a568SDoug Rabson { 1568f55a568SDoug Rabson 1578f55a568SDoug Rabson return (xdr_func(xdrs, xdr_ptr)); 1588f55a568SDoug Rabson } 1598f55a568SDoug Rabson 1604efa8f3eSDoug Rabson struct svc_auth_ops svc_auth_null_ops = { 1618f55a568SDoug Rabson svcauth_null_wrap, 1628f55a568SDoug Rabson svcauth_null_wrap, 1638f55a568SDoug Rabson }; 1648f55a568SDoug Rabson 165ad133ed6SBill Paul /*ARGSUSED*/ 16699064799SGarrett Wollman enum auth_stat 16768895e38SCraig Rodrigues _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg) 16899064799SGarrett Wollman { 16999064799SGarrett Wollman return (AUTH_OK); 17099064799SGarrett Wollman } 171ad133ed6SBill Paul 172ad133ed6SBill Paul /* 173ad133ed6SBill Paul * Allow the rpc service to register new authentication types that it is 174ad133ed6SBill Paul * prepared to handle. When an authentication flavor is registered, 175ad133ed6SBill Paul * the flavor is checked against already registered values. If not 176ad133ed6SBill Paul * registered, then a new Auths entry is added on the list. 177ad133ed6SBill Paul * 178ad133ed6SBill Paul * There is no provision to delete a registration once registered. 179ad133ed6SBill Paul * 180ad133ed6SBill Paul * This routine returns: 181ad133ed6SBill Paul * 0 if registration successful 182ad133ed6SBill Paul * 1 if flavor already registered 183ad133ed6SBill Paul * -1 if can't register (errno set) 184ad133ed6SBill Paul */ 185ad133ed6SBill Paul 186ad133ed6SBill Paul int 18768895e38SCraig Rodrigues svc_auth_reg(int cred_flavor, 18868895e38SCraig Rodrigues enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *)) 189ad133ed6SBill Paul { 1908360efbdSAlfred Perlstein struct authsvc *asp; 191ad133ed6SBill Paul 192ad133ed6SBill Paul switch (cred_flavor) { 193ad133ed6SBill Paul case AUTH_NULL: 1948360efbdSAlfred Perlstein case AUTH_SYS: 195ad133ed6SBill Paul case AUTH_SHORT: 196ad133ed6SBill Paul #ifdef DES_BUILTIN 197ad133ed6SBill Paul case AUTH_DES: 198ad133ed6SBill Paul #endif 199ad133ed6SBill Paul /* already registered */ 200ad133ed6SBill Paul return (1); 201ad133ed6SBill Paul 202ad133ed6SBill Paul default: 2038360efbdSAlfred Perlstein mutex_lock(&authsvc_lock); 204ad133ed6SBill Paul for (asp = Auths; asp; asp = asp->next) { 205ad133ed6SBill Paul if (asp->flavor == cred_flavor) { 206ad133ed6SBill Paul /* already registered */ 2078360efbdSAlfred Perlstein mutex_unlock(&authsvc_lock); 208ad133ed6SBill Paul return (1); 209ad133ed6SBill Paul } 210ad133ed6SBill Paul } 211ad133ed6SBill Paul 212ad133ed6SBill Paul /* this is a new one, so go ahead and register it */ 2138360efbdSAlfred Perlstein asp = mem_alloc(sizeof (*asp)); 214ad133ed6SBill Paul if (asp == NULL) { 2158360efbdSAlfred Perlstein mutex_unlock(&authsvc_lock); 216ad133ed6SBill Paul return (-1); 217ad133ed6SBill Paul } 218ad133ed6SBill Paul asp->flavor = cred_flavor; 219ad133ed6SBill Paul asp->handler = handler; 220ad133ed6SBill Paul asp->next = Auths; 221ad133ed6SBill Paul Auths = asp; 2228360efbdSAlfred Perlstein mutex_unlock(&authsvc_lock); 223ad133ed6SBill Paul break; 224ad133ed6SBill Paul } 225ad133ed6SBill Paul return (0); 226ad133ed6SBill Paul } 227