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