2 * Copyright (c) 2009, Sun Microsystems, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
28 * @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro
29 * @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC
30 * $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $
31 * $FreeBSD: src/lib/libc/rpc/auth_unix.c,v 1.18 2007/06/14 20:07:35 harti Exp $
35 * auth_unix.c, Implements UNIX style authentication parameters.
37 * Copyright (C) 1984, Sun Microsystems, Inc.
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.
46 #include "namespace.h"
47 #include "reentrant.h"
48 #include <sys/param.h>
57 #include <rpc/types.h>
60 #include <rpc/auth_unix.h>
61 #include "un-namespace.h"
65 static void authunix_destroy(AUTH
*);
66 static bool_t
authunix_marshal(AUTH
*, XDR
*);
67 static void authunix_nextverf(AUTH
*);
68 static struct auth_ops
*authunix_ops(void);
69 static bool_t
authunix_refresh(AUTH
*, void *);
70 static bool_t
authunix_validate(AUTH
*, struct opaque_auth
*);
71 static void marshal_new_auth(AUTH
*);
74 * This struct is pointed to by the ah_private field of an auth_handle.
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 */
83 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
86 * Create a unix style authenticator.
87 * Returns an auth handle with the given stuff in it.
90 authunix_create(char *machname
, int uid
, int gid
, int len
, int *aup_gids
)
92 struct authunix_parms aup
;
93 char mymem
[MAX_AUTH_BYTES
];
100 * Allocate and set up auth handle
103 auth
= mem_alloc(sizeof(*auth
));
106 warnx("authunix_create: out of memory");
107 goto cleanup_authunix_create
;
110 au
= mem_alloc(sizeof(*au
));
113 warnx("authunix_create: out of memory");
114 goto cleanup_authunix_create
;
117 auth
->ah_ops
= authunix_ops();
118 auth
->ah_private
= (caddr_t
)au
;
119 auth
->ah_verf
= au
->au_shcred
= _null_auth
;
121 au
->au_origcred
.oa_base
= NULL
;
124 * fill in param struct from the given params
126 gettimeofday(&now
, NULL
);
127 aup
.aup_time
= now
.tv_sec
;
128 aup
.aup_machname
= machname
;
131 aup
.aup_len
= (u_int
)len
;
132 aup
.aup_gids
= aup_gids
;
135 * Serialize the parameters into origcred
137 xdrmem_create(&xdrs
, mymem
, MAX_AUTH_BYTES
, XDR_ENCODE
);
138 if (! xdr_authunix_parms(&xdrs
, &aup
))
140 au
->au_origcred
.oa_length
= len
= XDR_GETPOS(&xdrs
);
141 au
->au_origcred
.oa_flavor
= AUTH_UNIX
;
143 au
->au_origcred
.oa_base
= mem_alloc((u_int
) len
);
145 if ((au
->au_origcred
.oa_base
= mem_alloc((u_int
) len
)) == NULL
) {
146 warnx("authunix_create: out of memory");
147 goto cleanup_authunix_create
;
150 memmove(au
->au_origcred
.oa_base
, mymem
, (size_t)len
);
153 * set auth handle to reflect new cred.
155 auth
->ah_cred
= au
->au_origcred
;
156 marshal_new_auth(auth
);
159 cleanup_authunix_create
:
161 mem_free(auth
, sizeof(*auth
));
163 if (au
->au_origcred
.oa_base
)
164 mem_free(au
->au_origcred
.oa_base
, (u_int
)len
);
165 mem_free(au
, sizeof(*au
));
172 * Returns an auth handle with parameters determined by doing lots of
176 authunix_create_default(void)
179 char machname
[MAXHOSTNAMELEN
+ 1];
182 gid_t gids
[NGROUPS_MAX
];
184 if (gethostname(machname
, sizeof machname
) == -1)
186 machname
[sizeof(machname
) - 1] = 0;
189 if ((len
= getgroups(NGROUPS_MAX
, gids
)) < 0)
193 /* XXX: interface problem; those should all have been unsigned */
194 return (authunix_create(machname
, (int)uid
, (int)gid
, len
,
199 * authunix operations
204 authunix_nextverf(AUTH
*auth __unused
)
206 /* no action necessary */
210 authunix_marshal(AUTH
*auth
, XDR
*xdrs
)
214 assert(auth
!= NULL
);
215 assert(xdrs
!= NULL
);
217 au
= AUTH_PRIVATE(auth
);
218 return (XDR_PUTBYTES(xdrs
, au
->au_marshed
, au
->au_mpos
));
222 authunix_validate(AUTH
*auth
, struct opaque_auth
*verf
)
227 assert(auth
!= NULL
);
228 assert(verf
!= NULL
);
230 if (verf
->oa_flavor
== AUTH_SHORT
) {
231 au
= AUTH_PRIVATE(auth
);
232 xdrmem_create(&xdrs
, verf
->oa_base
, verf
->oa_length
,
235 if (au
->au_shcred
.oa_base
!= NULL
) {
236 mem_free(au
->au_shcred
.oa_base
,
237 au
->au_shcred
.oa_length
);
238 au
->au_shcred
.oa_base
= NULL
;
240 if (xdr_opaque_auth(&xdrs
, &au
->au_shcred
)) {
241 auth
->ah_cred
= au
->au_shcred
;
243 xdrs
.x_op
= XDR_FREE
;
244 xdr_opaque_auth(&xdrs
, &au
->au_shcred
);
245 au
->au_shcred
.oa_base
= NULL
;
246 auth
->ah_cred
= au
->au_origcred
;
248 marshal_new_auth(auth
);
254 authunix_refresh(AUTH
*auth
, void *dummy __unused
)
256 struct audata
*au
= AUTH_PRIVATE(auth
);
257 struct authunix_parms aup
;
262 assert(auth
!= NULL
);
264 if (auth
->ah_cred
.oa_base
== au
->au_origcred
.oa_base
) {
265 /* there is no hope. Punt */
270 /* first deserialize the creds back into a struct authunix_parms */
271 aup
.aup_machname
= NULL
;
273 xdrmem_create(&xdrs
, au
->au_origcred
.oa_base
,
274 au
->au_origcred
.oa_length
, XDR_DECODE
);
275 stat
= xdr_authunix_parms(&xdrs
, &aup
);
279 /* update the time and serialize in place */
280 gettimeofday(&now
, NULL
);
281 aup
.aup_time
= now
.tv_sec
;
282 xdrs
.x_op
= XDR_ENCODE
;
283 XDR_SETPOS(&xdrs
, 0);
284 stat
= xdr_authunix_parms(&xdrs
, &aup
);
287 auth
->ah_cred
= au
->au_origcred
;
288 marshal_new_auth(auth
);
290 /* free the struct authunix_parms created by deserializing */
291 xdrs
.x_op
= XDR_FREE
;
292 xdr_authunix_parms(&xdrs
, &aup
);
298 authunix_destroy(AUTH
*auth
)
302 assert(auth
!= NULL
);
304 au
= AUTH_PRIVATE(auth
);
305 mem_free(au
->au_origcred
.oa_base
, au
->au_origcred
.oa_length
);
307 if (au
->au_shcred
.oa_base
!= NULL
)
308 mem_free(au
->au_shcred
.oa_base
, au
->au_shcred
.oa_length
);
310 mem_free(auth
->ah_private
, sizeof(struct audata
));
312 if (auth
->ah_verf
.oa_base
!= NULL
)
313 mem_free(auth
->ah_verf
.oa_base
, auth
->ah_verf
.oa_length
);
315 mem_free(auth
, sizeof(*auth
));
319 * Marshals (pre-serializes) an auth struct.
320 * sets private data, au_marshed and au_mpos
323 marshal_new_auth(AUTH
*auth
)
326 XDR
*xdrs
= &xdr_stream
;
329 assert(auth
!= NULL
);
331 au
= AUTH_PRIVATE(auth
);
332 xdrmem_create(xdrs
, au
->au_marshed
, MAX_AUTH_BYTES
, XDR_ENCODE
);
333 if ((! xdr_opaque_auth(xdrs
, &(auth
->ah_cred
))) ||
334 (! xdr_opaque_auth(xdrs
, &(auth
->ah_verf
))))
335 warnx("auth_none.c - Fatal marshalling problem");
337 au
->au_mpos
= XDR_GETPOS(xdrs
);
341 static struct auth_ops
*
344 static struct auth_ops ops
;
346 /* VARIABLES PROTECTED BY ops_lock: ops */
348 mutex_lock(&ops_lock
);
349 if (ops
.ah_nextverf
== NULL
) {
350 ops
.ah_nextverf
= authunix_nextverf
;
351 ops
.ah_marshal
= authunix_marshal
;
352 ops
.ah_validate
= authunix_validate
;
353 ops
.ah_refresh
= authunix_refresh
;
354 ops
.ah_destroy
= authunix_destroy
;
356 mutex_unlock(&ops_lock
);