svc_auth.c revision 1.13 1 1.13 lukem /* $NetBSD: svc_auth.c,v 1.13 2001/01/04 14:42:21 lukem Exp $ */
2 1.2 cgd
3 1.1 cgd /*
4 1.1 cgd * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 1.1 cgd * unrestricted use provided that this legend is included on all tape
6 1.1 cgd * media and as a part of the software program in whole or part. Users
7 1.1 cgd * may copy or modify Sun RPC without charge, but are not authorized
8 1.1 cgd * to license or distribute it to anyone else except as part of a product or
9 1.1 cgd * program developed by the user.
10 1.1 cgd *
11 1.1 cgd * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 1.1 cgd * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 1.1 cgd * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 1.1 cgd *
15 1.1 cgd * Sun RPC is provided with no support and without any obligation on the
16 1.1 cgd * part of Sun Microsystems, Inc. to assist in its use, correction,
17 1.1 cgd * modification or enhancement.
18 1.11 fvdl *
19 1.1 cgd * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 1.1 cgd * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 1.1 cgd * OR ANY PART THEREOF.
22 1.11 fvdl *
23 1.1 cgd * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 1.1 cgd * or profits or other special, indirect and consequential damages, even if
25 1.1 cgd * Sun has been advised of the possibility of such damages.
26 1.11 fvdl *
27 1.1 cgd * Sun Microsystems, Inc.
28 1.1 cgd * 2550 Garcia Avenue
29 1.1 cgd * Mountain View, California 94043
30 1.1 cgd */
31 1.11 fvdl /*
32 1.11 fvdl * Copyright (c) 1986-1991 by Sun Microsystems Inc.
33 1.11 fvdl */
34 1.11 fvdl
35 1.11 fvdl /* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */
36 1.1 cgd
37 1.3 christos #if 0
38 1.11 fvdl #if !defined(lint) && defined(SCCSIDS)
39 1.11 fvdl static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
40 1.3 christos #endif
41 1.1 cgd #endif
42 1.1 cgd
43 1.1 cgd /*
44 1.11 fvdl * svc_auth.c, Server-side rpc authenticator interface.
45 1.1 cgd *
46 1.1 cgd */
47 1.1 cgd
48 1.11 fvdl #include "namespace.h"
49 1.11 fvdl #include "reentrant.h"
50 1.11 fvdl #include <sys/types.h>
51 1.11 fvdl #include <rpc/rpc.h>
52 1.13 lukem #include <assert.h>
53 1.11 fvdl #include <stdlib.h>
54 1.9 lukem
55 1.11 fvdl #ifdef __weak_alias
56 1.11 fvdl __weak_alias(svc_auth_reg,_svc_auth_reg)
57 1.11 fvdl #endif
58 1.1 cgd
59 1.1 cgd /*
60 1.11 fvdl * svcauthsw is the bdevsw of server side authentication.
61 1.11 fvdl *
62 1.1 cgd * Server side authenticators are called from authenticate by
63 1.1 cgd * using the client auth struct flavor field to index into svcauthsw.
64 1.11 fvdl * The server auth flavors must implement a routine that looks
65 1.11 fvdl * like:
66 1.11 fvdl *
67 1.1 cgd * enum auth_stat
68 1.1 cgd * flavorx_auth(rqst, msg)
69 1.12 christos * struct svc_req *rqst;
70 1.12 christos * struct rpc_msg *msg;
71 1.1 cgd *
72 1.1 cgd */
73 1.1 cgd
74 1.11 fvdl /* declarations to allow servers to specify new authentication flavors */
75 1.11 fvdl struct authsvc {
76 1.11 fvdl int flavor;
77 1.11 fvdl enum auth_stat (*handler) __P((struct svc_req *, struct rpc_msg *));
78 1.11 fvdl struct authsvc *next;
79 1.1 cgd };
80 1.11 fvdl static struct authsvc *Auths = NULL;
81 1.1 cgd
82 1.1 cgd /*
83 1.1 cgd * The call rpc message, msg has been obtained from the wire. The msg contains
84 1.1 cgd * the raw form of credentials and verifiers. authenticate returns AUTH_OK
85 1.1 cgd * if the msg is successfully authenticated. If AUTH_OK then the routine also
86 1.1 cgd * does the following things:
87 1.1 cgd * set rqst->rq_xprt->verf to the appropriate response verifier;
88 1.1 cgd * sets rqst->rq_client_cred to the "cooked" form of the credentials.
89 1.1 cgd *
90 1.1 cgd * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
91 1.1 cgd * its length is set appropriately.
92 1.1 cgd *
93 1.1 cgd * The caller still owns and is responsible for msg->u.cmb.cred and
94 1.1 cgd * msg->u.cmb.verf. The authentication system retains ownership of
95 1.1 cgd * rqst->rq_client_cred, the cooked credentials.
96 1.1 cgd *
97 1.1 cgd * There is an assumption that any flavour less than AUTH_NULL is
98 1.1 cgd * invalid.
99 1.1 cgd */
100 1.1 cgd enum auth_stat
101 1.1 cgd _authenticate(rqst, msg)
102 1.12 christos struct svc_req *rqst;
103 1.1 cgd struct rpc_msg *msg;
104 1.1 cgd {
105 1.12 christos int cred_flavor;
106 1.12 christos struct authsvc *asp;
107 1.11 fvdl enum auth_stat dummy;
108 1.11 fvdl #ifdef __REENT
109 1.11 fvdl extern mutex_t authsvc_lock;
110 1.11 fvdl #endif
111 1.13 lukem
112 1.13 lukem _DIAGASSERT(rqst != NULL);
113 1.13 lukem _DIAGASSERT(msg != NULL);
114 1.9 lukem
115 1.11 fvdl /* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
116 1.1 cgd
117 1.1 cgd rqst->rq_cred = msg->rm_call.cb_cred;
118 1.1 cgd rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
119 1.1 cgd rqst->rq_xprt->xp_verf.oa_length = 0;
120 1.1 cgd cred_flavor = rqst->rq_cred.oa_flavor;
121 1.11 fvdl switch (cred_flavor) {
122 1.11 fvdl case AUTH_NULL:
123 1.11 fvdl dummy = _svcauth_null(rqst, msg);
124 1.11 fvdl return (dummy);
125 1.11 fvdl case AUTH_SYS:
126 1.11 fvdl dummy = _svcauth_unix(rqst, msg);
127 1.11 fvdl return (dummy);
128 1.11 fvdl case AUTH_SHORT:
129 1.11 fvdl dummy = _svcauth_short(rqst, msg);
130 1.11 fvdl return (dummy);
131 1.11 fvdl #if 0
132 1.11 fvdl case AUTH_DES:
133 1.11 fvdl dummy = __svcauth_des(rqst, msg);
134 1.11 fvdl return (dummy);
135 1.11 fvdl #endif
136 1.11 fvdl default:
137 1.11 fvdl break;
138 1.11 fvdl }
139 1.11 fvdl
140 1.11 fvdl /* flavor doesn't match any of the builtin types, so try new ones */
141 1.11 fvdl mutex_lock(&authsvc_lock);
142 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
143 1.11 fvdl if (asp->flavor == cred_flavor) {
144 1.11 fvdl enum auth_stat as;
145 1.11 fvdl
146 1.11 fvdl as = (*asp->handler)(rqst, msg);
147 1.11 fvdl mutex_unlock(&authsvc_lock);
148 1.11 fvdl return (as);
149 1.11 fvdl }
150 1.1 cgd }
151 1.11 fvdl mutex_unlock(&authsvc_lock);
152 1.1 cgd
153 1.1 cgd return (AUTH_REJECTEDCRED);
154 1.1 cgd }
155 1.1 cgd
156 1.11 fvdl /*ARGSUSED*/
157 1.1 cgd enum auth_stat
158 1.3 christos _svcauth_null(rqst, msg)
159 1.3 christos struct svc_req *rqst;
160 1.3 christos struct rpc_msg *msg;
161 1.1 cgd {
162 1.11 fvdl return (AUTH_OK);
163 1.11 fvdl }
164 1.11 fvdl
165 1.11 fvdl /*
166 1.11 fvdl * Allow the rpc service to register new authentication types that it is
167 1.11 fvdl * prepared to handle. When an authentication flavor is registered,
168 1.11 fvdl * the flavor is checked against already registered values. If not
169 1.11 fvdl * registered, then a new Auths entry is added on the list.
170 1.11 fvdl *
171 1.11 fvdl * There is no provision to delete a registration once registered.
172 1.11 fvdl *
173 1.11 fvdl * This routine returns:
174 1.11 fvdl * 0 if registration successful
175 1.11 fvdl * 1 if flavor already registered
176 1.11 fvdl * -1 if can't register (errno set)
177 1.11 fvdl */
178 1.11 fvdl
179 1.11 fvdl int
180 1.11 fvdl svc_auth_reg(cred_flavor, handler)
181 1.12 christos int cred_flavor;
182 1.11 fvdl enum auth_stat (*handler) __P((struct svc_req *, struct rpc_msg *));
183 1.11 fvdl {
184 1.12 christos struct authsvc *asp;
185 1.11 fvdl #ifdef __REENT
186 1.11 fvdl extern mutex_t authsvc_lock;
187 1.11 fvdl #endif
188 1.1 cgd
189 1.11 fvdl switch (cred_flavor) {
190 1.11 fvdl case AUTH_NULL:
191 1.11 fvdl case AUTH_SYS:
192 1.11 fvdl case AUTH_SHORT:
193 1.11 fvdl #if 0
194 1.11 fvdl case AUTH_DES:
195 1.11 fvdl #endif
196 1.11 fvdl /* already registered */
197 1.11 fvdl return (1);
198 1.11 fvdl
199 1.11 fvdl default:
200 1.11 fvdl mutex_lock(&authsvc_lock);
201 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
202 1.11 fvdl if (asp->flavor == cred_flavor) {
203 1.11 fvdl /* already registered */
204 1.11 fvdl mutex_unlock(&authsvc_lock);
205 1.11 fvdl return (1);
206 1.11 fvdl }
207 1.11 fvdl }
208 1.11 fvdl
209 1.11 fvdl /* this is a new one, so go ahead and register it */
210 1.12 christos asp = mem_alloc(sizeof (*asp));
211 1.11 fvdl if (asp == NULL) {
212 1.11 fvdl mutex_unlock(&authsvc_lock);
213 1.11 fvdl return (-1);
214 1.11 fvdl }
215 1.11 fvdl asp->flavor = cred_flavor;
216 1.11 fvdl asp->handler = handler;
217 1.11 fvdl asp->next = Auths;
218 1.11 fvdl Auths = asp;
219 1.11 fvdl mutex_unlock(&authsvc_lock);
220 1.11 fvdl break;
221 1.11 fvdl }
222 1.11 fvdl return (0);
223 1.1 cgd }
224