svc_auth.c revision 92990
185634Sdillon/*	$NetBSD: svc_auth.c,v 1.12 2000/07/06 03:10:35 christos Exp $	*/
285634Sdillon
385634Sdillon/*
485634Sdillon * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
585634Sdillon * unrestricted use provided that this legend is included on all tape
685634Sdillon * media and as a part of the software program in whole or part.  Users
785634Sdillon * may copy or modify Sun RPC without charge, but are not authorized
885634Sdillon * to license or distribute it to anyone else except as part of a product or
985634Sdillon * program developed by the user.
1085634Sdillon *
1185634Sdillon * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1285634Sdillon * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1385634Sdillon * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1485634Sdillon *
1585634Sdillon * Sun RPC is provided with no support and without any obligation on the
1685634Sdillon * part of Sun Microsystems, Inc. to assist in its use, correction,
1785634Sdillon * modification or enhancement.
1885634Sdillon *
1985634Sdillon * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
2085634Sdillon * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
2185634Sdillon * OR ANY PART THEREOF.
2285634Sdillon *
2385634Sdillon * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2489572Sdillon * or profits or other special, indirect and consequential damages, even if
2585634Sdillon * Sun has been advised of the possibility of such damages.
2685634Sdillon *
2785634Sdillon * Sun Microsystems, Inc.
2885634Sdillon * 2550 Garcia Avenue
2985634Sdillon * Mountain View, California  94043
3085634Sdillon */
3185634Sdillon/*
3285634Sdillon * Copyright (c) 1986-1991 by Sun Microsystems Inc.
3385634Sdillon */
3485634Sdillon
3589572Sdillon/* #ident	"@(#)svc_auth.c	1.16	94/04/24 SMI" */
3685634Sdillon
3785634Sdillon#if !defined(lint) && defined(SCCSIDS)
3885634Sdillonstatic char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
3985634Sdillon#endif
4085634Sdillon#include <sys/cdefs.h>
4185634Sdillon__FBSDID("$FreeBSD: head/lib/libc/rpc/svc_auth.c 92990 2002-03-22 23:18:37Z obrien $");
4285634Sdillon
4385634Sdillon/*
4485634Sdillon * svc_auth.c, Server-side rpc authenticator interface.
4585634Sdillon *
4689572Sdillon */
4785634Sdillon
4885634Sdillon#include "namespace.h"
4985634Sdillon#include "reentrant.h"
5085634Sdillon#include <sys/types.h>
5185634Sdillon#include <rpc/rpc.h>
5285634Sdillon#include <stdlib.h>
5385634Sdillon#include "un-namespace.h"
5485634Sdillon
5585634Sdillon/*
5689572Sdillon * svcauthsw is the bdevsw of server side authentication.
5785634Sdillon *
5885634Sdillon * Server side authenticators are called from authenticate by
5985634Sdillon * using the client auth struct flavor field to index into svcauthsw.
6085634Sdillon * The server auth flavors must implement a routine that looks
6185636Sdillon * like:
6285636Sdillon *
6385636Sdillon *	enum auth_stat
6485636Sdillon *	flavorx_auth(rqst, msg)
6585636Sdillon *		struct svc_req *rqst;
6689572Sdillon *		struct rpc_msg *msg;
6785636Sdillon *
6885636Sdillon */
6989572Sdillon
7085636Sdillon/* declarations to allow servers to specify new authentication flavors */
7185636Sdillonstruct authsvc {
7285636Sdillon	int	flavor;
7385636Sdillon	enum	auth_stat (*handler)(struct svc_req *, struct rpc_msg *);
7489572Sdillon	struct	authsvc	  *next;
7585636Sdillon};
7685636Sdillonstatic struct authsvc *Auths = NULL;
7789572Sdillon
7885636Sdillon/*
7985636Sdillon * The call rpc message, msg has been obtained from the wire.  The msg contains
8085636Sdillon * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
8185636Sdillon * if the msg is successfully authenticated.  If AUTH_OK then the routine also
8285636Sdillon * does the following things:
8385636Sdillon * set rqst->rq_xprt->verf to the appropriate response verifier;
8485636Sdillon * sets rqst->rq_client_cred to the "cooked" form of the credentials.
8585636Sdillon *
8689572Sdillon * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
8785636Sdillon * its length is set appropriately.
8885636Sdillon *
8989572Sdillon * The caller still owns and is responsible for msg->u.cmb.cred and
9085636Sdillon * msg->u.cmb.verf.  The authentication system retains ownership of
9185636Sdillon * rqst->rq_client_cred, the cooked credentials.
9285636Sdillon *
9385636Sdillon * There is an assumption that any flavour less than AUTH_NULL is
9489572Sdillon * invalid.
9585636Sdillon */
9685636Sdillonenum auth_stat
9789572Sdillon_authenticate(rqst, msg)
9885636Sdillon	struct svc_req *rqst;
9985636Sdillon	struct rpc_msg *msg;
10085636Sdillon{
101	int cred_flavor;
102	struct authsvc *asp;
103	enum auth_stat dummy;
104	extern mutex_t authsvc_lock;
105
106/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
107
108	rqst->rq_cred = msg->rm_call.cb_cred;
109	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
110	rqst->rq_xprt->xp_verf.oa_length = 0;
111	cred_flavor = rqst->rq_cred.oa_flavor;
112	switch (cred_flavor) {
113	case AUTH_NULL:
114		dummy = _svcauth_null(rqst, msg);
115		return (dummy);
116	case AUTH_SYS:
117		dummy = _svcauth_unix(rqst, msg);
118		return (dummy);
119	case AUTH_SHORT:
120		dummy = _svcauth_short(rqst, msg);
121		return (dummy);
122#ifdef DES_BUILTIN
123	case AUTH_DES:
124		dummy = _svcauth_des(rqst, msg);
125		return (dummy);
126#endif
127	default:
128		break;
129	}
130
131	/* flavor doesn't match any of the builtin types, so try new ones */
132	mutex_lock(&authsvc_lock);
133	for (asp = Auths; asp; asp = asp->next) {
134		if (asp->flavor == cred_flavor) {
135			enum auth_stat as;
136
137			as = (*asp->handler)(rqst, msg);
138			mutex_unlock(&authsvc_lock);
139			return (as);
140		}
141	}
142	mutex_unlock(&authsvc_lock);
143
144	return (AUTH_REJECTEDCRED);
145}
146
147/*ARGSUSED*/
148enum auth_stat
149_svcauth_null(rqst, msg)
150	struct svc_req *rqst;
151	struct rpc_msg *msg;
152{
153	return (AUTH_OK);
154}
155
156/*
157 *  Allow the rpc service to register new authentication types that it is
158 *  prepared to handle.  When an authentication flavor is registered,
159 *  the flavor is checked against already registered values.  If not
160 *  registered, then a new Auths entry is added on the list.
161 *
162 *  There is no provision to delete a registration once registered.
163 *
164 *  This routine returns:
165 *	 0 if registration successful
166 *	 1 if flavor already registered
167 *	-1 if can't register (errno set)
168 */
169
170int
171svc_auth_reg(cred_flavor, handler)
172	int cred_flavor;
173	enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *);
174{
175	struct authsvc *asp;
176	extern mutex_t authsvc_lock;
177
178	switch (cred_flavor) {
179	    case AUTH_NULL:
180	    case AUTH_SYS:
181	    case AUTH_SHORT:
182#ifdef DES_BUILTIN
183	    case AUTH_DES:
184#endif
185		/* already registered */
186		return (1);
187
188	    default:
189		mutex_lock(&authsvc_lock);
190		for (asp = Auths; asp; asp = asp->next) {
191			if (asp->flavor == cred_flavor) {
192				/* already registered */
193				mutex_unlock(&authsvc_lock);
194				return (1);
195			}
196		}
197
198		/* this is a new one, so go ahead and register it */
199		asp = mem_alloc(sizeof (*asp));
200		if (asp == NULL) {
201			mutex_unlock(&authsvc_lock);
202			return (-1);
203		}
204		asp->flavor = cred_flavor;
205		asp->handler = handler;
206		asp->next = Auths;
207		Auths = asp;
208		mutex_unlock(&authsvc_lock);
209		break;
210	}
211	return (0);
212}
213