svc_auth.c revision 1.15.56.1 1 1.15.56.1 yamt /* $NetBSD: svc_auth.c,v 1.15.56.1 2012/04/17 00:05:23 yamt 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.15 itojun #include <sys/cdefs.h>
38 1.15 itojun #if defined(LIBC_SCCS) && !defined(lint)
39 1.3 christos #if 0
40 1.11 fvdl static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
41 1.15 itojun #else
42 1.15.56.1 yamt __RCSID("$NetBSD: svc_auth.c,v 1.15.56.1 2012/04/17 00:05:23 yamt Exp $");
43 1.3 christos #endif
44 1.1 cgd #endif
45 1.1 cgd
46 1.1 cgd /*
47 1.11 fvdl * svc_auth.c, Server-side rpc authenticator interface.
48 1.1 cgd *
49 1.1 cgd */
50 1.1 cgd
51 1.11 fvdl #include "namespace.h"
52 1.11 fvdl #include "reentrant.h"
53 1.11 fvdl #include <sys/types.h>
54 1.11 fvdl #include <rpc/rpc.h>
55 1.13 lukem #include <assert.h>
56 1.11 fvdl #include <stdlib.h>
57 1.9 lukem
58 1.11 fvdl #ifdef __weak_alias
59 1.11 fvdl __weak_alias(svc_auth_reg,_svc_auth_reg)
60 1.11 fvdl #endif
61 1.1 cgd
62 1.1 cgd /*
63 1.11 fvdl * svcauthsw is the bdevsw of server side authentication.
64 1.11 fvdl *
65 1.1 cgd * Server side authenticators are called from authenticate by
66 1.1 cgd * using the client auth struct flavor field to index into svcauthsw.
67 1.11 fvdl * The server auth flavors must implement a routine that looks
68 1.11 fvdl * like:
69 1.11 fvdl *
70 1.1 cgd * enum auth_stat
71 1.1 cgd * flavorx_auth(rqst, msg)
72 1.12 christos * struct svc_req *rqst;
73 1.12 christos * struct rpc_msg *msg;
74 1.1 cgd *
75 1.1 cgd */
76 1.1 cgd
77 1.11 fvdl /* declarations to allow servers to specify new authentication flavors */
78 1.11 fvdl struct authsvc {
79 1.11 fvdl int flavor;
80 1.15.56.1 yamt enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *);
81 1.11 fvdl struct authsvc *next;
82 1.1 cgd };
83 1.11 fvdl static struct authsvc *Auths = NULL;
84 1.1 cgd
85 1.1 cgd /*
86 1.1 cgd * The call rpc message, msg has been obtained from the wire. The msg contains
87 1.1 cgd * the raw form of credentials and verifiers. authenticate returns AUTH_OK
88 1.1 cgd * if the msg is successfully authenticated. If AUTH_OK then the routine also
89 1.1 cgd * does the following things:
90 1.1 cgd * set rqst->rq_xprt->verf to the appropriate response verifier;
91 1.1 cgd * sets rqst->rq_client_cred to the "cooked" form of the credentials.
92 1.1 cgd *
93 1.1 cgd * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
94 1.1 cgd * its length is set appropriately.
95 1.1 cgd *
96 1.1 cgd * The caller still owns and is responsible for msg->u.cmb.cred and
97 1.1 cgd * msg->u.cmb.verf. The authentication system retains ownership of
98 1.1 cgd * rqst->rq_client_cred, the cooked credentials.
99 1.1 cgd *
100 1.1 cgd * There is an assumption that any flavour less than AUTH_NULL is
101 1.1 cgd * invalid.
102 1.1 cgd */
103 1.1 cgd enum auth_stat
104 1.15.56.1 yamt _authenticate(struct svc_req *rqst, struct rpc_msg *msg)
105 1.1 cgd {
106 1.12 christos int cred_flavor;
107 1.12 christos struct authsvc *asp;
108 1.11 fvdl enum auth_stat dummy;
109 1.14 thorpej #ifdef _REENTRANT
110 1.11 fvdl extern mutex_t authsvc_lock;
111 1.11 fvdl #endif
112 1.13 lukem
113 1.13 lukem _DIAGASSERT(rqst != NULL);
114 1.13 lukem _DIAGASSERT(msg != NULL);
115 1.9 lukem
116 1.11 fvdl /* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
117 1.1 cgd
118 1.1 cgd rqst->rq_cred = msg->rm_call.cb_cred;
119 1.1 cgd rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
120 1.1 cgd rqst->rq_xprt->xp_verf.oa_length = 0;
121 1.1 cgd cred_flavor = rqst->rq_cred.oa_flavor;
122 1.11 fvdl switch (cred_flavor) {
123 1.11 fvdl case AUTH_NULL:
124 1.11 fvdl dummy = _svcauth_null(rqst, msg);
125 1.11 fvdl return (dummy);
126 1.11 fvdl case AUTH_SYS:
127 1.11 fvdl dummy = _svcauth_unix(rqst, msg);
128 1.11 fvdl return (dummy);
129 1.11 fvdl case AUTH_SHORT:
130 1.11 fvdl dummy = _svcauth_short(rqst, msg);
131 1.11 fvdl return (dummy);
132 1.11 fvdl #if 0
133 1.11 fvdl case AUTH_DES:
134 1.11 fvdl dummy = __svcauth_des(rqst, msg);
135 1.11 fvdl return (dummy);
136 1.11 fvdl #endif
137 1.11 fvdl default:
138 1.11 fvdl break;
139 1.11 fvdl }
140 1.11 fvdl
141 1.11 fvdl /* flavor doesn't match any of the builtin types, so try new ones */
142 1.11 fvdl mutex_lock(&authsvc_lock);
143 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
144 1.11 fvdl if (asp->flavor == cred_flavor) {
145 1.11 fvdl enum auth_stat as;
146 1.11 fvdl
147 1.11 fvdl as = (*asp->handler)(rqst, msg);
148 1.11 fvdl mutex_unlock(&authsvc_lock);
149 1.11 fvdl return (as);
150 1.11 fvdl }
151 1.1 cgd }
152 1.11 fvdl mutex_unlock(&authsvc_lock);
153 1.1 cgd
154 1.1 cgd return (AUTH_REJECTEDCRED);
155 1.1 cgd }
156 1.1 cgd
157 1.11 fvdl /*ARGSUSED*/
158 1.1 cgd enum auth_stat
159 1.15.56.1 yamt _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg)
160 1.1 cgd {
161 1.11 fvdl return (AUTH_OK);
162 1.11 fvdl }
163 1.11 fvdl
164 1.11 fvdl /*
165 1.11 fvdl * Allow the rpc service to register new authentication types that it is
166 1.11 fvdl * prepared to handle. When an authentication flavor is registered,
167 1.11 fvdl * the flavor is checked against already registered values. If not
168 1.11 fvdl * registered, then a new Auths entry is added on the list.
169 1.11 fvdl *
170 1.11 fvdl * There is no provision to delete a registration once registered.
171 1.11 fvdl *
172 1.11 fvdl * This routine returns:
173 1.11 fvdl * 0 if registration successful
174 1.11 fvdl * 1 if flavor already registered
175 1.11 fvdl * -1 if can't register (errno set)
176 1.11 fvdl */
177 1.11 fvdl
178 1.11 fvdl int
179 1.15.56.1 yamt svc_auth_reg(
180 1.15.56.1 yamt int cred_flavor,
181 1.15.56.1 yamt enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *))
182 1.11 fvdl {
183 1.12 christos struct authsvc *asp;
184 1.14 thorpej #ifdef _REENTRANT
185 1.11 fvdl extern mutex_t authsvc_lock;
186 1.11 fvdl #endif
187 1.1 cgd
188 1.11 fvdl switch (cred_flavor) {
189 1.11 fvdl case AUTH_NULL:
190 1.11 fvdl case AUTH_SYS:
191 1.11 fvdl case AUTH_SHORT:
192 1.11 fvdl #if 0
193 1.11 fvdl case AUTH_DES:
194 1.11 fvdl #endif
195 1.11 fvdl /* already registered */
196 1.11 fvdl return (1);
197 1.11 fvdl
198 1.11 fvdl default:
199 1.11 fvdl mutex_lock(&authsvc_lock);
200 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
201 1.11 fvdl if (asp->flavor == cred_flavor) {
202 1.11 fvdl /* already registered */
203 1.11 fvdl mutex_unlock(&authsvc_lock);
204 1.11 fvdl return (1);
205 1.11 fvdl }
206 1.11 fvdl }
207 1.11 fvdl
208 1.11 fvdl /* this is a new one, so go ahead and register it */
209 1.12 christos asp = mem_alloc(sizeof (*asp));
210 1.11 fvdl if (asp == NULL) {
211 1.11 fvdl mutex_unlock(&authsvc_lock);
212 1.11 fvdl return (-1);
213 1.11 fvdl }
214 1.11 fvdl asp->flavor = cred_flavor;
215 1.11 fvdl asp->handler = handler;
216 1.11 fvdl asp->next = Auths;
217 1.11 fvdl Auths = asp;
218 1.11 fvdl mutex_unlock(&authsvc_lock);
219 1.11 fvdl break;
220 1.11 fvdl }
221 1.11 fvdl return (0);
222 1.1 cgd }
223