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