svc_auth.c revision 182891
174462Salfred/* $NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $ */ 274462Salfred 31901Swollman/* 41901Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 51901Swollman * unrestricted use provided that this legend is included on all tape 61901Swollman * media and as a part of the software program in whole or part. Users 71901Swollman * may copy or modify Sun RPC without charge, but are not authorized 81901Swollman * to license or distribute it to anyone else except as part of a product or 91901Swollman * program developed by the user. 1026221Swpaul * 111901Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 121901Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 131901Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1426221Swpaul * 151901Swollman * Sun RPC is provided with no support and without any obligation on the 161901Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 171901Swollman * modification or enhancement. 1826221Swpaul * 191901Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 201901Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 211901Swollman * OR ANY PART THEREOF. 2226221Swpaul * 231901Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 241901Swollman * or profits or other special, indirect and consequential damages, even if 251901Swollman * Sun has been advised of the possibility of such damages. 2626221Swpaul * 271901Swollman * Sun Microsystems, Inc. 281901Swollman * 2550 Garcia Avenue 291901Swollman * Mountain View, California 94043 301901Swollman */ 3126221Swpaul/* 3226221Swpaul * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3326221Swpaul */ 341901Swollman 35136581Sobrien#if defined(LIBC_SCCS) && !defined(lint) 36136581Sobrien#ident "@(#)svc_auth.c 1.16 94/04/24 SMI" 3726221Swpaulstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; 381901Swollman#endif 3992990Sobrien#include <sys/cdefs.h> 4092990Sobrien__FBSDID("$FreeBSD: head/lib/libc/rpc/svc_auth.c 182891 2008-09-09 14:15:55Z dfr $"); 411901Swollman 421901Swollman/* 4326221Swpaul * svc_auth.c, Server-side rpc authenticator interface. 441901Swollman * 451901Swollman */ 461901Swollman 4775094Siedowse#include "namespace.h" 4874462Salfred#include "reentrant.h" 4974462Salfred#include <sys/types.h> 5074462Salfred#include <rpc/rpc.h> 5126221Swpaul#include <stdlib.h> 5274462Salfred#include "un-namespace.h" 53156090Sdeischen#include "mt_misc.h" 541901Swollman 551901Swollman/* 568870Srgrimes * svcauthsw is the bdevsw of server side authentication. 578870Srgrimes * 581901Swollman * Server side authenticators are called from authenticate by 591901Swollman * using the client auth struct flavor field to index into svcauthsw. 608870Srgrimes * The server auth flavors must implement a routine that looks 618870Srgrimes * like: 628870Srgrimes * 631901Swollman * enum auth_stat 641901Swollman * flavorx_auth(rqst, msg) 6574462Salfred * struct svc_req *rqst; 6674462Salfred * struct rpc_msg *msg; 671901Swollman * 681901Swollman */ 691901Swollman 7026221Swpaul/* declarations to allow servers to specify new authentication flavors */ 7126221Swpaulstruct authsvc { 7226221Swpaul int flavor; 7392905Sobrien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 7426221Swpaul struct authsvc *next; 751901Swollman}; 7626221Swpaulstatic struct authsvc *Auths = NULL; 771901Swollman 78182891Sdfrstruct svc_auth_ops svc_auth_null_ops; 79181344Sdfr 801901Swollman/* 811901Swollman * The call rpc message, msg has been obtained from the wire. The msg contains 821901Swollman * the raw form of credentials and verifiers. authenticate returns AUTH_OK 831901Swollman * if the msg is successfully authenticated. If AUTH_OK then the routine also 841901Swollman * does the following things: 851901Swollman * set rqst->rq_xprt->verf to the appropriate response verifier; 861901Swollman * sets rqst->rq_client_cred to the "cooked" form of the credentials. 871901Swollman * 881901Swollman * NB: rqst->rq_cxprt->verf must be pre-alloctaed; 891901Swollman * its length is set appropriately. 901901Swollman * 911901Swollman * The caller still owns and is responsible for msg->u.cmb.cred and 921901Swollman * msg->u.cmb.verf. The authentication system retains ownership of 931901Swollman * rqst->rq_client_cred, the cooked credentials. 941901Swollman * 951901Swollman * There is an assumption that any flavour less than AUTH_NULL is 961901Swollman * invalid. 971901Swollman */ 981901Swollmanenum auth_stat 991901Swollman_authenticate(rqst, msg) 10074462Salfred struct svc_req *rqst; 1011901Swollman struct rpc_msg *msg; 1021901Swollman{ 10374462Salfred int cred_flavor; 10474462Salfred struct authsvc *asp; 10574462Salfred enum auth_stat dummy; 1061901Swollman 10774462Salfred/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ 10874462Salfred 1091901Swollman rqst->rq_cred = msg->rm_call.cb_cred; 110181344Sdfr SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops; 111181344Sdfr SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL; 1121901Swollman rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 1131901Swollman rqst->rq_xprt->xp_verf.oa_length = 0; 1141901Swollman cred_flavor = rqst->rq_cred.oa_flavor; 11526221Swpaul switch (cred_flavor) { 11626221Swpaul case AUTH_NULL: 11774462Salfred dummy = _svcauth_null(rqst, msg); 11874462Salfred return (dummy); 11974462Salfred case AUTH_SYS: 12074462Salfred dummy = _svcauth_unix(rqst, msg); 12174462Salfred return (dummy); 12226221Swpaul case AUTH_SHORT: 12374462Salfred dummy = _svcauth_short(rqst, msg); 12474462Salfred return (dummy); 12526221Swpaul#ifdef DES_BUILTIN 12626221Swpaul case AUTH_DES: 12774462Salfred dummy = _svcauth_des(rqst, msg); 12874462Salfred return (dummy); 12926221Swpaul#endif 13074462Salfred default: 13174462Salfred break; 1321901Swollman } 1331901Swollman 13426221Swpaul /* flavor doesn't match any of the builtin types, so try new ones */ 13574462Salfred mutex_lock(&authsvc_lock); 13626221Swpaul for (asp = Auths; asp; asp = asp->next) { 13726221Swpaul if (asp->flavor == cred_flavor) { 13826221Swpaul enum auth_stat as; 13926221Swpaul 14026221Swpaul as = (*asp->handler)(rqst, msg); 14174462Salfred mutex_unlock(&authsvc_lock); 14226221Swpaul return (as); 14326221Swpaul } 14426221Swpaul } 14574462Salfred mutex_unlock(&authsvc_lock); 14626221Swpaul 1471901Swollman return (AUTH_REJECTEDCRED); 1481901Swollman} 1491901Swollman 150181344Sdfr/* 151181344Sdfr * A set of null auth methods used by any authentication protocols 152181344Sdfr * that don't need to inspect or modify the message body. 153181344Sdfr */ 154181344Sdfrstatic bool_t 155181344Sdfrsvcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr) 156181344Sdfr SVCAUTH *auth; 157181344Sdfr XDR *xdrs; 158181344Sdfr xdrproc_t xdr_func; 159181344Sdfr caddr_t xdr_ptr; 160181344Sdfr{ 161181344Sdfr 162181344Sdfr return (xdr_func(xdrs, xdr_ptr)); 163181344Sdfr} 164181344Sdfr 165182891Sdfrstruct svc_auth_ops svc_auth_null_ops = { 166181344Sdfr svcauth_null_wrap, 167181344Sdfr svcauth_null_wrap, 168181344Sdfr}; 169181344Sdfr 17026221Swpaul/*ARGSUSED*/ 1711901Swollmanenum auth_stat 17226221Swpaul_svcauth_null(rqst, msg) 17326221Swpaul struct svc_req *rqst; 17426221Swpaul struct rpc_msg *msg; 1751901Swollman{ 1761901Swollman return (AUTH_OK); 1771901Swollman} 17826221Swpaul 17926221Swpaul/* 18026221Swpaul * Allow the rpc service to register new authentication types that it is 18126221Swpaul * prepared to handle. When an authentication flavor is registered, 18226221Swpaul * the flavor is checked against already registered values. If not 18326221Swpaul * registered, then a new Auths entry is added on the list. 18426221Swpaul * 18526221Swpaul * There is no provision to delete a registration once registered. 18626221Swpaul * 18726221Swpaul * This routine returns: 18826221Swpaul * 0 if registration successful 18926221Swpaul * 1 if flavor already registered 19026221Swpaul * -1 if can't register (errno set) 19126221Swpaul */ 19226221Swpaul 19326221Swpaulint 19426221Swpaulsvc_auth_reg(cred_flavor, handler) 19574462Salfred int cred_flavor; 19692905Sobrien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 19726221Swpaul{ 19874462Salfred struct authsvc *asp; 19926221Swpaul 20026221Swpaul switch (cred_flavor) { 20126221Swpaul case AUTH_NULL: 20274462Salfred case AUTH_SYS: 20326221Swpaul case AUTH_SHORT: 20426221Swpaul#ifdef DES_BUILTIN 20526221Swpaul case AUTH_DES: 20626221Swpaul#endif 20726221Swpaul /* already registered */ 20826221Swpaul return (1); 20926221Swpaul 21026221Swpaul default: 21174462Salfred mutex_lock(&authsvc_lock); 21226221Swpaul for (asp = Auths; asp; asp = asp->next) { 21326221Swpaul if (asp->flavor == cred_flavor) { 21426221Swpaul /* already registered */ 21574462Salfred mutex_unlock(&authsvc_lock); 21626221Swpaul return (1); 21726221Swpaul } 21826221Swpaul } 21926221Swpaul 22026221Swpaul /* this is a new one, so go ahead and register it */ 22174462Salfred asp = mem_alloc(sizeof (*asp)); 22226221Swpaul if (asp == NULL) { 22374462Salfred mutex_unlock(&authsvc_lock); 22426221Swpaul return (-1); 22526221Swpaul } 22626221Swpaul asp->flavor = cred_flavor; 22726221Swpaul asp->handler = handler; 22826221Swpaul asp->next = Auths; 22926221Swpaul Auths = asp; 23074462Salfred mutex_unlock(&authsvc_lock); 23126221Swpaul break; 23226221Swpaul } 23326221Swpaul return (0); 23426221Swpaul} 235