xref: /illumos-gate/usr/src/uts/common/rpc/sec/auth_loopb.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 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 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_loopb.c, implements UNIX style authentication parameters in the
39  * kernel.  Interfaces with svc_auth_loopback on the server.  See
40  * auth_loopb.c for the user level implementation of the loopback 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/utsname.h>
51 #include <sys/cred.h>
52 #include <sys/kmem.h>
53 #include <sys/sysmacros.h>
54 #include <sys/cmn_err.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	authloopback_nextverf(AUTH *);
67 static bool_t	authloopback_marshal(AUTH *, XDR *, struct cred *);
68 static bool_t	authloopback_validate(AUTH *, struct opaque_auth *);
69 static bool_t	authloopback_refresh(AUTH *, struct rpc_msg *, cred_t *);
70 static void	authloopback_destroy(AUTH *);
71 
72 static struct auth_ops authloopback_ops = {
73 	authloopback_nextverf,
74 	authloopback_marshal,
75 	authloopback_validate,
76 	authloopback_refresh,
77 	authloopback_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 authloopback_create(void)
88 {
89 	/*
90 	 * Allocate and set up auth handle
91 	 */
92 	return (kmem_cache_alloc(authloopback_cache, KM_SLEEP));
93 }
94 
95 /*
96  *  The constructor of the authloopback_cache.
97  */
98 /* ARGSUSED */
99 int
100 authloopback_init(void *buf, void *cdrarg, int kmflags)
101 {
102 	AUTH *auth = (AUTH *)buf;
103 
104 	auth->ah_ops = &authloopback_ops;
105 	auth->ah_cred.oa_flavor = AUTH_LOOPBACK;
106 	auth->ah_verf = _null_auth;
107 
108 	return (0);
109 }
110 
111 /*
112  * authloopback operations
113  */
114 /* ARGSUSED */
115 static void
116 authloopback_nextverf(AUTH *auth)
117 {
118 
119 	/* no action necessary */
120 }
121 
122 static bool_t
123 authloopback_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
124 {
125 	char *sercred;
126 	XDR xdrm;
127 	struct opaque_auth *cred;
128 	bool_t ret = FALSE;
129 	const gid_t *gp, *gpend;
130 	int gidlen, credsize, namelen, rounded_namelen;
131 	int32_t *ptr;
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_LOOPBACK)
140 		return (FALSE);
141 	gpend = &gp[gidlen-1];
142 
143 	namelen = (int)strlen(uts_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_LOOPBACK);	/* 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(uts_nodename(), 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_authloopback(&xdrm)) {
176 		printf("authloopback_marshal: xdr_authloopback 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 authloopback_validate(AUTH *auth, struct opaque_auth *verf)
204 {
205 	return (TRUE);
206 }
207 
208 /* ARGSUSED */
209 static bool_t
210 authloopback_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr)
211 {
212 	return (FALSE);
213 }
214 
215 static void
216 authloopback_destroy(register AUTH *auth)
217 {
218 	kmem_cache_free(authloopback_cache, auth);
219 }
220