2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
25 * Sun Microsystems, Inc.
27 * Mountain View, California 94043
30 * Copyright (C) 1984, Sun Microsystems, Inc.
33 * auth_unix.c, Implements UNIX style authentication parameters.
35 * The system is very weak. The client uses no encryption for it's
36 * credentials and only sends null verifiers. The server sends backs
37 * null verifiers or optionally a verifier that suggests a new short hand
38 * for the credentials.
48 #include <sys/param.h>
50 #include <rpc/types.h>
53 #include <rpc/auth_unix.h>
60 * Unix authenticator operations vector
62 static void authunix_nextverf (AUTH *);
63 static bool_t authunix_marshal (AUTH *, XDR *);
64 static bool_t authunix_validate (AUTH *, struct opaque_auth *);
65 static bool_t authunix_refresh (AUTH *);
66 static void authunix_destroy (AUTH *);
68 static struct auth_ops auth_unix_ops = {
77 * This struct is pointed to by the ah_private field of an auth_handle.
80 struct opaque_auth au_origcred; /* original credentials */
81 struct opaque_auth au_shcred; /* short hand cred */
82 u_long au_shfaults; /* short hand cache faults */
83 char au_marshed[MAX_AUTH_BYTES];
84 u_int au_mpos; /* xdr pos at end of marshed */
86 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
88 static bool_t marshal_new_auth (AUTH *) internal_function;
92 * Create a unix style authenticator.
93 * Returns an auth handle with the given stuff in it.
96 authunix_create (char *machname, uid_t uid, gid_t gid, int len,
99 struct authunix_parms aup;
100 char mymem[MAX_AUTH_BYTES];
107 * Allocate and set up auth handle
109 auth = (AUTH *) mem_alloc (sizeof (*auth));
110 au = (struct audata *) mem_alloc (sizeof (*au));
111 if (auth == NULL || au == NULL)
114 (void) __fxprintf (NULL, "%s", L"%s",
115 _("authunix_create: out of memory\n"));
116 mem_free (auth, sizeof (*auth));
117 mem_free (au, sizeof (*au));
120 auth->ah_ops = &auth_unix_ops;
121 auth->ah_private = (caddr_t) au;
122 auth->ah_verf = au->au_shcred = _null_auth;
126 * fill in param struct from the given params
128 (void) __gettimeofday (&now, (struct timezone *) 0);
129 aup.aup_time = now.tv_sec;
130 aup.aup_machname = machname;
133 aup.aup_len = (u_int) len;
134 aup.aup_gids = aup_gids;
137 * Serialize the parameters into origcred
139 INTUSE(xdrmem_create) (&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
140 if (!INTUSE(xdr_authunix_parms) (&xdrs, &aup))
142 au->au_origcred.oa_length = len = XDR_GETPOS (&xdrs);
143 au->au_origcred.oa_flavor = AUTH_UNIX;
144 au->au_origcred.oa_base = mem_alloc ((u_int) len);
145 if (au->au_origcred.oa_base == NULL)
147 memcpy(au->au_origcred.oa_base, mymem, (u_int) len);
150 * set auth handle to reflect new cred.
152 auth->ah_cred = au->au_origcred;
153 marshal_new_auth (auth);
156 INTDEF (authunix_create)
159 * Returns an auth handle with parameters determined by doing lots of
163 authunix_create_default (void)
165 char machname[MAX_MACHINE_NAME + 1];
167 if (__gethostname (machname, MAX_MACHINE_NAME) == -1)
169 machname[MAX_MACHINE_NAME] = 0;
170 uid_t uid = __geteuid ();
171 gid_t gid = __getegid ();
174 /* When we have to try a second time, do not use alloca() again. We
175 might have reached the stack limit already. */
178 /* Ask the kernel how many groups there are exactly. Note that we
179 might have to redo all this if the number of groups has changed
180 between the two calls. */
181 max_nr_groups = __getgroups (0, NULL);
183 /* Just some random reasonable stack limit. */
184 #define ALLOCA_LIMIT (1024 / sizeof (gid_t))
186 if (max_nr_groups < ALLOCA_LIMIT && ! retry)
187 gids = (gid_t *) alloca (max_nr_groups * sizeof (gid_t));
190 gids = (gid_t *) malloc (max_nr_groups * sizeof (gid_t));
195 int len = __getgroups (max_nr_groups, gids);
200 /* New groups added in the meantime. Try again. */
201 if (max_nr_groups >= ALLOCA_LIMIT || retry)
206 /* No other error can happen. */
210 /* This braindamaged Sun code forces us here to truncate the
211 list of groups to NGRPS members since the code in
212 authuxprot.c transforms a fixed array. Grrr. */
213 AUTH *result = INTUSE(authunix_create) (machname, uid, gid, MIN (NGRPS, len),
216 if (max_nr_groups >= ALLOCA_LIMIT || retry)
221 INTDEF (authunix_create_default)
224 * authunix operations
228 authunix_nextverf (AUTH *auth)
230 /* no action necessary */
234 authunix_marshal (AUTH *auth, XDR *xdrs)
236 struct audata *au = AUTH_PRIVATE (auth);
238 return XDR_PUTBYTES (xdrs, au->au_marshed, au->au_mpos);
242 authunix_validate (AUTH *auth, struct opaque_auth *verf)
247 if (verf->oa_flavor == AUTH_SHORT)
249 au = AUTH_PRIVATE (auth);
250 INTUSE(xdrmem_create) (&xdrs, verf->oa_base, verf->oa_length,
253 if (au->au_shcred.oa_base != NULL)
255 mem_free (au->au_shcred.oa_base,
256 au->au_shcred.oa_length);
257 au->au_shcred.oa_base = NULL;
259 if (INTUSE(xdr_opaque_auth) (&xdrs, &au->au_shcred))
261 auth->ah_cred = au->au_shcred;
265 xdrs.x_op = XDR_FREE;
266 (void) INTUSE(xdr_opaque_auth) (&xdrs, &au->au_shcred);
267 au->au_shcred.oa_base = NULL;
268 auth->ah_cred = au->au_origcred;
270 marshal_new_auth (auth);
276 authunix_refresh (AUTH *auth)
278 struct audata *au = AUTH_PRIVATE (auth);
279 struct authunix_parms aup;
284 if (auth->ah_cred.oa_base == au->au_origcred.oa_base)
286 /* there is no hope. Punt */
291 /* first deserialize the creds back into a struct authunix_parms */
292 aup.aup_machname = NULL;
293 aup.aup_gids = (gid_t *) NULL;
294 INTUSE(xdrmem_create) (&xdrs, au->au_origcred.oa_base,
295 au->au_origcred.oa_length, XDR_DECODE);
296 stat = INTUSE(xdr_authunix_parms) (&xdrs, &aup);
300 /* update the time and serialize in place */
301 (void) __gettimeofday (&now, (struct timezone *) 0);
302 aup.aup_time = now.tv_sec;
303 xdrs.x_op = XDR_ENCODE;
304 XDR_SETPOS (&xdrs, 0);
305 stat = INTUSE(xdr_authunix_parms) (&xdrs, &aup);
308 auth->ah_cred = au->au_origcred;
309 marshal_new_auth (auth);
311 /* free the struct authunix_parms created by deserializing */
312 xdrs.x_op = XDR_FREE;
313 (void) INTUSE(xdr_authunix_parms) (&xdrs, &aup);
319 authunix_destroy (AUTH *auth)
321 struct audata *au = AUTH_PRIVATE (auth);
323 mem_free (au->au_origcred.oa_base, au->au_origcred.oa_length);
325 if (au->au_shcred.oa_base != NULL)
326 mem_free (au->au_shcred.oa_base, au->au_shcred.oa_length);
328 mem_free (auth->ah_private, sizeof (struct audata));
330 if (auth->ah_verf.oa_base != NULL)
331 mem_free (auth->ah_verf.oa_base, auth->ah_verf.oa_length);
333 mem_free ((caddr_t) auth, sizeof (*auth));
337 * Marshals (pre-serializes) an auth struct.
338 * sets private data, au_marshed and au_mpos
342 marshal_new_auth (AUTH *auth)
345 XDR *xdrs = &xdr_stream;
346 struct audata *au = AUTH_PRIVATE (auth);
348 INTUSE(xdrmem_create) (xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
349 if ((!INTUSE(xdr_opaque_auth) (xdrs, &(auth->ah_cred))) ||
350 (!INTUSE(xdr_opaque_auth) (xdrs, &(auth->ah_verf))))
351 perror (_("auth_none.c - Fatal marshalling problem"));
353 au->au_mpos = XDR_GETPOS (xdrs);