1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * Portions of this source code were derived from Berkeley 4.3 BSD
31 * under license from the Regents of the University of California.
32 */
33
34 /*
35 * auth_kern.c, implements UNIX style authentication parameters in the kernel.
36 * Interfaces with svc_auth_unix on the server. See auth_unix.c for the user
37 * level implementation of unix auth.
38 *
39 */
40
41 #include <sys/param.h>
42 #include <sys/time.h>
43 #include <sys/types.h>
44 #include <sys/systm.h>
45 #include <sys/user.h>
46 #include <sys/proc.h>
47 #include <sys/cred.h>
48 #include <sys/kmem.h>
49 #include <sys/sysmacros.h>
50 #include <sys/cmn_err.h>
51 #include <sys/utsname.h>
52
53 #include <rpc/types.h>
54 #include <rpc/xdr.h>
55 #include <rpc/auth.h>
56 #include <rpc/auth_unix.h>
57 #include <rpc/clnt.h>
58 #include <rpc/rpc_msg.h>
59
60 /*
61 * Unix authenticator operations vector
62 */
63 static void authkern_nextverf(AUTH *);
64 static bool_t authkern_marshal(AUTH *, XDR *, struct cred *);
65 static bool_t authkern_validate(AUTH *, struct opaque_auth *);
66 static bool_t authkern_refresh(AUTH *, struct rpc_msg *, cred_t *);
67 static void authkern_destroy(AUTH *);
68
69 static struct auth_ops auth_kern_ops = {
70 authkern_nextverf,
71 authkern_marshal,
72 authkern_validate,
73 authkern_refresh,
74 authkern_destroy,
75 authany_wrap,
76 authany_unwrap
77 };
78
79 /*
80 * Create a kernel unix style authenticator.
81 * Returns an auth handle.
82 */
83 AUTH *
authkern_create(void)84 authkern_create(void)
85 {
86 /*
87 * Allocate and set up auth handle
88 */
89 return (kmem_cache_alloc(authkern_cache, KM_SLEEP));
90 }
91
92 /*
93 * The constructor of the authkern_cache.
94 */
95 /* ARGSUSED */
96 int
authkern_init(void * buf,void * cdrarg,int kmflags)97 authkern_init(void *buf, void *cdrarg, int kmflags)
98 {
99 AUTH *auth = (AUTH *)buf;
100
101 auth->ah_ops = &auth_kern_ops;
102 auth->ah_cred.oa_flavor = AUTH_UNIX;
103 auth->ah_verf = _null_auth;
104
105 return (0);
106 }
107
108 /*
109 * authkern operations
110 */
111 /* ARGSUSED */
112 static void
authkern_nextverf(AUTH * auth)113 authkern_nextverf(AUTH *auth)
114 {
115 /* no action necessary */
116 }
117
118 static bool_t
authkern_marshal(AUTH * auth,XDR * xdrs,struct cred * cr)119 authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
120 {
121 char *sercred;
122 XDR xdrm;
123 struct opaque_auth *cred;
124 bool_t ret = FALSE;
125 const gid_t *gp, *gpend;
126 int gidlen, credsize, namelen, rounded_namelen;
127 int32_t *ptr;
128 char *nodename = uts_nodename();
129
130 /*
131 * First we try a fast path to get through
132 * this very common operation.
133 */
134 gp = crgetgroups(cr);
135 gidlen = crgetngroups(cr);
136 if (gidlen > NGRPS)
137 gidlen = NGRPS;
138 gpend = &gp[gidlen-1];
139
140 namelen = (int)strlen(nodename);
141 rounded_namelen = RNDUP(namelen);
142 credsize = 4 + 4 + rounded_namelen + 4 + 4 + 4 + gidlen * 4;
143 ptr = XDR_INLINE(xdrs, 4 + 4 + credsize + 4 + 4);
144 if (ptr) {
145 /*
146 * We can do the fast path.
147 */
148 IXDR_PUT_INT32(ptr, AUTH_UNIX); /* cred flavor */
149 IXDR_PUT_INT32(ptr, credsize); /* cred len */
150 IXDR_PUT_INT32(ptr, gethrestime_sec());
151 IXDR_PUT_INT32(ptr, namelen);
152 bcopy(nodename, (caddr_t)ptr, namelen);
153 if (rounded_namelen - namelen)
154 bzero(((caddr_t)ptr) + namelen,
155 rounded_namelen - namelen);
156 ptr += rounded_namelen / BYTES_PER_XDR_UNIT;
157 IXDR_PUT_INT32(ptr, crgetuid(cr));
158 IXDR_PUT_INT32(ptr, crgetgid(cr));
159 IXDR_PUT_INT32(ptr, gidlen);
160 while (gp <= gpend) {
161 IXDR_PUT_INT32(ptr, *gp++);
162 }
163 IXDR_PUT_INT32(ptr, AUTH_NULL); /* verf flavor */
164 IXDR_PUT_INT32(ptr, 0); /* verf len */
165 return (TRUE);
166 }
167 sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP);
168 /*
169 * serialize u struct stuff into sercred
170 */
171 xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE);
172 if (!xdr_authkern(&xdrm)) {
173 printf("authkern_marshal: xdr_authkern failed\n");
174 ret = FALSE;
175 goto done;
176 }
177
178 /*
179 * Make opaque auth credentials that point at serialized u struct
180 */
181 cred = &(auth->ah_cred);
182 cred->oa_length = XDR_GETPOS(&xdrm);
183 cred->oa_base = sercred;
184
185 /*
186 * serialize credentials and verifiers (null)
187 */
188 if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) &&
189 (xdr_opaque_auth(xdrs, &(auth->ah_verf))))
190 ret = TRUE;
191 else
192 ret = FALSE;
193 done:
194 kmem_free(sercred, MAX_AUTH_BYTES);
195 return (ret);
196 }
197
198 /* ARGSUSED */
199 static bool_t
authkern_validate(AUTH * auth,struct opaque_auth * verf)200 authkern_validate(AUTH *auth, struct opaque_auth *verf)
201 {
202 return (TRUE);
203 }
204
205 /* ARGSUSED */
206 static bool_t
authkern_refresh(AUTH * auth,struct rpc_msg * msg,cred_t * cr)207 authkern_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr)
208 {
209 return (FALSE);
210 }
211
212 static void
authkern_destroy(AUTH * auth)213 authkern_destroy(AUTH *auth)
214 {
215 kmem_cache_free(authkern_cache, auth);
216 }
217