svc_auth.c revision 75094
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 3574462Salfred/* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */ 3626221Swpaul 3774462Salfred#if 0 3826221Swpaul#if !defined(lint) && defined(SCCSIDS) 3926221Swpaulstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro"; 4074462Salfredstatic const char rcsid[] = "$FreeBSD: head/lib/libc/rpc/svc_auth.c 75094 2001-04-02 21:41:44Z iedowse $"; 411901Swollman#endif 4255206Speter#endif 431901Swollman 441901Swollman/* 4526221Swpaul * svc_auth.c, Server-side rpc authenticator interface. 461901Swollman * 471901Swollman */ 481901Swollman 4975094Siedowse#include "namespace.h" 5074462Salfred#include "reentrant.h" 5174462Salfred#include <sys/types.h> 5274462Salfred#include <rpc/rpc.h> 5326221Swpaul#include <stdlib.h> 5474462Salfred#include "un-namespace.h" 551901Swollman 561901Swollman/* 578870Srgrimes * svcauthsw is the bdevsw of server side authentication. 588870Srgrimes * 591901Swollman * Server side authenticators are called from authenticate by 601901Swollman * using the client auth struct flavor field to index into svcauthsw. 618870Srgrimes * The server auth flavors must implement a routine that looks 628870Srgrimes * like: 638870Srgrimes * 641901Swollman * enum auth_stat 651901Swollman * flavorx_auth(rqst, msg) 6674462Salfred * struct svc_req *rqst; 6774462Salfred * struct rpc_msg *msg; 681901Swollman * 691901Swollman */ 701901Swollman 7126221Swpaul/* declarations to allow servers to specify new authentication flavors */ 7226221Swpaulstruct authsvc { 7326221Swpaul int flavor; 7474462Salfred enum auth_stat (*handler) __P((struct svc_req *, struct rpc_msg *)); 7526221Swpaul struct authsvc *next; 761901Swollman}; 7726221Swpaulstatic struct authsvc *Auths = NULL; 781901Swollman 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; 10574462Salfred extern mutex_t authsvc_lock; 1061901Swollman 10774462Salfred/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ 10874462Salfred 1091901Swollman rqst->rq_cred = msg->rm_call.cb_cred; 1101901Swollman rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 1111901Swollman rqst->rq_xprt->xp_verf.oa_length = 0; 1121901Swollman cred_flavor = rqst->rq_cred.oa_flavor; 11326221Swpaul switch (cred_flavor) { 11426221Swpaul case AUTH_NULL: 11574462Salfred dummy = _svcauth_null(rqst, msg); 11674462Salfred return (dummy); 11774462Salfred case AUTH_SYS: 11874462Salfred dummy = _svcauth_unix(rqst, msg); 11974462Salfred return (dummy); 12026221Swpaul case AUTH_SHORT: 12174462Salfred dummy = _svcauth_short(rqst, msg); 12274462Salfred return (dummy); 12326221Swpaul#ifdef DES_BUILTIN 12426221Swpaul case AUTH_DES: 12574462Salfred dummy = _svcauth_des(rqst, msg); 12674462Salfred return (dummy); 12726221Swpaul#endif 12874462Salfred default: 12974462Salfred break; 1301901Swollman } 1311901Swollman 13226221Swpaul /* flavor doesn't match any of the builtin types, so try new ones */ 13374462Salfred mutex_lock(&authsvc_lock); 13426221Swpaul for (asp = Auths; asp; asp = asp->next) { 13526221Swpaul if (asp->flavor == cred_flavor) { 13626221Swpaul enum auth_stat as; 13726221Swpaul 13826221Swpaul as = (*asp->handler)(rqst, msg); 13974462Salfred mutex_unlock(&authsvc_lock); 14026221Swpaul return (as); 14126221Swpaul } 14226221Swpaul } 14374462Salfred mutex_unlock(&authsvc_lock); 14426221Swpaul 1451901Swollman return (AUTH_REJECTEDCRED); 1461901Swollman} 1471901Swollman 14826221Swpaul/*ARGSUSED*/ 1491901Swollmanenum auth_stat 15026221Swpaul_svcauth_null(rqst, msg) 15126221Swpaul struct svc_req *rqst; 15226221Swpaul struct rpc_msg *msg; 1531901Swollman{ 1541901Swollman return (AUTH_OK); 1551901Swollman} 15626221Swpaul 15726221Swpaul/* 15826221Swpaul * Allow the rpc service to register new authentication types that it is 15926221Swpaul * prepared to handle. When an authentication flavor is registered, 16026221Swpaul * the flavor is checked against already registered values. If not 16126221Swpaul * registered, then a new Auths entry is added on the list. 16226221Swpaul * 16326221Swpaul * There is no provision to delete a registration once registered. 16426221Swpaul * 16526221Swpaul * This routine returns: 16626221Swpaul * 0 if registration successful 16726221Swpaul * 1 if flavor already registered 16826221Swpaul * -1 if can't register (errno set) 16926221Swpaul */ 17026221Swpaul 17126221Swpaulint 17226221Swpaulsvc_auth_reg(cred_flavor, handler) 17374462Salfred int cred_flavor; 17474462Salfred enum auth_stat (*handler) __P((struct svc_req *, struct rpc_msg *)); 17526221Swpaul{ 17674462Salfred struct authsvc *asp; 17774462Salfred extern mutex_t authsvc_lock; 17826221Swpaul 17926221Swpaul switch (cred_flavor) { 18026221Swpaul case AUTH_NULL: 18174462Salfred case AUTH_SYS: 18226221Swpaul case AUTH_SHORT: 18326221Swpaul#ifdef DES_BUILTIN 18426221Swpaul case AUTH_DES: 18526221Swpaul#endif 18626221Swpaul /* already registered */ 18726221Swpaul return (1); 18826221Swpaul 18926221Swpaul default: 19074462Salfred mutex_lock(&authsvc_lock); 19126221Swpaul for (asp = Auths; asp; asp = asp->next) { 19226221Swpaul if (asp->flavor == cred_flavor) { 19326221Swpaul /* already registered */ 19474462Salfred mutex_unlock(&authsvc_lock); 19526221Swpaul return (1); 19626221Swpaul } 19726221Swpaul } 19826221Swpaul 19926221Swpaul /* this is a new one, so go ahead and register it */ 20074462Salfred asp = mem_alloc(sizeof (*asp)); 20126221Swpaul if (asp == NULL) { 20274462Salfred mutex_unlock(&authsvc_lock); 20326221Swpaul return (-1); 20426221Swpaul } 20526221Swpaul asp->flavor = cred_flavor; 20626221Swpaul asp->handler = handler; 20726221Swpaul asp->next = Auths; 20826221Swpaul Auths = asp; 20974462Salfred mutex_unlock(&authsvc_lock); 21026221Swpaul break; 21126221Swpaul } 21226221Swpaul return (0); 21326221Swpaul} 214