svc_auth.c revision 136581
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 136581 2004-10-16 06:11:35Z obrien $"); 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" 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 771901Swollman/* 781901Swollman * The call rpc message, msg has been obtained from the wire. The msg contains 791901Swollman * the raw form of credentials and verifiers. authenticate returns AUTH_OK 801901Swollman * if the msg is successfully authenticated. If AUTH_OK then the routine also 811901Swollman * does the following things: 821901Swollman * set rqst->rq_xprt->verf to the appropriate response verifier; 831901Swollman * sets rqst->rq_client_cred to the "cooked" form of the credentials. 841901Swollman * 851901Swollman * NB: rqst->rq_cxprt->verf must be pre-alloctaed; 861901Swollman * its length is set appropriately. 871901Swollman * 881901Swollman * The caller still owns and is responsible for msg->u.cmb.cred and 891901Swollman * msg->u.cmb.verf. The authentication system retains ownership of 901901Swollman * rqst->rq_client_cred, the cooked credentials. 911901Swollman * 921901Swollman * There is an assumption that any flavour less than AUTH_NULL is 931901Swollman * invalid. 941901Swollman */ 951901Swollmanenum auth_stat 961901Swollman_authenticate(rqst, msg) 9774462Salfred struct svc_req *rqst; 981901Swollman struct rpc_msg *msg; 991901Swollman{ 10074462Salfred int cred_flavor; 10174462Salfred struct authsvc *asp; 10274462Salfred enum auth_stat dummy; 10374462Salfred extern mutex_t authsvc_lock; 1041901Swollman 10574462Salfred/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */ 10674462Salfred 1071901Swollman rqst->rq_cred = msg->rm_call.cb_cred; 1081901Swollman rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 1091901Swollman rqst->rq_xprt->xp_verf.oa_length = 0; 1101901Swollman cred_flavor = rqst->rq_cred.oa_flavor; 11126221Swpaul switch (cred_flavor) { 11226221Swpaul case AUTH_NULL: 11374462Salfred dummy = _svcauth_null(rqst, msg); 11474462Salfred return (dummy); 11574462Salfred case AUTH_SYS: 11674462Salfred dummy = _svcauth_unix(rqst, msg); 11774462Salfred return (dummy); 11826221Swpaul case AUTH_SHORT: 11974462Salfred dummy = _svcauth_short(rqst, msg); 12074462Salfred return (dummy); 12126221Swpaul#ifdef DES_BUILTIN 12226221Swpaul case AUTH_DES: 12374462Salfred dummy = _svcauth_des(rqst, msg); 12474462Salfred return (dummy); 12526221Swpaul#endif 12674462Salfred default: 12774462Salfred break; 1281901Swollman } 1291901Swollman 13026221Swpaul /* flavor doesn't match any of the builtin types, so try new ones */ 13174462Salfred mutex_lock(&authsvc_lock); 13226221Swpaul for (asp = Auths; asp; asp = asp->next) { 13326221Swpaul if (asp->flavor == cred_flavor) { 13426221Swpaul enum auth_stat as; 13526221Swpaul 13626221Swpaul as = (*asp->handler)(rqst, msg); 13774462Salfred mutex_unlock(&authsvc_lock); 13826221Swpaul return (as); 13926221Swpaul } 14026221Swpaul } 14174462Salfred mutex_unlock(&authsvc_lock); 14226221Swpaul 1431901Swollman return (AUTH_REJECTEDCRED); 1441901Swollman} 1451901Swollman 14626221Swpaul/*ARGSUSED*/ 1471901Swollmanenum auth_stat 14826221Swpaul_svcauth_null(rqst, msg) 14926221Swpaul struct svc_req *rqst; 15026221Swpaul struct rpc_msg *msg; 1511901Swollman{ 1521901Swollman return (AUTH_OK); 1531901Swollman} 15426221Swpaul 15526221Swpaul/* 15626221Swpaul * Allow the rpc service to register new authentication types that it is 15726221Swpaul * prepared to handle. When an authentication flavor is registered, 15826221Swpaul * the flavor is checked against already registered values. If not 15926221Swpaul * registered, then a new Auths entry is added on the list. 16026221Swpaul * 16126221Swpaul * There is no provision to delete a registration once registered. 16226221Swpaul * 16326221Swpaul * This routine returns: 16426221Swpaul * 0 if registration successful 16526221Swpaul * 1 if flavor already registered 16626221Swpaul * -1 if can't register (errno set) 16726221Swpaul */ 16826221Swpaul 16926221Swpaulint 17026221Swpaulsvc_auth_reg(cred_flavor, handler) 17174462Salfred int cred_flavor; 17292905Sobrien enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *); 17326221Swpaul{ 17474462Salfred struct authsvc *asp; 17574462Salfred extern mutex_t authsvc_lock; 17626221Swpaul 17726221Swpaul switch (cred_flavor) { 17826221Swpaul case AUTH_NULL: 17974462Salfred case AUTH_SYS: 18026221Swpaul case AUTH_SHORT: 18126221Swpaul#ifdef DES_BUILTIN 18226221Swpaul case AUTH_DES: 18326221Swpaul#endif 18426221Swpaul /* already registered */ 18526221Swpaul return (1); 18626221Swpaul 18726221Swpaul default: 18874462Salfred mutex_lock(&authsvc_lock); 18926221Swpaul for (asp = Auths; asp; asp = asp->next) { 19026221Swpaul if (asp->flavor == cred_flavor) { 19126221Swpaul /* already registered */ 19274462Salfred mutex_unlock(&authsvc_lock); 19326221Swpaul return (1); 19426221Swpaul } 19526221Swpaul } 19626221Swpaul 19726221Swpaul /* this is a new one, so go ahead and register it */ 19874462Salfred asp = mem_alloc(sizeof (*asp)); 19926221Swpaul if (asp == NULL) { 20074462Salfred mutex_unlock(&authsvc_lock); 20126221Swpaul return (-1); 20226221Swpaul } 20326221Swpaul asp->flavor = cred_flavor; 20426221Swpaul asp->handler = handler; 20526221Swpaul asp->next = Auths; 20626221Swpaul Auths = asp; 20774462Salfred mutex_unlock(&authsvc_lock); 20826221Swpaul break; 20926221Swpaul } 21026221Swpaul return (0); 21126221Swpaul} 212