17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 567dbe2beSCasper H.S. Dik * Common Development and Distribution License (the "License"). 667dbe2beSCasper H.S. Dik * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2267dbe2beSCasper H.S. Dik * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 317c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * auth_kern.c, implements UNIX style authentication parameters in the kernel. 367c478bd9Sstevel@tonic-gate * Interfaces with svc_auth_unix on the server. See auth_unix.c for the user 377c478bd9Sstevel@tonic-gate * level implementation of unix auth. 387c478bd9Sstevel@tonic-gate * 397c478bd9Sstevel@tonic-gate */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #include <sys/param.h> 427c478bd9Sstevel@tonic-gate #include <sys/time.h> 437c478bd9Sstevel@tonic-gate #include <sys/types.h> 447c478bd9Sstevel@tonic-gate #include <sys/systm.h> 457c478bd9Sstevel@tonic-gate #include <sys/user.h> 467c478bd9Sstevel@tonic-gate #include <sys/proc.h> 477c478bd9Sstevel@tonic-gate #include <sys/cred.h> 487c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 497c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 507c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 517c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #include <rpc/types.h> 547c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 557c478bd9Sstevel@tonic-gate #include <rpc/auth.h> 567c478bd9Sstevel@tonic-gate #include <rpc/auth_unix.h> 577c478bd9Sstevel@tonic-gate #include <rpc/clnt.h> 587c478bd9Sstevel@tonic-gate #include <rpc/rpc_msg.h> 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* 617c478bd9Sstevel@tonic-gate * Unix authenticator operations vector 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate static void authkern_nextverf(AUTH *); 647c478bd9Sstevel@tonic-gate static bool_t authkern_marshal(AUTH *, XDR *, struct cred *); 657c478bd9Sstevel@tonic-gate static bool_t authkern_validate(AUTH *, struct opaque_auth *); 667c478bd9Sstevel@tonic-gate static bool_t authkern_refresh(AUTH *, struct rpc_msg *, cred_t *); 677c478bd9Sstevel@tonic-gate static void authkern_destroy(AUTH *); 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static struct auth_ops auth_kern_ops = { 707c478bd9Sstevel@tonic-gate authkern_nextverf, 717c478bd9Sstevel@tonic-gate authkern_marshal, 727c478bd9Sstevel@tonic-gate authkern_validate, 737c478bd9Sstevel@tonic-gate authkern_refresh, 747c478bd9Sstevel@tonic-gate authkern_destroy, 757c478bd9Sstevel@tonic-gate authany_wrap, 767c478bd9Sstevel@tonic-gate authany_unwrap 777c478bd9Sstevel@tonic-gate }; 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* 807c478bd9Sstevel@tonic-gate * Create a kernel unix style authenticator. 817c478bd9Sstevel@tonic-gate * Returns an auth handle. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate AUTH * 847c478bd9Sstevel@tonic-gate authkern_create(void) 857c478bd9Sstevel@tonic-gate { 867c478bd9Sstevel@tonic-gate /* 877c478bd9Sstevel@tonic-gate * Allocate and set up auth handle 887c478bd9Sstevel@tonic-gate */ 897c478bd9Sstevel@tonic-gate return (kmem_cache_alloc(authkern_cache, KM_SLEEP)); 907c478bd9Sstevel@tonic-gate } 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* 937c478bd9Sstevel@tonic-gate * The constructor of the authkern_cache. 947c478bd9Sstevel@tonic-gate */ 957c478bd9Sstevel@tonic-gate /* ARGSUSED */ 967c478bd9Sstevel@tonic-gate int 977c478bd9Sstevel@tonic-gate authkern_init(void *buf, void *cdrarg, int kmflags) 987c478bd9Sstevel@tonic-gate { 997c478bd9Sstevel@tonic-gate AUTH *auth = (AUTH *)buf; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate auth->ah_ops = &auth_kern_ops; 1027c478bd9Sstevel@tonic-gate auth->ah_cred.oa_flavor = AUTH_UNIX; 1037c478bd9Sstevel@tonic-gate auth->ah_verf = _null_auth; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate return (0); 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate /* 1097c478bd9Sstevel@tonic-gate * authkern operations 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1127c478bd9Sstevel@tonic-gate static void 1137c478bd9Sstevel@tonic-gate authkern_nextverf(AUTH *auth) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate /* no action necessary */ 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate static bool_t 1197c478bd9Sstevel@tonic-gate authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr) 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate char *sercred; 1227c478bd9Sstevel@tonic-gate XDR xdrm; 123*0e91b739SMarcel Telka bool_t ret; 124*0e91b739SMarcel Telka uint32_t gidlen, credsize, namelen, rounded_namelen; 1257c478bd9Sstevel@tonic-gate int32_t *ptr; 1267c478bd9Sstevel@tonic-gate char *nodename = uts_nodename(); 127*0e91b739SMarcel Telka uint_t startpos; 128*0e91b739SMarcel Telka 129*0e91b739SMarcel Telka ASSERT(xdrs->x_op == XDR_ENCODE); 130*0e91b739SMarcel Telka ASSERT(auth->ah_cred.oa_flavor == AUTH_SYS); 131*0e91b739SMarcel Telka ASSERT(auth->ah_verf.oa_flavor == AUTH_NONE); 132*0e91b739SMarcel Telka ASSERT(auth->ah_verf.oa_length == 0); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * First we try a fast path to get through 1367c478bd9Sstevel@tonic-gate * this very common operation. 1377c478bd9Sstevel@tonic-gate */ 138*0e91b739SMarcel Telka namelen = (uint32_t)strlen(nodename); 139*0e91b739SMarcel Telka if (namelen > MAX_MACHINE_NAME) 140*0e91b739SMarcel Telka return (FALSE); 141*0e91b739SMarcel Telka rounded_namelen = RNDUP(namelen); 142*0e91b739SMarcel Telka 143*0e91b739SMarcel Telka /* 144*0e91b739SMarcel Telka * NFIELDS is a number of the following fields we are going to encode: 145*0e91b739SMarcel Telka * - stamp 146*0e91b739SMarcel Telka * - strlen(machinename) 147*0e91b739SMarcel Telka * - uid 148*0e91b739SMarcel Telka * - gid 149*0e91b739SMarcel Telka * - the number of gids 150*0e91b739SMarcel Telka */ 151*0e91b739SMarcel Telka #define NFIELDS 5 152*0e91b739SMarcel Telka CTASSERT((NFIELDS + NGRPS) * BYTES_PER_XDR_UNIT + 153*0e91b739SMarcel Telka RNDUP(MAX_MACHINE_NAME) <= MAX_AUTH_BYTES); 154*0e91b739SMarcel Telka 1557c478bd9Sstevel@tonic-gate gidlen = crgetngroups(cr); 1567c478bd9Sstevel@tonic-gate if (gidlen > NGRPS) 15767dbe2beSCasper H.S. Dik gidlen = NGRPS; 1587c478bd9Sstevel@tonic-gate 159*0e91b739SMarcel Telka credsize = NFIELDS * BYTES_PER_XDR_UNIT + rounded_namelen + 160*0e91b739SMarcel Telka gidlen * BYTES_PER_XDR_UNIT; 161*0e91b739SMarcel Telka ASSERT(credsize <= MAX_AUTH_BYTES); 162*0e91b739SMarcel Telka #undef NFIELDS 163*0e91b739SMarcel Telka 164*0e91b739SMarcel Telka /* 165*0e91b739SMarcel Telka * We need to marshal both cred and verf parts of the rpc_msg body 166*0e91b739SMarcel Telka * (call_body). For the cred part we need to inline the auth_flavor 167*0e91b739SMarcel Telka * and the opaque auth body size. Then we inline the credsize bytes of 168*0e91b739SMarcel Telka * the opaque auth body for the cred part. Finally we add the 169*0e91b739SMarcel Telka * AUTH_NONE verifier (its auth_flavor and the opaque auth body size). 170*0e91b739SMarcel Telka */ 171*0e91b739SMarcel Telka ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + credsize + 172*0e91b739SMarcel Telka 2 * BYTES_PER_XDR_UNIT); 173*0e91b739SMarcel Telka if (ptr != NULL) { 1747c478bd9Sstevel@tonic-gate /* 1757c478bd9Sstevel@tonic-gate * We can do the fast path. 1767c478bd9Sstevel@tonic-gate */ 177*0e91b739SMarcel Telka const gid_t *gp = crgetgroups(cr); 178*0e91b739SMarcel Telka 179*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, AUTH_SYS); /* cred flavor */ 180*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, credsize); /* cred len */ 181*0e91b739SMarcel Telka 1827c478bd9Sstevel@tonic-gate IXDR_PUT_INT32(ptr, gethrestime_sec()); 183*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, namelen); 184*0e91b739SMarcel Telka bcopy(nodename, ptr, namelen); 185*0e91b739SMarcel Telka if ((rounded_namelen - namelen) > 0) 186*0e91b739SMarcel Telka bzero((char *)ptr + namelen, rounded_namelen - namelen); 1877c478bd9Sstevel@tonic-gate ptr += rounded_namelen / BYTES_PER_XDR_UNIT; 188*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, crgetuid(cr)); 189*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, crgetgid(cr)); 190*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, gidlen); 191*0e91b739SMarcel Telka while (gidlen-- > 0) 192*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, *gp++); 193*0e91b739SMarcel Telka 194*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, AUTH_NULL); /* verf flavor */ 195*0e91b739SMarcel Telka IXDR_PUT_U_INT32(ptr, 0); /* verf len */ 196*0e91b739SMarcel Telka 1977c478bd9Sstevel@tonic-gate return (TRUE); 1987c478bd9Sstevel@tonic-gate } 199*0e91b739SMarcel Telka 2007c478bd9Sstevel@tonic-gate sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP); 201*0e91b739SMarcel Telka 2027c478bd9Sstevel@tonic-gate /* 203*0e91b739SMarcel Telka * Serialize the auth body data into sercred. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE); 206*0e91b739SMarcel Telka startpos = XDR_GETPOS(&xdrm); 207*0e91b739SMarcel Telka if (!xdr_authkern(&xdrm, cr)) { 2087c478bd9Sstevel@tonic-gate printf("authkern_marshal: xdr_authkern failed\n"); 2097c478bd9Sstevel@tonic-gate ret = FALSE; 2107c478bd9Sstevel@tonic-gate goto done; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 214*0e91b739SMarcel Telka * Make opaque auth credentials to point at the serialized auth body 215*0e91b739SMarcel Telka * data. 2167c478bd9Sstevel@tonic-gate */ 217*0e91b739SMarcel Telka auth->ah_cred.oa_base = sercred; 218*0e91b739SMarcel Telka auth->ah_cred.oa_length = XDR_GETPOS(&xdrm) - startpos; 219*0e91b739SMarcel Telka ASSERT(auth->ah_cred.oa_length <= MAX_AUTH_BYTES); 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate /* 222*0e91b739SMarcel Telka * serialize credentials and verifier (null) 2237c478bd9Sstevel@tonic-gate */ 2247c478bd9Sstevel@tonic-gate if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) && 2257c478bd9Sstevel@tonic-gate (xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 2267c478bd9Sstevel@tonic-gate ret = TRUE; 2277c478bd9Sstevel@tonic-gate else 2287c478bd9Sstevel@tonic-gate ret = FALSE; 229*0e91b739SMarcel Telka 2307c478bd9Sstevel@tonic-gate done: 231*0e91b739SMarcel Telka XDR_DESTROY(&xdrm); 2327c478bd9Sstevel@tonic-gate kmem_free(sercred, MAX_AUTH_BYTES); 233*0e91b739SMarcel Telka 2347c478bd9Sstevel@tonic-gate return (ret); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2387c478bd9Sstevel@tonic-gate static bool_t 2397c478bd9Sstevel@tonic-gate authkern_validate(AUTH *auth, struct opaque_auth *verf) 2407c478bd9Sstevel@tonic-gate { 2417c478bd9Sstevel@tonic-gate return (TRUE); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* ARGSUSED */ 2457c478bd9Sstevel@tonic-gate static bool_t 2467c478bd9Sstevel@tonic-gate authkern_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr) 2477c478bd9Sstevel@tonic-gate { 2487c478bd9Sstevel@tonic-gate return (FALSE); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate static void 2527c478bd9Sstevel@tonic-gate authkern_destroy(AUTH *auth) 2537c478bd9Sstevel@tonic-gate { 2547c478bd9Sstevel@tonic-gate kmem_cache_free(authkern_cache, auth); 2557c478bd9Sstevel@tonic-gate } 256