svc_auth.c revision 26221
11901Swollman/*
21901Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
31901Swollman * unrestricted use provided that this legend is included on all tape
41901Swollman * media and as a part of the software program in whole or part.  Users
51901Swollman * may copy or modify Sun RPC without charge, but are not authorized
61901Swollman * to license or distribute it to anyone else except as part of a product or
71901Swollman * program developed by the user.
826221Swpaul *
91901Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
101901Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
111901Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1226221Swpaul *
131901Swollman * Sun RPC is provided with no support and without any obligation on the
141901Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
151901Swollman * modification or enhancement.
1626221Swpaul *
171901Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
181901Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
191901Swollman * OR ANY PART THEREOF.
2026221Swpaul *
211901Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
221901Swollman * or profits or other special, indirect and consequential damages, even if
231901Swollman * Sun has been advised of the possibility of such damages.
2426221Swpaul *
251901Swollman * Sun Microsystems, Inc.
261901Swollman * 2550 Garcia Avenue
271901Swollman * Mountain View, California  94043
281901Swollman */
2926221Swpaul/*
3026221Swpaul * Copyright (c) 1986-1991 by Sun Microsystems Inc.
3126221Swpaul */
321901Swollman
3326221Swpaul#ident	"@(#)svc_auth.c	1.16	94/04/24 SMI"
3426221Swpaul
3526221Swpaul#if !defined(lint) && defined(SCCSIDS)
3626221Swpaulstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
371901Swollman#endif
381901Swollman
391901Swollman/*
4026221Swpaul * svc_auth.c, Server-side rpc authenticator interface.
411901Swollman *
421901Swollman */
431901Swollman
4426221Swpaul#ifdef KERNEL
4526221Swpaul#include <sys/param.h>
4626221Swpaul#include <rpc/types.h>
4726221Swpaul#include <rpc/xdr.h>
4826221Swpaul#include <rpc/auth.h>
4926221Swpaul#include <rpc/clnt.h>
5026221Swpaul#include <rpc/rpc_msg.h>
5126221Swpaul#include <rpc/svc.h>
5226221Swpaul#include <rpc/svc_auth.h>
5326221Swpaul#else
5426221Swpaul#include <stdlib.h>
551901Swollman#include <rpc/rpc.h>
5626221Swpaul#endif
5726221Swpaul#include <sys/types.h>
581901Swollman
591901Swollman/*
608870Srgrimes * svcauthsw is the bdevsw of server side authentication.
618870Srgrimes *
621901Swollman * Server side authenticators are called from authenticate by
631901Swollman * using the client auth struct flavor field to index into svcauthsw.
648870Srgrimes * The server auth flavors must implement a routine that looks
658870Srgrimes * like:
668870Srgrimes *
671901Swollman *	enum auth_stat
681901Swollman *	flavorx_auth(rqst, msg)
698870Srgrimes *		register struct svc_req *rqst;
701901Swollman *		register struct rpc_msg *msg;
711901Swollman *
721901Swollman */
731901Swollman
7426221Swpaulenum auth_stat _svcauth_null();	/* no authentication */
7526221Swpaulenum auth_stat _svcauth_unix();		/* (system) unix style (uid, gids) */
761901Swollmanenum auth_stat _svcauth_short();	/* short hand unix style */
7726221Swpaulenum auth_stat _svcauth_des();		/* des style */
781901Swollman
7926221Swpaul/* declarations to allow servers to specify new authentication flavors */
8026221Swpaulstruct authsvc {
8126221Swpaul	int	flavor;
8226221Swpaul	enum	auth_stat (*handler)();
8326221Swpaul	struct	authsvc	  *next;
841901Swollman};
8526221Swpaulstatic struct authsvc *Auths = NULL;
861901Swollman
871901Swollman/*
881901Swollman * The call rpc message, msg has been obtained from the wire.  The msg contains
891901Swollman * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
901901Swollman * if the msg is successfully authenticated.  If AUTH_OK then the routine also
911901Swollman * does the following things:
921901Swollman * set rqst->rq_xprt->verf to the appropriate response verifier;
931901Swollman * sets rqst->rq_client_cred to the "cooked" form of the credentials.
941901Swollman *
951901Swollman * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
961901Swollman * its length is set appropriately.
971901Swollman *
981901Swollman * The caller still owns and is responsible for msg->u.cmb.cred and
991901Swollman * msg->u.cmb.verf.  The authentication system retains ownership of
1001901Swollman * rqst->rq_client_cred, the cooked credentials.
1011901Swollman *
1021901Swollman * There is an assumption that any flavour less than AUTH_NULL is
1031901Swollman * invalid.
1041901Swollman */
1051901Swollmanenum auth_stat
1061901Swollman_authenticate(rqst, msg)
1071901Swollman	register struct svc_req *rqst;
1081901Swollman	struct rpc_msg *msg;
1091901Swollman{
1101901Swollman	register int cred_flavor;
11126221Swpaul	register struct authsvc *asp;
1121901Swollman
1131901Swollman	rqst->rq_cred = msg->rm_call.cb_cred;
1141901Swollman	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
1151901Swollman	rqst->rq_xprt->xp_verf.oa_length = 0;
1161901Swollman	cred_flavor = rqst->rq_cred.oa_flavor;
11726221Swpaul	switch (cred_flavor) {
11826221Swpaul	case AUTH_NULL:
11926221Swpaul		return(_svcauth_null(rqst, msg));
12026221Swpaul	case AUTH_UNIX:
12126221Swpaul		return(_svcauth_unix(rqst, msg));
12226221Swpaul	case AUTH_SHORT:
12326221Swpaul		return(_svcauth_short(rqst, msg));
12426221Swpaul	/*
12526221Swpaul	 * We leave AUTH_DES turned off by default because svcauth_des()
12626221Swpaul	 * needs getpublickey(), which is in librpcsvc, not libc. If we
12726221Swpaul 	 * included AUTH_DES as a built-in flavor, programs that don't
12826221Swpaul	 * have -lrpcsvc in their Makefiles wouldn't link correctly, even
12926221Swpaul	 * though they don't use AUTH_DES. And I'm too lazy to go through
13026221Swpaul	 * the tree looking for all of them.
13126221Swpaul	 */
13226221Swpaul#ifdef DES_BUILTIN
13326221Swpaul	case AUTH_DES:
13426221Swpaul		return(_svcauth_des(rqst, msg));
13526221Swpaul#endif
1361901Swollman	}
1371901Swollman
13826221Swpaul	/* flavor doesn't match any of the builtin types, so try new ones */
13926221Swpaul	for (asp = Auths; asp; asp = asp->next) {
14026221Swpaul		if (asp->flavor == cred_flavor) {
14126221Swpaul			enum auth_stat as;
14226221Swpaul
14326221Swpaul			as = (*asp->handler)(rqst, msg);
14426221Swpaul			return (as);
14526221Swpaul		}
14626221Swpaul	}
14726221Swpaul
1481901Swollman	return (AUTH_REJECTEDCRED);
1491901Swollman}
1501901Swollman
15126221Swpaul/*ARGSUSED*/
1521901Swollmanenum auth_stat
15326221Swpaul_svcauth_null(rqst, msg)
15426221Swpaul	struct svc_req *rqst;
15526221Swpaul	struct rpc_msg *msg;
1561901Swollman{
1571901Swollman	return (AUTH_OK);
1581901Swollman}
15926221Swpaul
16026221Swpaul/*
16126221Swpaul *  Allow the rpc service to register new authentication types that it is
16226221Swpaul *  prepared to handle.  When an authentication flavor is registered,
16326221Swpaul *  the flavor is checked against already registered values.  If not
16426221Swpaul *  registered, then a new Auths entry is added on the list.
16526221Swpaul *
16626221Swpaul *  There is no provision to delete a registration once registered.
16726221Swpaul *
16826221Swpaul *  This routine returns:
16926221Swpaul *	 0 if registration successful
17026221Swpaul *	 1 if flavor already registered
17126221Swpaul *	-1 if can't register (errno set)
17226221Swpaul */
17326221Swpaul
17426221Swpaulint
17526221Swpaulsvc_auth_reg(cred_flavor, handler)
17626221Swpaul	register int cred_flavor;
17726221Swpaul	enum auth_stat (*handler)();
17826221Swpaul{
17926221Swpaul	register struct authsvc *asp;
18026221Swpaul
18126221Swpaul	switch (cred_flavor) {
18226221Swpaul	    case AUTH_NULL:
18326221Swpaul	    case AUTH_UNIX:
18426221Swpaul	    case AUTH_SHORT:
18526221Swpaul#ifdef DES_BUILTIN
18626221Swpaul	    case AUTH_DES:
18726221Swpaul#endif
18826221Swpaul		/* already registered */
18926221Swpaul		return (1);
19026221Swpaul
19126221Swpaul	    default:
19226221Swpaul		for (asp = Auths; asp; asp = asp->next) {
19326221Swpaul			if (asp->flavor == cred_flavor) {
19426221Swpaul				/* already registered */
19526221Swpaul				return (1);
19626221Swpaul			}
19726221Swpaul		}
19826221Swpaul
19926221Swpaul		/* this is a new one, so go ahead and register it */
20026221Swpaul		asp = (struct authsvc *)mem_alloc(sizeof (*asp));
20126221Swpaul		if (asp == NULL) {
20226221Swpaul			return (-1);
20326221Swpaul		}
20426221Swpaul		asp->flavor = cred_flavor;
20526221Swpaul		asp->handler = handler;
20626221Swpaul		asp->next = Auths;
20726221Swpaul		Auths = asp;
20826221Swpaul		break;
20926221Swpaul	}
21026221Swpaul	return (0);
21126221Swpaul}
212