auth_unix.c revision 1.3.2.1 1 /* $NetBSD: auth_unix.c,v 1.3.2.1 1996/09/16 23:44:17 jtc Exp $ */
2
3 /*
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
10 *
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 *
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
18 *
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
22 *
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
26 *
27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue
29 * Mountain View, California 94043
30 */
31
32 #if defined(LIBC_SCCS) && !defined(lint)
33 /*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
34 /*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
35 static char *rcsid = "$NetBSD: auth_unix.c,v 1.3.2.1 1996/09/16 23:44:17 jtc Exp $";
36 #endif
37
38 /*
39 * auth_unix.c, Implements UNIX style authentication parameters.
40 *
41 * Copyright (C) 1984, Sun Microsystems, Inc.
42 *
43 * The system is very weak. The client uses no encryption for it's
44 * credentials and only sends null verifiers. The server sends backs
45 * null verifiers or optionally a verifier that suggests a new short hand
46 * for the credentials.
47 *
48 */
49
50 #include "namespace.h"
51 #include <stdio.h>
52 #include <stdlib.h>
53
54 #include <rpc/types.h>
55 #include <rpc/xdr.h>
56 #include <rpc/auth.h>
57 #include <rpc/auth_unix.h>
58
59 #ifdef __weak_alias
60 __weak_alias(authunix_create,_authunix_create);
61 __weak_alias(authunix_create_default,_authunix_create_default);
62 #endif
63
64 /*
65 * Unix authenticator operations vector
66 */
67 static void authunix_nextverf();
68 static bool_t authunix_marshal();
69 static bool_t authunix_validate();
70 static bool_t authunix_refresh();
71 static void authunix_destroy();
72
73 static struct auth_ops auth_unix_ops = {
74 authunix_nextverf,
75 authunix_marshal,
76 authunix_validate,
77 authunix_refresh,
78 authunix_destroy
79 };
80
81 /*
82 * This struct is pointed to by the ah_private field of an auth_handle.
83 */
84 struct audata {
85 struct opaque_auth au_origcred; /* original credentials */
86 struct opaque_auth au_shcred; /* short hand cred */
87 u_long au_shfaults; /* short hand cache faults */
88 char au_marshed[MAX_AUTH_BYTES];
89 u_int au_mpos; /* xdr pos at end of marshed */
90 };
91 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
92
93 static void marshal_new_auth();
94
95
96 /*
97 * Create a unix style authenticator.
98 * Returns an auth handle with the given stuff in it.
99 */
100 AUTH *
101 authunix_create(machname, uid, gid, len, aup_gids)
102 char *machname;
103 int uid;
104 int gid;
105 register int len;
106 int *aup_gids;
107 {
108 struct authunix_parms aup;
109 char mymem[MAX_AUTH_BYTES];
110 struct timeval now;
111 XDR xdrs;
112 register AUTH *auth;
113 register struct audata *au;
114
115 /*
116 * Allocate and set up auth handle
117 */
118 auth = (AUTH *)mem_alloc(sizeof(*auth));
119 #ifndef KERNEL
120 if (auth == NULL) {
121 (void)fprintf(stderr, "authunix_create: out of memory\n");
122 return (NULL);
123 }
124 #endif
125 au = (struct audata *)mem_alloc(sizeof(*au));
126 #ifndef KERNEL
127 if (au == NULL) {
128 (void)fprintf(stderr, "authunix_create: out of memory\n");
129 return (NULL);
130 }
131 #endif
132 auth->ah_ops = &auth_unix_ops;
133 auth->ah_private = (caddr_t)au;
134 auth->ah_verf = au->au_shcred = _null_auth;
135 au->au_shfaults = 0;
136
137 /*
138 * fill in param struct from the given params
139 */
140 (void)gettimeofday(&now, (struct timezone *)0);
141 aup.aup_time = now.tv_sec;
142 aup.aup_machname = machname;
143 aup.aup_uid = uid;
144 aup.aup_gid = gid;
145 aup.aup_len = (u_int)len;
146 aup.aup_gids = aup_gids;
147
148 /*
149 * Serialize the parameters into origcred
150 */
151 xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
152 if (! xdr_authunix_parms(&xdrs, &aup))
153 abort();
154 au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
155 au->au_origcred.oa_flavor = AUTH_UNIX;
156 #ifdef KERNEL
157 au->au_origcred.oa_base = mem_alloc((u_int) len);
158 #else
159 if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
160 (void)fprintf(stderr, "authunix_create: out of memory\n");
161 return (NULL);
162 }
163 #endif
164 bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
165
166 /*
167 * set auth handle to reflect new cred.
168 */
169 auth->ah_cred = au->au_origcred;
170 marshal_new_auth(auth);
171 return (auth);
172 }
173
174 /*
175 * Returns an auth handle with parameters determined by doing lots of
176 * syscalls.
177 */
178 AUTH *
179 authunix_create_default()
180 {
181 register int len;
182 char machname[MAX_MACHINE_NAME + 1];
183 register int uid;
184 register int gid;
185 int gids[NGRPS];
186
187 if (gethostname(machname, MAX_MACHINE_NAME) == -1)
188 abort();
189 machname[MAX_MACHINE_NAME] = 0;
190 uid = geteuid();
191 gid = getegid();
192 if ((len = getgroups(NGRPS, gids)) < 0)
193 abort();
194 return (authunix_create(machname, uid, gid, len, gids));
195 }
196
197 /*
198 * authunix operations
199 */
200
201 static void
202 authunix_nextverf(auth)
203 AUTH *auth;
204 {
205 /* no action necessary */
206 }
207
208 static bool_t
209 authunix_marshal(auth, xdrs)
210 AUTH *auth;
211 XDR *xdrs;
212 {
213 register struct audata *au = AUTH_PRIVATE(auth);
214
215 return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
216 }
217
218 static bool_t
219 authunix_validate(auth, verf)
220 register AUTH *auth;
221 struct opaque_auth verf;
222 {
223 register struct audata *au;
224 XDR xdrs;
225
226 if (verf.oa_flavor == AUTH_SHORT) {
227 au = AUTH_PRIVATE(auth);
228 xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
229
230 if (au->au_shcred.oa_base != NULL) {
231 mem_free(au->au_shcred.oa_base,
232 au->au_shcred.oa_length);
233 au->au_shcred.oa_base = NULL;
234 }
235 if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
236 auth->ah_cred = au->au_shcred;
237 } else {
238 xdrs.x_op = XDR_FREE;
239 (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
240 au->au_shcred.oa_base = NULL;
241 auth->ah_cred = au->au_origcred;
242 }
243 marshal_new_auth(auth);
244 }
245 return (TRUE);
246 }
247
248 static bool_t
249 authunix_refresh(auth)
250 register AUTH *auth;
251 {
252 register struct audata *au = AUTH_PRIVATE(auth);
253 struct authunix_parms aup;
254 struct timeval now;
255 XDR xdrs;
256 register int stat;
257
258 if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
259 /* there is no hope. Punt */
260 return (FALSE);
261 }
262 au->au_shfaults ++;
263
264 /* first deserialize the creds back into a struct authunix_parms */
265 aup.aup_machname = NULL;
266 aup.aup_gids = (int *)NULL;
267 xdrmem_create(&xdrs, au->au_origcred.oa_base,
268 au->au_origcred.oa_length, XDR_DECODE);
269 stat = xdr_authunix_parms(&xdrs, &aup);
270 if (! stat)
271 goto done;
272
273 /* update the time and serialize in place */
274 (void)gettimeofday(&now, (struct timezone *)0);
275 aup.aup_time = now.tv_sec;
276 xdrs.x_op = XDR_ENCODE;
277 XDR_SETPOS(&xdrs, 0);
278 stat = xdr_authunix_parms(&xdrs, &aup);
279 if (! stat)
280 goto done;
281 auth->ah_cred = au->au_origcred;
282 marshal_new_auth(auth);
283 done:
284 /* free the struct authunix_parms created by deserializing */
285 xdrs.x_op = XDR_FREE;
286 (void)xdr_authunix_parms(&xdrs, &aup);
287 XDR_DESTROY(&xdrs);
288 return (stat);
289 }
290
291 static void
292 authunix_destroy(auth)
293 register AUTH *auth;
294 {
295 register struct audata *au = AUTH_PRIVATE(auth);
296
297 mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
298
299 if (au->au_shcred.oa_base != NULL)
300 mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
301
302 mem_free(auth->ah_private, sizeof(struct audata));
303
304 if (auth->ah_verf.oa_base != NULL)
305 mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
306
307 mem_free((caddr_t)auth, sizeof(*auth));
308 }
309
310 /*
311 * Marshals (pre-serializes) an auth struct.
312 * sets private data, au_marshed and au_mpos
313 */
314 static void
315 marshal_new_auth(auth)
316 register AUTH *auth;
317 {
318 XDR xdr_stream;
319 register XDR *xdrs = &xdr_stream;
320 register struct audata *au = AUTH_PRIVATE(auth);
321
322 xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
323 if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
324 (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
325 perror("auth_none.c - Fatal marshalling problem");
326 } else {
327 au->au_mpos = XDR_GETPOS(xdrs);
328 }
329 XDR_DESTROY(xdrs);
330 }
331