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