svc_auth.c revision 258578
174462Salfred/* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ 274462Salfred 3258578Shrs/*- 4258578Shrs * Copyright (c) 2009, Sun Microsystems, Inc. 5258578Shrs * All rights reserved. 6258578Shrs * 7258578Shrs * Redistribution and use in source and binary forms, with or without 8258578Shrs * modification, are permitted provided that the following conditions are met: 9258578Shrs * - Redistributions of source code must retain the above copyright notice, 10258578Shrs * this list of conditions and the following disclaimer. 11258578Shrs * - Redistributions in binary form must reproduce the above copyright notice, 12258578Shrs * this list of conditions and the following disclaimer in the documentation 13258578Shrs * and/or other materials provided with the distribution. 14258578Shrs * - Neither the name of Sun Microsystems, Inc. nor the names of its 15258578Shrs * contributors may be used to endorse or promote products derived 16258578Shrs * from this software without specific prior written permission. 1726221Swpaul * 18258578Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19258578Shrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20258578Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21258578Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22258578Shrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23258578Shrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24258578Shrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25258578Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26258578Shrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27258578Shrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28258578Shrs * POSSIBILITY OF SUCH DAMAGE. 291901Swollman */ 3026221Swpaul/* 3126221Swpaul * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3226221Swpaul */ 331901Swollman 34136581Sobrien#if defined(LIBC_SCCS) && !defined(lint) 35136581Sobrien#ident "@(#)svc_auth.c 1.16 94/04/24 SMI" 3626221Swpaulstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; 371901Swollman#endif 3892990Sobrien#include <sys/cdefs.h> 3992990Sobrien__FBSDID("$FreeBSD: head/lib/libc/rpc/svc_auth.c 258578 2013-11-25 19:04:36Z hrs $"); 401901Swollman 411901Swollman/* 4226221Swpaul * svc_auth.c, Server-side rpc authenticator interface. 431901Swollman * 441901Swollman */ 451901Swollman 4675094Siedowse#include "namespace.h" 4774462Salfred#include "reentrant.h" 4874462Salfred#include <sys/types.h> 4974462Salfred#include <rpc/rpc.h> 5026221Swpaul#include <stdlib.h> 5174462Salfred#include "un-namespace.h" 52156090Sdeischen#include "mt_misc.h" 531901Swollman 541901Swollman/* 558870Srgrimes * svcauthsw is the bdevsw of server side authentication. 568870Srgrimes * 571901Swollman * Server side authenticators are called from authenticate by 581901Swollman * using the client auth struct flavor field to index into svcauthsw. 598870Srgrimes * The server auth flavors must implement a routine that looks 608870Srgrimes * like: 618870Srgrimes * 621901Swollman * enum auth_stat 631901Swollman * flavorx_auth(rqst, msg) 6474462Salfred * struct svc_req *rqst; 6574462Salfred * struct rpc_msg *msg; 661901Swollman * 671901Swollman */ 681901Swollman 6926221Swpaul/* declarations to allow servers to specify new authentication flavors */ 7026221Swpaulstruct authsvc { 7126221Swpaul int flavor; 7292905Sobrien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 7326221Swpaul struct authsvc *next; 741901Swollman}; 7526221Swpaulstatic struct authsvc *Auths = NULL; 761901Swollman 77182891Sdfrstruct svc_auth_ops svc_auth_null_ops; 78181344Sdfr 791901Swollman/* 801901Swollman * The call rpc message, msg has been obtained from the wire. The msg contains 811901Swollman * the raw form of credentials and verifiers. authenticate returns AUTH_OK 821901Swollman * if the msg is successfully authenticated. If AUTH_OK then the routine also 831901Swollman * does the following things: 841901Swollman * set rqst->rq_xprt->verf to the appropriate response verifier; 851901Swollman * sets rqst->rq_client_cred to the "cooked" form of the credentials. 861901Swollman * 871901Swollman * NB: rqst->rq_cxprt->verf must be pre-alloctaed; 881901Swollman * its length is set appropriately. 891901Swollman * 901901Swollman * The caller still owns and is responsible for msg->u.cmb.cred and 911901Swollman * msg->u.cmb.verf. The authentication system retains ownership of 921901Swollman * rqst->rq_client_cred, the cooked credentials. 931901Swollman * 941901Swollman * There is an assumption that any flavour less than AUTH_NULL is 951901Swollman * invalid. 961901Swollman */ 971901Swollmanenum auth_stat 981901Swollman_authenticate(rqst, msg) 9974462Salfred struct svc_req *rqst; 1001901Swollman struct rpc_msg *msg; 1011901Swollman{ 10274462Salfred int cred_flavor; 10374462Salfred struct authsvc *asp; 10474462Salfred enum auth_stat dummy; 1051901Swollman 10674462Salfred/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ 10774462Salfred 1081901Swollman rqst->rq_cred = msg->rm_call.cb_cred; 109181344Sdfr SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops; 110181344Sdfr SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL; 1111901Swollman rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 1121901Swollman rqst->rq_xprt->xp_verf.oa_length = 0; 1131901Swollman cred_flavor = rqst->rq_cred.oa_flavor; 11426221Swpaul switch (cred_flavor) { 11526221Swpaul case AUTH_NULL: 11674462Salfred dummy = _svcauth_null(rqst, msg); 11774462Salfred return (dummy); 11874462Salfred case AUTH_SYS: 11974462Salfred dummy = _svcauth_unix(rqst, msg); 12074462Salfred return (dummy); 12126221Swpaul case AUTH_SHORT: 12274462Salfred dummy = _svcauth_short(rqst, msg); 12374462Salfred return (dummy); 12426221Swpaul#ifdef DES_BUILTIN 12526221Swpaul case AUTH_DES: 12674462Salfred dummy = _svcauth_des(rqst, msg); 12774462Salfred return (dummy); 12826221Swpaul#endif 12974462Salfred default: 13074462Salfred break; 1311901Swollman } 1321901Swollman 13326221Swpaul /* flavor doesn't match any of the builtin types, so try new ones */ 13474462Salfred mutex_lock(&authsvc_lock); 13526221Swpaul for (asp = Auths; asp; asp = asp->next) { 13626221Swpaul if (asp->flavor == cred_flavor) { 13726221Swpaul enum auth_stat as; 13826221Swpaul 13926221Swpaul as = (*asp->handler)(rqst, msg); 14074462Salfred mutex_unlock(&authsvc_lock); 14126221Swpaul return (as); 14226221Swpaul } 14326221Swpaul } 14474462Salfred mutex_unlock(&authsvc_lock); 14526221Swpaul 1461901Swollman return (AUTH_REJECTEDCRED); 1471901Swollman} 1481901Swollman 149181344Sdfr/* 150181344Sdfr * A set of null auth methods used by any authentication protocols 151181344Sdfr * that don't need to inspect or modify the message body. 152181344Sdfr */ 153181344Sdfrstatic bool_t 154181344Sdfrsvcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr) 155181344Sdfr SVCAUTH *auth; 156181344Sdfr XDR *xdrs; 157181344Sdfr xdrproc_t xdr_func; 158181344Sdfr caddr_t xdr_ptr; 159181344Sdfr{ 160181344Sdfr 161181344Sdfr return (xdr_func(xdrs, xdr_ptr)); 162181344Sdfr} 163181344Sdfr 164182891Sdfrstruct svc_auth_ops svc_auth_null_ops = { 165181344Sdfr svcauth_null_wrap, 166181344Sdfr svcauth_null_wrap, 167181344Sdfr}; 168181344Sdfr 16926221Swpaul/*ARGSUSED*/ 1701901Swollmanenum auth_stat 17126221Swpaul_svcauth_null(rqst, msg) 17226221Swpaul struct svc_req *rqst; 17326221Swpaul struct rpc_msg *msg; 1741901Swollman{ 1751901Swollman return (AUTH_OK); 1761901Swollman} 17726221Swpaul 17826221Swpaul/* 17926221Swpaul * Allow the rpc service to register new authentication types that it is 18026221Swpaul * prepared to handle. When an authentication flavor is registered, 18126221Swpaul * the flavor is checked against already registered values. If not 18226221Swpaul * registered, then a new Auths entry is added on the list. 18326221Swpaul * 18426221Swpaul * There is no provision to delete a registration once registered. 18526221Swpaul * 18626221Swpaul * This routine returns: 18726221Swpaul * 0 if registration successful 18826221Swpaul * 1 if flavor already registered 18926221Swpaul * -1 if can't register (errno set) 19026221Swpaul */ 19126221Swpaul 19226221Swpaulint 19326221Swpaulsvc_auth_reg(cred_flavor, handler) 19474462Salfred int cred_flavor; 19592905Sobrien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 19626221Swpaul{ 19774462Salfred struct authsvc *asp; 19826221Swpaul 19926221Swpaul switch (cred_flavor) { 20026221Swpaul case AUTH_NULL: 20174462Salfred case AUTH_SYS: 20226221Swpaul case AUTH_SHORT: 20326221Swpaul#ifdef DES_BUILTIN 20426221Swpaul case AUTH_DES: 20526221Swpaul#endif 20626221Swpaul /* already registered */ 20726221Swpaul return (1); 20826221Swpaul 20926221Swpaul default: 21074462Salfred mutex_lock(&authsvc_lock); 21126221Swpaul for (asp = Auths; asp; asp = asp->next) { 21226221Swpaul if (asp->flavor == cred_flavor) { 21326221Swpaul /* already registered */ 21474462Salfred mutex_unlock(&authsvc_lock); 21526221Swpaul return (1); 21626221Swpaul } 21726221Swpaul } 21826221Swpaul 21926221Swpaul /* this is a new one, so go ahead and register it */ 22074462Salfred asp = mem_alloc(sizeof (*asp)); 22126221Swpaul if (asp == NULL) { 22274462Salfred mutex_unlock(&authsvc_lock); 22326221Swpaul return (-1); 22426221Swpaul } 22526221Swpaul asp->flavor = cred_flavor; 22626221Swpaul asp->handler = handler; 22726221Swpaul asp->next = Auths; 22826221Swpaul Auths = asp; 22974462Salfred mutex_unlock(&authsvc_lock); 23026221Swpaul break; 23126221Swpaul } 23226221Swpaul return (0); 23326221Swpaul} 234