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