4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
36 * auth_loopb.c, implements UNIX style authentication parameters in the
37 * kernel. Interfaces with svc_auth_loopback on the server. See
38 * auth_loopb.c for the user level implementation of the loopback auth.
42 #include <sys/param.h>
44 #include <sys/types.h>
45 #include <sys/systm.h>
48 #include <sys/utsname.h>
51 #include <sys/sysmacros.h>
52 #include <sys/cmn_err.h>
54 #include <rpc/types.h>
57 #include <rpc/auth_unix.h>
59 #include <rpc/rpc_msg.h>
62 * Unix authenticator operations vector
64 static void authloopback_nextverf(AUTH
*);
65 static bool_t
authloopback_marshal(AUTH
*, XDR
*, struct cred
*);
66 static bool_t
authloopback_validate(AUTH
*, struct opaque_auth
*);
67 static bool_t
authloopback_refresh(AUTH
*, struct rpc_msg
*, cred_t
*);
68 static void authloopback_destroy(AUTH
*);
70 static struct auth_ops authloopback_ops
= {
71 authloopback_nextverf
,
73 authloopback_validate
,
81 * Create a kernel unix style authenticator.
82 * Returns an auth handle.
85 authloopback_create(void)
88 * Allocate and set up auth handle
90 return (kmem_cache_alloc(authloopback_cache
, KM_SLEEP
));
94 * The constructor of the authloopback_cache.
98 authloopback_init(void *buf
, void *cdrarg
, int kmflags
)
100 AUTH
*auth
= (AUTH
*)buf
;
102 auth
->ah_ops
= &authloopback_ops
;
103 auth
->ah_cred
.oa_flavor
= AUTH_LOOPBACK
;
104 auth
->ah_verf
= _null_auth
;
110 * authloopback operations
114 authloopback_nextverf(AUTH
*auth
)
117 /* no action necessary */
121 authloopback_marshal(AUTH
*auth
, XDR
*xdrs
, struct cred
*cr
)
126 uint32_t gidlen
, credsize
, namelen
, rounded_namelen
;
128 char *nodename
= uts_nodename();
132 ASSERT(xdrs
->x_op
== XDR_ENCODE
);
133 ASSERT(auth
->ah_cred
.oa_flavor
== AUTH_LOOPBACK
);
134 ASSERT(auth
->ah_verf
.oa_flavor
== AUTH_NONE
);
135 ASSERT(auth
->ah_verf
.oa_length
== 0);
138 * First we try a fast path to get through
139 * this very common operation.
141 namelen
= (uint32_t)strlen(nodename
);
142 if (namelen
> MAX_MACHINE_NAME
)
144 rounded_namelen
= RNDUP(namelen
);
147 * NFIELDS is a number of the following fields we are going to encode:
149 * - strlen(machinename)
152 * - the number of gids
155 CTASSERT(NFIELDS
* BYTES_PER_XDR_UNIT
+ RNDUP(MAX_MACHINE_NAME
) <=
157 maxgidlen
= (MAX_AUTH_BYTES
- NFIELDS
* BYTES_PER_XDR_UNIT
-
158 rounded_namelen
) / BYTES_PER_XDR_UNIT
;
160 gidlen
= crgetngroups(cr
);
161 if (gidlen
> maxgidlen
)
164 credsize
= NFIELDS
* BYTES_PER_XDR_UNIT
+ rounded_namelen
+
165 gidlen
* BYTES_PER_XDR_UNIT
;
166 ASSERT(credsize
<= MAX_AUTH_BYTES
);
170 * We need to marshal both cred and verf parts of the rpc_msg body
171 * (call_body). For the cred part we need to inline the auth_flavor
172 * and the opaque auth body size. Then we inline the credsize bytes of
173 * the opaque auth body for the cred part. Finally we add the
174 * AUTH_NONE verifier (its auth_flavor and the opaque auth body size).
176 ptr
= XDR_INLINE(xdrs
, 2 * BYTES_PER_XDR_UNIT
+ credsize
+
177 2 * BYTES_PER_XDR_UNIT
);
180 * We can do the fast path.
182 const gid_t
*gp
= crgetgroups(cr
);
184 IXDR_PUT_U_INT32(ptr
, AUTH_LOOPBACK
); /* cred flavor */
185 IXDR_PUT_U_INT32(ptr
, credsize
); /* cred len */
187 IXDR_PUT_INT32(ptr
, gethrestime_sec());
188 IXDR_PUT_U_INT32(ptr
, namelen
);
189 bcopy(nodename
, ptr
, namelen
);
190 if ((rounded_namelen
- namelen
) > 0)
191 bzero((char *)ptr
+ namelen
, rounded_namelen
- namelen
);
192 ptr
+= rounded_namelen
/ BYTES_PER_XDR_UNIT
;
193 IXDR_PUT_U_INT32(ptr
, crgetuid(cr
));
194 IXDR_PUT_U_INT32(ptr
, crgetgid(cr
));
195 IXDR_PUT_U_INT32(ptr
, gidlen
);
197 IXDR_PUT_U_INT32(ptr
, *gp
++);
199 IXDR_PUT_U_INT32(ptr
, AUTH_NONE
); /* verf flavor */
200 IXDR_PUT_U_INT32(ptr
, 0); /* verf len */
205 sercred
= kmem_alloc(MAX_AUTH_BYTES
, KM_SLEEP
);
208 * Serialize the auth body data into sercred.
210 xdrmem_create(&xdrm
, sercred
, MAX_AUTH_BYTES
, XDR_ENCODE
);
211 startpos
= XDR_GETPOS(&xdrm
);
212 if (!xdr_authloopback(&xdrm
, cr
)) {
213 printf("authloopback_marshal: xdr_authloopback failed\n");
219 * Make opaque auth credentials to point at the serialized auth body
222 auth
->ah_cred
.oa_base
= sercred
;
223 auth
->ah_cred
.oa_length
= XDR_GETPOS(&xdrm
) - startpos
;
224 ASSERT(auth
->ah_cred
.oa_length
<= MAX_AUTH_BYTES
);
227 * serialize credentials and verifier (null)
229 if ((xdr_opaque_auth(xdrs
, &(auth
->ah_cred
))) &&
230 (xdr_opaque_auth(xdrs
, &(auth
->ah_verf
))))
237 kmem_free(sercred
, MAX_AUTH_BYTES
);
244 authloopback_validate(AUTH
*auth
, struct opaque_auth
*verf
)
251 authloopback_refresh(AUTH
*auth
, struct rpc_msg
*msg
, cred_t
*cr
)
257 authloopback_destroy(register AUTH
*auth
)
259 kmem_cache_free(authloopback_cache
, auth
);