1 /* $NetBSD: auth_unix.c,v 1.26 2014/10/18 08:33:23 snj Exp $ */
4 * Copyright (c) 2010, Oracle America, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 * * Neither the name of the "Oracle America, Inc." nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 #if defined(LIBC_SCCS) && !defined(lint)
37 static char *sccsid
= "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
38 static char *sccsid
= "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";
40 __RCSID("$NetBSD: auth_unix.c,v 1.26 2014/10/18 08:33:23 snj Exp $");
45 * auth_unix.c, Implements UNIX style authentication parameters.
47 * Copyright (C) 1984, Sun Microsystems, Inc.
49 * The system is very weak. The client uses no encryption for its
50 * credentials and only sends null verifiers. The server sends backs
51 * null verifiers or optionally a verifier that suggests a new short hand
52 * for the credentials.
56 #include "namespace.h"
57 #include "reentrant.h"
58 #include <sys/param.h>
67 #include <rpc/types.h>
70 #include <rpc/auth_unix.h>
73 __weak_alias(authunix_create
,_authunix_create
)
74 __weak_alias(authunix_create_default
,_authunix_create_default
)
79 static void authunix_nextverf(AUTH
*);
80 static bool_t
authunix_marshal(AUTH
*, XDR
*);
81 static bool_t
authunix_validate(AUTH
*, struct opaque_auth
*);
82 static bool_t
authunix_refresh(AUTH
*);
83 static void authunix_destroy(AUTH
*);
84 static void marshal_new_auth(AUTH
*);
85 static const struct auth_ops
*authunix_ops(void);
88 * This struct is pointed to by the ah_private field of an auth_handle.
91 struct opaque_auth au_origcred
; /* original credentials */
92 struct opaque_auth au_shcred
; /* short hand cred */
93 u_long au_shfaults
; /* short hand cache faults */
94 char au_marshed
[MAX_AUTH_BYTES
];
95 u_int au_mpos
; /* xdr pos at end of marshed */
97 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
100 * Create a unix style authenticator.
101 * Returns an auth handle with the given stuff in it.
104 authunix_create(char *machname
, int uid
, int gid
, int len
, int *aup_gids
)
106 struct authunix_parms aup
;
107 char mymem
[MAX_AUTH_BYTES
];
114 * Allocate and set up auth handle
117 auth
= mem_alloc(sizeof(*auth
));
120 warn("%s: out of memory", __func__
);
121 goto cleanup_authunix_create
;
124 au
= mem_alloc(sizeof(*au
));
127 warn("%s: out of memory", __func__
);
128 goto cleanup_authunix_create
;
131 auth
->ah_ops
= authunix_ops();
132 auth
->ah_private
= au
;
133 auth
->ah_verf
= au
->au_shcred
= _null_auth
;
135 au
->au_origcred
.oa_base
= NULL
;
138 * fill in param struct from the given params
140 (void)gettimeofday(&now
, NULL
);
141 aup
.aup_time
= (u_long
)now
.tv_sec
; /* XXX: truncate on 32 bit */
142 aup
.aup_machname
= machname
;
145 aup
.aup_len
= (u_int
)len
;
146 aup
.aup_gids
= aup_gids
;
149 * Serialize the parameters into origcred
151 xdrmem_create(&xdrs
, mymem
, MAX_AUTH_BYTES
, XDR_ENCODE
);
152 if (! xdr_authunix_parms(&xdrs
, &aup
))
154 au
->au_origcred
.oa_length
= len
= XDR_GETPOS(&xdrs
);
155 au
->au_origcred
.oa_flavor
= AUTH_UNIX
;
157 au
->au_origcred
.oa_base
= mem_alloc((size_t)len
);
159 if ((au
->au_origcred
.oa_base
= mem_alloc((size_t)len
)) == NULL
) {
160 warn("%s: out of memory", __func__
);
161 goto cleanup_authunix_create
;
164 memmove(au
->au_origcred
.oa_base
, mymem
, (size_t)len
);
167 * set auth handle to reflect new cred.
169 auth
->ah_cred
= au
->au_origcred
;
170 marshal_new_auth(auth
);
173 cleanup_authunix_create
:
175 mem_free(auth
, sizeof(*auth
));
177 if (au
->au_origcred
.oa_base
)
178 mem_free(au
->au_origcred
.oa_base
, (u_int
)len
);
179 mem_free(au
, sizeof(*au
));
186 * Returns an auth handle with parameters determined by doing lots of
190 authunix_create_default(void)
193 char machname
[MAXHOSTNAMELEN
+ 1];
198 if (gethostname(machname
, sizeof machname
) == -1)
200 machname
[sizeof(machname
) - 1] = 0;
203 if ((len
= getgroups(NGRPS
, gids
)) < 0)
205 /* XXX: interface problem; those should all have been unsigned */
206 return (authunix_create(machname
, (int)uid
, (int)gid
, len
,
211 * authunix operations
216 authunix_nextverf(AUTH
*auth
)
218 /* no action necessary */
222 authunix_marshal(AUTH
*auth
, XDR
*xdrs
)
226 _DIAGASSERT(auth
!= NULL
);
227 _DIAGASSERT(xdrs
!= NULL
);
229 au
= AUTH_PRIVATE(auth
);
230 return (XDR_PUTBYTES(xdrs
, au
->au_marshed
, au
->au_mpos
));
234 authunix_validate(AUTH
*auth
, struct opaque_auth
*verf
)
239 _DIAGASSERT(auth
!= NULL
);
240 _DIAGASSERT(verf
!= NULL
);
242 if (verf
->oa_flavor
== AUTH_SHORT
) {
243 au
= AUTH_PRIVATE(auth
);
244 xdrmem_create(&xdrs
, verf
->oa_base
, verf
->oa_length
,
247 if (au
->au_shcred
.oa_base
!= NULL
) {
248 mem_free(au
->au_shcred
.oa_base
,
249 au
->au_shcred
.oa_length
);
250 au
->au_shcred
.oa_base
= NULL
;
252 if (xdr_opaque_auth(&xdrs
, &au
->au_shcred
)) {
253 auth
->ah_cred
= au
->au_shcred
;
255 xdrs
.x_op
= XDR_FREE
;
256 (void)xdr_opaque_auth(&xdrs
, &au
->au_shcred
);
257 au
->au_shcred
.oa_base
= NULL
;
258 auth
->ah_cred
= au
->au_origcred
;
260 marshal_new_auth(auth
);
266 authunix_refresh(AUTH
*auth
)
268 struct audata
*au
= AUTH_PRIVATE(auth
);
269 struct authunix_parms aup
;
274 _DIAGASSERT(auth
!= NULL
);
276 if (auth
->ah_cred
.oa_base
== au
->au_origcred
.oa_base
) {
277 /* there is no hope. Punt */
282 /* first deserialize the creds back into a struct authunix_parms */
283 aup
.aup_machname
= NULL
;
285 xdrmem_create(&xdrs
, au
->au_origcred
.oa_base
,
286 au
->au_origcred
.oa_length
, XDR_DECODE
);
287 stat
= xdr_authunix_parms(&xdrs
, &aup
);
291 /* update the time and serialize in place */
292 (void)gettimeofday(&now
, NULL
);
293 aup
.aup_time
= (u_long
)now
.tv_sec
; /* XXX: truncate on 32 bit */
294 xdrs
.x_op
= XDR_ENCODE
;
295 XDR_SETPOS(&xdrs
, 0);
296 stat
= xdr_authunix_parms(&xdrs
, &aup
);
299 auth
->ah_cred
= au
->au_origcred
;
300 marshal_new_auth(auth
);
302 /* free the struct authunix_parms created by deserializing */
303 xdrs
.x_op
= XDR_FREE
;
304 (void)xdr_authunix_parms(&xdrs
, &aup
);
310 authunix_destroy(AUTH
*auth
)
314 _DIAGASSERT(auth
!= NULL
);
316 au
= AUTH_PRIVATE(auth
);
317 mem_free(au
->au_origcred
.oa_base
, au
->au_origcred
.oa_length
);
319 if (au
->au_shcred
.oa_base
!= NULL
)
320 mem_free(au
->au_shcred
.oa_base
, au
->au_shcred
.oa_length
);
322 mem_free(auth
->ah_private
, sizeof(struct audata
));
324 if (auth
->ah_verf
.oa_base
!= NULL
)
325 mem_free(auth
->ah_verf
.oa_base
, auth
->ah_verf
.oa_length
);
327 mem_free(auth
, sizeof(*auth
));
331 * Marshals (pre-serializes) an auth struct.
332 * sets private data, au_marshed and au_mpos
335 marshal_new_auth(AUTH
*auth
)
338 XDR
*xdrs
= &xdr_stream
;
341 _DIAGASSERT(auth
!= NULL
);
343 au
= AUTH_PRIVATE(auth
);
344 xdrmem_create(xdrs
, au
->au_marshed
, MAX_AUTH_BYTES
, XDR_ENCODE
);
345 if ((! xdr_opaque_auth(xdrs
, &(auth
->ah_cred
))) ||
346 (! xdr_opaque_auth(xdrs
, &(auth
->ah_verf
))))
347 warnx("%s: Fatal marshalling problem", __func__
);
349 au
->au_mpos
= XDR_GETPOS(xdrs
);
353 static const struct auth_ops
*
356 static struct auth_ops ops
;
358 extern mutex_t ops_lock
;
361 /* VARIABLES PROTECTED BY ops_lock: ops */
363 mutex_lock(&ops_lock
);
364 if (ops
.ah_nextverf
== NULL
) {
365 ops
.ah_nextverf
= authunix_nextverf
;
366 ops
.ah_marshal
= authunix_marshal
;
367 ops
.ah_validate
= authunix_validate
;
368 ops
.ah_refresh
= authunix_refresh
;
369 ops
.ah_destroy
= authunix_destroy
;
371 mutex_unlock(&ops_lock
);