svc_auth.c revision 1.16.2.1 1 1.16.2.1 tls /* $NetBSD: svc_auth.c,v 1.16.2.1 2013/06/23 06:21:05 tls Exp $ */
2 1.2 cgd
3 1.1 cgd /*
4 1.16.2.1 tls * Copyright (c) 2010, Oracle America, Inc.
5 1.16.2.1 tls *
6 1.16.2.1 tls * Redistribution and use in source and binary forms, with or without
7 1.16.2.1 tls * modification, are permitted provided that the following conditions are
8 1.16.2.1 tls * met:
9 1.16.2.1 tls *
10 1.16.2.1 tls * * Redistributions of source code must retain the above copyright
11 1.16.2.1 tls * notice, this list of conditions and the following disclaimer.
12 1.16.2.1 tls * * Redistributions in binary form must reproduce the above
13 1.16.2.1 tls * copyright notice, this list of conditions and the following
14 1.16.2.1 tls * disclaimer in the documentation and/or other materials
15 1.16.2.1 tls * provided with the distribution.
16 1.16.2.1 tls * * Neither the name of the "Oracle America, Inc." nor the names of its
17 1.16.2.1 tls * contributors may be used to endorse or promote products derived
18 1.16.2.1 tls * from this software without specific prior written permission.
19 1.16.2.1 tls *
20 1.16.2.1 tls * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 1.16.2.1 tls * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 1.16.2.1 tls * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 1.16.2.1 tls * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 1.16.2.1 tls * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 1.16.2.1 tls * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.16.2.1 tls * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 1.16.2.1 tls * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 1.16.2.1 tls * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 1.16.2.1 tls * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 1.16.2.1 tls * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 1.16.2.1 tls * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 cgd */
33 1.11 fvdl /*
34 1.11 fvdl * Copyright (c) 1986-1991 by Sun Microsystems Inc.
35 1.11 fvdl */
36 1.11 fvdl
37 1.11 fvdl /* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */
38 1.1 cgd
39 1.15 itojun #include <sys/cdefs.h>
40 1.15 itojun #if defined(LIBC_SCCS) && !defined(lint)
41 1.3 christos #if 0
42 1.11 fvdl static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
43 1.15 itojun #else
44 1.16.2.1 tls __RCSID("$NetBSD: svc_auth.c,v 1.16.2.1 2013/06/23 06:21:05 tls Exp $");
45 1.3 christos #endif
46 1.1 cgd #endif
47 1.1 cgd
48 1.1 cgd /*
49 1.11 fvdl * svc_auth.c, Server-side rpc authenticator interface.
50 1.1 cgd *
51 1.1 cgd */
52 1.1 cgd
53 1.11 fvdl #include "namespace.h"
54 1.11 fvdl #include "reentrant.h"
55 1.11 fvdl #include <sys/types.h>
56 1.11 fvdl #include <rpc/rpc.h>
57 1.13 lukem #include <assert.h>
58 1.11 fvdl #include <stdlib.h>
59 1.9 lukem
60 1.11 fvdl #ifdef __weak_alias
61 1.11 fvdl __weak_alias(svc_auth_reg,_svc_auth_reg)
62 1.11 fvdl #endif
63 1.1 cgd
64 1.1 cgd /*
65 1.11 fvdl * svcauthsw is the bdevsw of server side authentication.
66 1.11 fvdl *
67 1.1 cgd * Server side authenticators are called from authenticate by
68 1.1 cgd * using the client auth struct flavor field to index into svcauthsw.
69 1.11 fvdl * The server auth flavors must implement a routine that looks
70 1.11 fvdl * like:
71 1.11 fvdl *
72 1.1 cgd * enum auth_stat
73 1.1 cgd * flavorx_auth(rqst, msg)
74 1.12 christos * struct svc_req *rqst;
75 1.12 christos * struct rpc_msg *msg;
76 1.1 cgd *
77 1.1 cgd */
78 1.1 cgd
79 1.11 fvdl /* declarations to allow servers to specify new authentication flavors */
80 1.11 fvdl struct authsvc {
81 1.11 fvdl int flavor;
82 1.16 matt enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *);
83 1.11 fvdl struct authsvc *next;
84 1.1 cgd };
85 1.11 fvdl static struct authsvc *Auths = NULL;
86 1.1 cgd
87 1.1 cgd /*
88 1.1 cgd * The call rpc message, msg has been obtained from the wire. The msg contains
89 1.1 cgd * the raw form of credentials and verifiers. authenticate returns AUTH_OK
90 1.1 cgd * if the msg is successfully authenticated. If AUTH_OK then the routine also
91 1.1 cgd * does the following things:
92 1.1 cgd * set rqst->rq_xprt->verf to the appropriate response verifier;
93 1.1 cgd * sets rqst->rq_client_cred to the "cooked" form of the credentials.
94 1.1 cgd *
95 1.1 cgd * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
96 1.1 cgd * its length is set appropriately.
97 1.1 cgd *
98 1.1 cgd * The caller still owns and is responsible for msg->u.cmb.cred and
99 1.1 cgd * msg->u.cmb.verf. The authentication system retains ownership of
100 1.1 cgd * rqst->rq_client_cred, the cooked credentials.
101 1.1 cgd *
102 1.1 cgd * There is an assumption that any flavour less than AUTH_NULL is
103 1.1 cgd * invalid.
104 1.1 cgd */
105 1.1 cgd enum auth_stat
106 1.16 matt _authenticate(struct svc_req *rqst, struct rpc_msg *msg)
107 1.1 cgd {
108 1.12 christos int cred_flavor;
109 1.12 christos struct authsvc *asp;
110 1.11 fvdl enum auth_stat dummy;
111 1.14 thorpej #ifdef _REENTRANT
112 1.11 fvdl extern mutex_t authsvc_lock;
113 1.11 fvdl #endif
114 1.13 lukem
115 1.13 lukem _DIAGASSERT(rqst != NULL);
116 1.13 lukem _DIAGASSERT(msg != NULL);
117 1.9 lukem
118 1.11 fvdl /* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
119 1.1 cgd
120 1.1 cgd rqst->rq_cred = msg->rm_call.cb_cred;
121 1.1 cgd rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
122 1.1 cgd rqst->rq_xprt->xp_verf.oa_length = 0;
123 1.1 cgd cred_flavor = rqst->rq_cred.oa_flavor;
124 1.11 fvdl switch (cred_flavor) {
125 1.11 fvdl case AUTH_NULL:
126 1.11 fvdl dummy = _svcauth_null(rqst, msg);
127 1.11 fvdl return (dummy);
128 1.11 fvdl case AUTH_SYS:
129 1.11 fvdl dummy = _svcauth_unix(rqst, msg);
130 1.11 fvdl return (dummy);
131 1.11 fvdl case AUTH_SHORT:
132 1.11 fvdl dummy = _svcauth_short(rqst, msg);
133 1.11 fvdl return (dummy);
134 1.11 fvdl #if 0
135 1.11 fvdl case AUTH_DES:
136 1.11 fvdl dummy = __svcauth_des(rqst, msg);
137 1.11 fvdl return (dummy);
138 1.11 fvdl #endif
139 1.11 fvdl default:
140 1.11 fvdl break;
141 1.11 fvdl }
142 1.11 fvdl
143 1.11 fvdl /* flavor doesn't match any of the builtin types, so try new ones */
144 1.11 fvdl mutex_lock(&authsvc_lock);
145 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
146 1.11 fvdl if (asp->flavor == cred_flavor) {
147 1.11 fvdl enum auth_stat as;
148 1.11 fvdl
149 1.11 fvdl as = (*asp->handler)(rqst, msg);
150 1.11 fvdl mutex_unlock(&authsvc_lock);
151 1.11 fvdl return (as);
152 1.11 fvdl }
153 1.1 cgd }
154 1.11 fvdl mutex_unlock(&authsvc_lock);
155 1.1 cgd
156 1.1 cgd return (AUTH_REJECTEDCRED);
157 1.1 cgd }
158 1.1 cgd
159 1.11 fvdl /*ARGSUSED*/
160 1.1 cgd enum auth_stat
161 1.16 matt _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg)
162 1.1 cgd {
163 1.11 fvdl return (AUTH_OK);
164 1.11 fvdl }
165 1.11 fvdl
166 1.11 fvdl /*
167 1.11 fvdl * Allow the rpc service to register new authentication types that it is
168 1.11 fvdl * prepared to handle. When an authentication flavor is registered,
169 1.11 fvdl * the flavor is checked against already registered values. If not
170 1.11 fvdl * registered, then a new Auths entry is added on the list.
171 1.11 fvdl *
172 1.11 fvdl * There is no provision to delete a registration once registered.
173 1.11 fvdl *
174 1.11 fvdl * This routine returns:
175 1.11 fvdl * 0 if registration successful
176 1.11 fvdl * 1 if flavor already registered
177 1.11 fvdl * -1 if can't register (errno set)
178 1.11 fvdl */
179 1.11 fvdl
180 1.11 fvdl int
181 1.16 matt svc_auth_reg(
182 1.16 matt int cred_flavor,
183 1.16 matt enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *))
184 1.11 fvdl {
185 1.12 christos struct authsvc *asp;
186 1.14 thorpej #ifdef _REENTRANT
187 1.11 fvdl extern mutex_t authsvc_lock;
188 1.11 fvdl #endif
189 1.1 cgd
190 1.11 fvdl switch (cred_flavor) {
191 1.11 fvdl case AUTH_NULL:
192 1.11 fvdl case AUTH_SYS:
193 1.11 fvdl case AUTH_SHORT:
194 1.11 fvdl #if 0
195 1.11 fvdl case AUTH_DES:
196 1.11 fvdl #endif
197 1.11 fvdl /* already registered */
198 1.11 fvdl return (1);
199 1.11 fvdl
200 1.11 fvdl default:
201 1.11 fvdl mutex_lock(&authsvc_lock);
202 1.11 fvdl for (asp = Auths; asp; asp = asp->next) {
203 1.11 fvdl if (asp->flavor == cred_flavor) {
204 1.11 fvdl /* already registered */
205 1.11 fvdl mutex_unlock(&authsvc_lock);
206 1.11 fvdl return (1);
207 1.11 fvdl }
208 1.11 fvdl }
209 1.11 fvdl
210 1.11 fvdl /* this is a new one, so go ahead and register it */
211 1.12 christos asp = mem_alloc(sizeof (*asp));
212 1.11 fvdl if (asp == NULL) {
213 1.11 fvdl mutex_unlock(&authsvc_lock);
214 1.11 fvdl return (-1);
215 1.11 fvdl }
216 1.11 fvdl asp->flavor = cred_flavor;
217 1.11 fvdl asp->handler = handler;
218 1.11 fvdl asp->next = Auths;
219 1.11 fvdl Auths = asp;
220 1.11 fvdl mutex_unlock(&authsvc_lock);
221 1.11 fvdl break;
222 1.11 fvdl }
223 1.11 fvdl return (0);
224 1.1 cgd }
225