import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / port / nsl / auth_sys.c
blob3cec9dd585e866ea30a8e5c4e3d4978332028675
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * Portions of this source code were derived from Berkeley
30 * 4.3 BSD under license from the Regents of the University of
31 * California.
35 * auth_sys.c, Implements UNIX (system) style authentication parameters.
37 * The system is very weak. The client uses no encryption for its
38 * credentials and only sends null verifiers. The server sends backs
39 * null verifiers or optionally a verifier that suggests a new short hand
40 * for the credentials.
43 #include "mt.h"
44 #include "rpc_mt.h"
45 #include <alloca.h>
46 #include <stdio.h>
47 #include <syslog.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <string.h>
51 #include <rpc/types.h>
52 #include <rpc/xdr.h>
53 #include <rpc/auth.h>
54 #include <rpc/auth_sys.h>
55 #include <synch.h>
57 extern int gethostname(char *, int);
58 extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
60 static struct auth_ops *authsys_ops(void);
63 * This struct is pointed to by the ah_private field of an auth_handle.
65 struct audata {
66 struct opaque_auth au_origcred; /* original credentials */
67 struct opaque_auth au_shcred; /* short hand cred */
68 uint_t au_shfaults; /* short hand cache faults */
69 char au_marshed[MAX_AUTH_BYTES];
70 uint_t au_mpos; /* xdr pos at end of marshed */
72 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
74 static void marshal_new_auth();
76 static const char auth_sys_str[] = "%s : %s";
77 static const char authsys_create_str[] = "authsys_create";
78 static const char __no_mem_auth[] = "out of memory";
81 * Create a (sys) unix style authenticator.
82 * Returns an auth handle with the given stuff in it.
84 AUTH *
85 authsys_create(const char *machname, const uid_t uid, const gid_t gid,
86 const int len, const gid_t *aup_gids)
88 struct authsys_parms aup;
89 char mymem[MAX_AUTH_BYTES];
90 struct timeval now;
91 XDR xdrs;
92 AUTH *auth;
93 struct audata *au;
96 * Allocate and set up auth handle
98 auth = malloc(sizeof (*auth));
99 if (auth == NULL) {
100 (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
101 __no_mem_auth);
102 return (NULL);
104 au = malloc(sizeof (*au));
105 if (au == NULL) {
106 (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
107 __no_mem_auth);
108 free(auth);
109 return (NULL);
111 auth->ah_ops = authsys_ops();
112 auth->ah_private = (caddr_t)au;
113 auth->ah_verf = au->au_shcred = _null_auth;
114 au->au_shfaults = 0;
117 * fill in param struct from the given params
119 (void) gettimeofday(&now, NULL);
120 aup.aup_time = now.tv_sec;
121 aup.aup_machname = (char *)machname;
122 aup.aup_uid = uid;
123 aup.aup_gid = gid;
124 aup.aup_len = (uint_t)len;
125 aup.aup_gids = (gid_t *)aup_gids;
128 * Serialize the parameters into origcred
130 xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
131 if (!xdr_authsys_parms(&xdrs, &aup)) {
132 (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
133 ": xdr_authsys_parms failed");
134 return (NULL);
136 au->au_origcred.oa_length = XDR_GETPOS(&xdrs);
137 au->au_origcred.oa_flavor = AUTH_SYS;
138 if ((au->au_origcred.oa_base = malloc(au->au_origcred.oa_length)) ==
139 NULL) {
140 (void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
141 __no_mem_auth);
142 free(au);
143 free(auth);
144 return (NULL);
146 (void) memcpy(au->au_origcred.oa_base, mymem,
147 (size_t)au->au_origcred.oa_length);
150 * set auth handle to reflect new cred.
152 auth->ah_cred = au->au_origcred;
153 (void) marshal_new_auth(auth);
154 return (auth);
158 * authsys_create_default is a public interface.
160 * Returns an auth handle with parameters determined by doing lots of
161 * syscalls.
164 static const char authsys_def_str[] =
165 "authsys_create_default: get%s failed: %m";
167 AUTH *
168 authsys_create_default(void)
170 int len;
171 char machname[MAX_MACHINE_NAME + 1];
172 uid_t uid;
173 gid_t gid;
174 int maxgrp = getgroups(0, NULL);
175 gid_t *gids = alloca(maxgrp * sizeof (gid_t));
177 if (gethostname(machname, MAX_MACHINE_NAME) == -1) {
178 (void) syslog(LOG_ERR, authsys_def_str, "hostname");
179 return (NULL);
181 machname[MAX_MACHINE_NAME] = 0;
182 uid = geteuid();
183 gid = getegid();
184 if ((len = getgroups(maxgrp, gids)) < 0) {
185 (void) syslog(LOG_ERR, authsys_def_str, "groups");
186 return (NULL);
188 if (len > NGRPS)
189 len = NGRPS;
190 return (authsys_create(machname, uid, gid, len, gids));
194 * authsys_create_ruid() is a private routine and is a
195 * variant of authsys_create_default().
197 * authsys_create_default() is using the effective uid.
198 * authsys_create_ruid() is using the real uid.
200 * This routine is used by key_call_ext() in key_call.c
202 AUTH *
203 authsys_create_ruid(void)
205 int len;
206 char machname[MAX_MACHINE_NAME + 1];
207 uid_t uid;
208 gid_t gid;
209 int maxgrp = getgroups(0, NULL);
210 gid_t *gids = alloca(maxgrp * sizeof (gid_t));
211 AUTH *res;
213 if (gethostname(machname, MAX_MACHINE_NAME) == -1) {
214 (void) syslog(LOG_ERR,
215 "authsys_create_ruid:gethostname failed");
216 return (NULL);
218 machname[MAX_MACHINE_NAME] = 0;
219 uid = getuid();
220 gid = getgid();
221 if ((len = getgroups(maxgrp, gids)) < 0) {
222 (void) syslog(LOG_ERR,
223 "authsys_create_ruid:getgroups failed");
224 return (NULL);
226 if (len > NGRPS)
227 len = NGRPS;
228 res = authsys_create(machname, uid, gid, len, gids);
229 return (res);
233 * authsys operations
236 /*ARGSUSED*/
237 static void
238 authsys_nextverf(AUTH *auth)
240 /* no action necessary */
243 static bool_t
244 authsys_marshal(AUTH *auth, XDR *xdrs)
246 /* LINTED pointer alignment */
247 struct audata *au = AUTH_PRIVATE(auth);
249 return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
252 static bool_t
253 authsys_validate(AUTH *auth, struct opaque_auth *verf)
255 struct audata *au;
256 XDR xdrs;
258 if (verf->oa_flavor == AUTH_SHORT) {
259 /* LINTED pointer alignment */
260 au = AUTH_PRIVATE(auth);
261 xdrmem_create(&xdrs, verf->oa_base,
262 verf->oa_length, XDR_DECODE);
264 if (au->au_shcred.oa_base != NULL) {
265 free(au->au_shcred.oa_base);
266 au->au_shcred.oa_base = NULL;
268 if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
269 auth->ah_cred = au->au_shcred;
270 } else {
271 xdrs.x_op = XDR_FREE;
272 (void) xdr_opaque_auth(&xdrs, &au->au_shcred);
273 au->au_shcred.oa_base = NULL;
274 auth->ah_cred = au->au_origcred;
276 (void) marshal_new_auth(auth);
278 return (TRUE);
281 /*ARGSUSED*/
282 static bool_t
283 authsys_refresh(AUTH *auth, void *dummy)
285 /* LINTED pointer alignment */
286 struct audata *au = AUTH_PRIVATE(auth);
287 struct authsys_parms aup;
288 struct timeval now;
289 XDR xdrs;
290 int stat;
292 if (auth->ah_cred.oa_base == au->au_origcred.oa_base)
293 return (FALSE); /* there is no hope. Punt */
294 au->au_shfaults ++;
296 /* first deserialize the creds back into a struct authsys_parms */
297 aup.aup_machname = NULL;
298 aup.aup_gids = NULL;
299 xdrmem_create(&xdrs, au->au_origcred.oa_base,
300 au->au_origcred.oa_length, XDR_DECODE);
301 stat = xdr_authsys_parms(&xdrs, &aup);
302 if (!stat)
303 goto done;
305 /* update the time and serialize in place */
306 (void) gettimeofday(&now, NULL);
307 aup.aup_time = now.tv_sec;
308 xdrs.x_op = XDR_ENCODE;
309 XDR_SETPOS(&xdrs, 0);
310 stat = xdr_authsys_parms(&xdrs, &aup);
311 if (!stat)
312 goto done;
313 auth->ah_cred = au->au_origcred;
314 (void) marshal_new_auth(auth);
315 done:
316 /* free the struct authsys_parms created by deserializing */
317 xdrs.x_op = XDR_FREE;
318 (void) xdr_authsys_parms(&xdrs, &aup);
319 XDR_DESTROY(&xdrs);
320 return (stat);
323 static void
324 authsys_destroy(AUTH *auth)
326 /* LINTED pointer alignment */
327 struct audata *au = AUTH_PRIVATE(auth);
329 free(au->au_origcred.oa_base);
330 free(au->au_shcred.oa_base);
331 free(auth->ah_private);
332 free(auth->ah_verf.oa_base);
333 free(auth);
337 * Marshals (pre-serializes) an auth struct.
338 * sets private data, au_marshed and au_mpos
341 static const char marshal_new_auth_str[] =
342 "marshal_new_auth - Fatal marshalling problem";
343 static void
344 marshal_new_auth(AUTH *auth)
346 XDR xdr_stream;
347 XDR *xdrs = &xdr_stream;
348 /* LINTED pointer alignment */
349 struct audata *au = AUTH_PRIVATE(auth);
351 xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
352 if ((!xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
353 (!xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
354 (void) syslog(LOG_ERR, marshal_new_auth_str);
355 } else {
356 au->au_mpos = XDR_GETPOS(xdrs);
358 XDR_DESTROY(xdrs);
361 static struct auth_ops *
362 authsys_ops(void)
364 static struct auth_ops ops;
365 extern mutex_t ops_lock;
367 /* VARIABLES PROTECTED BY ops_lock: ops */
369 (void) mutex_lock(&ops_lock);
370 if (ops.ah_nextverf == NULL) {
371 ops.ah_nextverf = authsys_nextverf;
372 ops.ah_marshal = authsys_marshal;
373 ops.ah_validate = authsys_validate;
374 ops.ah_refresh = authsys_refresh;
375 ops.ah_destroy = authsys_destroy;
377 (void) mutex_unlock(&ops_lock);
378 return (&ops);