update from main archive 961009
[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 <limits.h>
47 #include <stdio.h>
48 #include <unistd.h>
49 #include <sys/param.h>
50
51 #include <rpc/types.h>
52 #include <rpc/xdr.h>
53 #include <rpc/auth.h>
54 #include <rpc/auth_unix.h>
55
56 /*
57  * Unix authenticator operations vector
58  */
59 static void     authunix_nextverf();
60 static bool_t   authunix_marshal();
61 static bool_t   authunix_validate();
62 static bool_t   authunix_refresh();
63 static void     authunix_destroy();
64
65 static struct auth_ops auth_unix_ops = {
66         authunix_nextverf,
67         authunix_marshal,
68         authunix_validate,
69         authunix_refresh,
70         authunix_destroy
71 };
72
73 /*
74  * This struct is pointed to by the ah_private field of an auth_handle.
75  */
76 struct audata {
77         struct opaque_auth      au_origcred;    /* original credentials */
78         struct opaque_auth      au_shcred;      /* short hand cred */
79         u_long                  au_shfaults;    /* short hand cache faults */
80         char                    au_marshed[MAX_AUTH_BYTES];
81         u_int                   au_mpos;        /* xdr pos at end of marshed */
82 };
83 #define AUTH_PRIVATE(auth)      ((struct audata *)auth->ah_private)
84
85 static bool_t marshal_new_auth();
86
87
88 /*
89  * Create a unix style authenticator.
90  * Returns an auth handle with the given stuff in it.
91  */
92 AUTH *
93 authunix_create(machname, uid, gid, len, aup_gids)
94         char *machname;
95         int uid;
96         int gid;
97         register int len;
98         int *aup_gids;
99 {
100         struct authunix_parms aup;
101         char mymem[MAX_AUTH_BYTES];
102         struct timeval now;
103         XDR xdrs;
104         register AUTH *auth;
105         register struct audata *au;
106
107         /*
108          * Allocate and set up auth handle
109          */
110         auth = (AUTH *)mem_alloc(sizeof(*auth));
111 #ifndef KERNEL
112         if (auth == NULL) {
113                 (void)fprintf(stderr, "authunix_create: out of memory\n");
114                 return (NULL);
115         }
116 #endif
117         au = (struct audata *)mem_alloc(sizeof(*au));
118 #ifndef KERNEL
119         if (au == NULL) {
120                 (void)fprintf(stderr, "authunix_create: out of memory\n");
121                 return (NULL);
122         }
123 #endif
124         auth->ah_ops = &auth_unix_ops;
125         auth->ah_private = (caddr_t)au;
126         auth->ah_verf = au->au_shcred = _null_auth;
127         au->au_shfaults = 0;
128
129         /*
130          * fill in param struct from the given params
131          */
132         (void)gettimeofday(&now,  (struct timezone *)0);
133         aup.aup_time = now.tv_sec;
134         aup.aup_machname = machname;
135         aup.aup_uid = uid;
136         aup.aup_gid = gid;
137         aup.aup_len = (u_int)len;
138         aup.aup_gids = aup_gids;
139
140         /*
141          * Serialize the parameters into origcred
142          */
143         xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
144         if (! xdr_authunix_parms(&xdrs, &aup))
145                 abort();
146         au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
147         au->au_origcred.oa_flavor = AUTH_UNIX;
148 #ifdef KERNEL
149         au->au_origcred.oa_base = mem_alloc((u_int) len);
150 #else
151         if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
152                 (void)fprintf(stderr, "authunix_create: out of memory\n");
153                 return (NULL);
154         }
155 #endif
156         bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
157
158         /*
159          * set auth handle to reflect new cred.
160          */
161         auth->ah_cred = au->au_origcred;
162         marshal_new_auth(auth);
163         return (auth);
164 }
165
166 /*
167  * Returns an auth handle with parameters determined by doing lots of
168  * syscalls.
169  */
170 AUTH *
171 authunix_create_default()
172 {
173         register int len;
174         char machname[MAX_MACHINE_NAME + 1];
175         register int uid;
176         register int gid;
177         int max_nr_groups = sysconf (_SC_NGROUPS_MAX);
178         gid_t gids[max_nr_groups];
179
180         if (gethostname(machname, MAX_MACHINE_NAME) == -1)
181                 abort();
182         machname[MAX_MACHINE_NAME] = 0;
183         uid = geteuid();
184         gid = getegid();
185
186         if ((len = getgroups(max_nr_groups, gids)) < 0)
187                 abort();
188         /* This braindamaged Sun code forces us here to truncate the
189            list of groups to NGRPS members since the code in
190            authuxprot.c transforms a fixed array.  Grrr.  */
191         return (authunix_create(machname, uid, gid, MIN (NGRPS, len), gids));
192 }
193
194 /*
195  * authunix operations
196  */
197
198 static void
199 authunix_nextverf(auth)
200         AUTH *auth;
201 {
202         /* no action necessary */
203 }
204
205 static bool_t
206 authunix_marshal(auth, xdrs)
207         AUTH *auth;
208         XDR *xdrs;
209 {
210         register struct audata *au = AUTH_PRIVATE(auth);
211
212         return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
213 }
214
215 static bool_t
216 authunix_validate(auth, verf)
217         register AUTH *auth;
218         struct opaque_auth verf;
219 {
220         register struct audata *au;
221         XDR xdrs;
222
223         if (verf.oa_flavor == AUTH_SHORT) {
224                 au = AUTH_PRIVATE(auth);
225                 xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
226
227                 if (au->au_shcred.oa_base != NULL) {
228                         mem_free(au->au_shcred.oa_base,
229                             au->au_shcred.oa_length);
230                         au->au_shcred.oa_base = NULL;
231                 }
232                 if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
233                         auth->ah_cred = au->au_shcred;
234                 } else {
235                         xdrs.x_op = XDR_FREE;
236                         (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
237                         au->au_shcred.oa_base = NULL;
238                         auth->ah_cred = au->au_origcred;
239                 }
240                 marshal_new_auth(auth);
241         }
242         return (TRUE);
243 }
244
245 static bool_t
246 authunix_refresh(auth)
247         register AUTH *auth;
248 {
249         register struct audata *au = AUTH_PRIVATE(auth);
250         struct authunix_parms aup;
251         struct timeval now;
252         XDR xdrs;
253         register int stat;
254
255         if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
256                 /* there is no hope.  Punt */
257                 return (FALSE);
258         }
259         au->au_shfaults ++;
260
261         /* first deserialize the creds back into a struct authunix_parms */
262         aup.aup_machname = NULL;
263         aup.aup_gids = (int *)NULL;
264         xdrmem_create(&xdrs, au->au_origcred.oa_base,
265             au->au_origcred.oa_length, XDR_DECODE);
266         stat = xdr_authunix_parms(&xdrs, &aup);
267         if (! stat)
268                 goto done;
269
270         /* update the time and serialize in place */
271         (void)gettimeofday(&now, (struct timezone *)0);
272         aup.aup_time = now.tv_sec;
273         xdrs.x_op = XDR_ENCODE;
274         XDR_SETPOS(&xdrs, 0);
275         stat = xdr_authunix_parms(&xdrs, &aup);
276         if (! stat)
277                 goto done;
278         auth->ah_cred = au->au_origcred;
279         marshal_new_auth(auth);
280 done:
281         /* free the struct authunix_parms created by deserializing */
282         xdrs.x_op = XDR_FREE;
283         (void)xdr_authunix_parms(&xdrs, &aup);
284         XDR_DESTROY(&xdrs);
285         return (stat);
286 }
287
288 static void
289 authunix_destroy(auth)
290         register AUTH *auth;
291 {
292         register struct audata *au = AUTH_PRIVATE(auth);
293
294         mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
295
296         if (au->au_shcred.oa_base != NULL)
297                 mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
298
299         mem_free(auth->ah_private, sizeof(struct audata));
300
301         if (auth->ah_verf.oa_base != NULL)
302                 mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
303
304         mem_free((caddr_t)auth, sizeof(*auth));
305 }
306
307 /*
308  * Marshals (pre-serializes) an auth struct.
309  * sets private data, au_marshed and au_mpos
310  */
311 static bool_t
312 marshal_new_auth(auth)
313         register AUTH *auth;
314 {
315         XDR             xdr_stream;
316         register XDR    *xdrs = &xdr_stream;
317         register struct audata *au = AUTH_PRIVATE(auth);
318
319         xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
320         if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
321             (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
322                 perror(_("auth_none.c - Fatal marshalling problem"));
323         } else {
324                 au->au_mpos = XDR_GETPOS(xdrs);
325         }
326         XDR_DESTROY(xdrs);
327 }