1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 32*7c478bd9Sstevel@tonic-gate * under license from the Regents of the University of California. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * Adapted for use by the boot program. 39*7c478bd9Sstevel@tonic-gate * 40*7c478bd9Sstevel@tonic-gate * auth_unix.c, Implements UNIX style authentication parameters. 41*7c478bd9Sstevel@tonic-gate * 42*7c478bd9Sstevel@tonic-gate * The system is very weak. The client uses no encryption for its 43*7c478bd9Sstevel@tonic-gate * credentials and only sends null verifiers. The server sends backs 44*7c478bd9Sstevel@tonic-gate * null verifiers or optionally a verifier that suggests a new short hand 45*7c478bd9Sstevel@tonic-gate * for the credentials. 46*7c478bd9Sstevel@tonic-gate */ 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 50*7c478bd9Sstevel@tonic-gate #include <rpc/types.h> 51*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 52*7c478bd9Sstevel@tonic-gate #include <rpc/auth.h> 53*7c478bd9Sstevel@tonic-gate #include "clnt.h" 54*7c478bd9Sstevel@tonic-gate #include <rpc/auth_unix.h> 55*7c478bd9Sstevel@tonic-gate #include <sys/promif.h> 56*7c478bd9Sstevel@tonic-gate #include <sys/salib.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/bootdebug.h> 58*7c478bd9Sstevel@tonic-gate #include "nfs_inet.h" 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate static struct auth_ops *authunix_ops(); 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate * This struct is pointed to by the ah_private field of an auth_handle. 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate struct audata { 65*7c478bd9Sstevel@tonic-gate struct opaque_auth au_origcred; /* original credentials */ 66*7c478bd9Sstevel@tonic-gate struct opaque_auth au_shcred; /* short hand cred */ 67*7c478bd9Sstevel@tonic-gate uint_t au_shfaults; /* short hand cache faults */ 68*7c478bd9Sstevel@tonic-gate char au_marshed[MAX_AUTH_BYTES]; 69*7c478bd9Sstevel@tonic-gate uint_t au_mpos; /* xdr pos at end of marshed */ 70*7c478bd9Sstevel@tonic-gate }; 71*7c478bd9Sstevel@tonic-gate #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate static void marshal_new_auth(AUTH *); 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate /* 78*7c478bd9Sstevel@tonic-gate * Create a unix style authenticator. 79*7c478bd9Sstevel@tonic-gate * Returns an auth handle with the given stuff in it. 80*7c478bd9Sstevel@tonic-gate */ 81*7c478bd9Sstevel@tonic-gate AUTH * 82*7c478bd9Sstevel@tonic-gate authunix_create(char *machname, uid_t uid, gid_t gid, int len, gid_t *aup_gids) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate struct authunix_parms aup; 85*7c478bd9Sstevel@tonic-gate char mymem[MAX_AUTH_BYTES]; 86*7c478bd9Sstevel@tonic-gate XDR xdrs; 87*7c478bd9Sstevel@tonic-gate AUTH *auth; 88*7c478bd9Sstevel@tonic-gate struct audata *au; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * Allocate and set up auth handle 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate auth = (AUTH *) bkmem_alloc(sizeof (*auth)); 94*7c478bd9Sstevel@tonic-gate if (auth == NULL) { 95*7c478bd9Sstevel@tonic-gate prom_panic("authunix_create: Cannot allocate memory."); 96*7c478bd9Sstevel@tonic-gate return (NULL); 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate au = (struct audata *)bkmem_alloc(sizeof (*au)); 100*7c478bd9Sstevel@tonic-gate if (au == NULL) { 101*7c478bd9Sstevel@tonic-gate prom_panic("authunix_create: Cannot allocate memory."); 102*7c478bd9Sstevel@tonic-gate return (NULL); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* setup authenticator. */ 106*7c478bd9Sstevel@tonic-gate auth->ah_ops = authunix_ops(); 107*7c478bd9Sstevel@tonic-gate auth->ah_private = (caddr_t)au; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* structure copies */ 110*7c478bd9Sstevel@tonic-gate auth->ah_verf = au->au_shcred = _null_auth; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate au->au_shfaults = 0; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * fill in param struct from the given params 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate aup.aup_time = prom_gettime() / 1000; 118*7c478bd9Sstevel@tonic-gate aup.aup_machname = machname; 119*7c478bd9Sstevel@tonic-gate aup.aup_uid = uid; 120*7c478bd9Sstevel@tonic-gate aup.aup_gid = gid; 121*7c478bd9Sstevel@tonic-gate aup.aup_len = (uint_t)len; 122*7c478bd9Sstevel@tonic-gate aup.aup_gids = (gid_t *)aup_gids; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * Serialize the parameters into origcred 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 128*7c478bd9Sstevel@tonic-gate if (!xdr_authunix_parms(&xdrs, &aup)) { 129*7c478bd9Sstevel@tonic-gate prom_panic("authunix_create: xdr_authunix_parms failed"); 130*7c478bd9Sstevel@tonic-gate bkmem_free(auth->ah_private, sizeof (struct audata)); 131*7c478bd9Sstevel@tonic-gate bkmem_free((caddr_t)auth, sizeof (*auth)); 132*7c478bd9Sstevel@tonic-gate return ((AUTH *)0); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 135*7c478bd9Sstevel@tonic-gate au->au_origcred.oa_flavor = (uint_t)AUTH_UNIX; 136*7c478bd9Sstevel@tonic-gate if ((au->au_origcred.oa_base = bkmem_alloc((uint_t)len)) == NULL) { 137*7c478bd9Sstevel@tonic-gate prom_panic("authunix_create: memory alloc failed"); 138*7c478bd9Sstevel@tonic-gate bkmem_free(auth->ah_private, sizeof (struct audata)); 139*7c478bd9Sstevel@tonic-gate bkmem_free((caddr_t)auth, sizeof (*auth)); 140*7c478bd9Sstevel@tonic-gate return ((AUTH *)0); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate (void) bcopy(mymem, au->au_origcred.oa_base, (uint_t)len); 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * set auth handle to reflect new cred. 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate auth->ah_cred = au->au_origcred; 148*7c478bd9Sstevel@tonic-gate marshal_new_auth(auth); 149*7c478bd9Sstevel@tonic-gate return (auth); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * authunix operations 154*7c478bd9Sstevel@tonic-gate */ 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 157*7c478bd9Sstevel@tonic-gate static void 158*7c478bd9Sstevel@tonic-gate authunix_nextverf(AUTH *auth) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 163*7c478bd9Sstevel@tonic-gate static bool_t 164*7c478bd9Sstevel@tonic-gate authunix_marshal(AUTH *auth, XDR *xdrs, cred_t *cr) 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate struct audata *au = AUTH_PRIVATE(auth); 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate static bool_t 172*7c478bd9Sstevel@tonic-gate authunix_validate(AUTH *auth, struct opaque_auth *verf) 173*7c478bd9Sstevel@tonic-gate { 174*7c478bd9Sstevel@tonic-gate struct audata *au; 175*7c478bd9Sstevel@tonic-gate XDR xdrs; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate if (verf->oa_flavor == AUTH_SHORT) { 178*7c478bd9Sstevel@tonic-gate au = AUTH_PRIVATE(auth); 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 182*7c478bd9Sstevel@tonic-gate XDR_DECODE); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 185*7c478bd9Sstevel@tonic-gate auth->ah_cred = au->au_shcred; 186*7c478bd9Sstevel@tonic-gate } else { 187*7c478bd9Sstevel@tonic-gate xdrs.x_op = XDR_FREE; 188*7c478bd9Sstevel@tonic-gate (void) xdr_opaque_auth(&xdrs, &au->au_shcred); 189*7c478bd9Sstevel@tonic-gate au->au_shcred.oa_base = 0; 190*7c478bd9Sstevel@tonic-gate auth->ah_cred = au->au_origcred; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate marshal_new_auth(auth); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate return (TRUE); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 199*7c478bd9Sstevel@tonic-gate static bool_t 200*7c478bd9Sstevel@tonic-gate authunix_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr) 201*7c478bd9Sstevel@tonic-gate { 202*7c478bd9Sstevel@tonic-gate struct audata *au = AUTH_PRIVATE(auth); 203*7c478bd9Sstevel@tonic-gate struct authunix_parms aup; 204*7c478bd9Sstevel@tonic-gate XDR xdrs; 205*7c478bd9Sstevel@tonic-gate int stat; 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 208*7c478bd9Sstevel@tonic-gate /* there is no hope. Punt */ 209*7c478bd9Sstevel@tonic-gate return (FALSE); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate au->au_shfaults ++; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* first deserialize the creds back into a struct authunix_parms */ 214*7c478bd9Sstevel@tonic-gate aup.aup_machname = (char *)0; 215*7c478bd9Sstevel@tonic-gate aup.aup_gids = (gid_t *)0; 216*7c478bd9Sstevel@tonic-gate xdrmem_create(&xdrs, au->au_origcred.oa_base, 217*7c478bd9Sstevel@tonic-gate au->au_origcred.oa_length, XDR_DECODE); 218*7c478bd9Sstevel@tonic-gate stat = xdr_authunix_parms(&xdrs, &aup); 219*7c478bd9Sstevel@tonic-gate if (!stat) 220*7c478bd9Sstevel@tonic-gate goto done; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate /* update the time and serialize in place */ 223*7c478bd9Sstevel@tonic-gate aup.aup_time = (prom_gettime() / 1000); 224*7c478bd9Sstevel@tonic-gate xdrs.x_op = XDR_ENCODE; 225*7c478bd9Sstevel@tonic-gate XDR_SETPOS(&xdrs, 0); 226*7c478bd9Sstevel@tonic-gate stat = xdr_authunix_parms(&xdrs, &aup); 227*7c478bd9Sstevel@tonic-gate if (!stat) 228*7c478bd9Sstevel@tonic-gate goto done; 229*7c478bd9Sstevel@tonic-gate auth->ah_cred = au->au_origcred; 230*7c478bd9Sstevel@tonic-gate marshal_new_auth(auth); 231*7c478bd9Sstevel@tonic-gate done: 232*7c478bd9Sstevel@tonic-gate /* free the struct authunix_parms created by deserializing */ 233*7c478bd9Sstevel@tonic-gate xdrs.x_op = XDR_FREE; 234*7c478bd9Sstevel@tonic-gate (void) xdr_authunix_parms(&xdrs, &aup); 235*7c478bd9Sstevel@tonic-gate XDR_DESTROY(&xdrs); 236*7c478bd9Sstevel@tonic-gate return (stat); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate static void 240*7c478bd9Sstevel@tonic-gate authunix_destroy(AUTH *auth) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate struct audata *au = AUTH_PRIVATE(auth); 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate if (au->au_shcred.oa_base != NULL) 245*7c478bd9Sstevel@tonic-gate bkmem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 246*7c478bd9Sstevel@tonic-gate bkmem_free(auth->ah_private, sizeof (struct audata)); 247*7c478bd9Sstevel@tonic-gate if (auth->ah_verf.oa_base != NULL) 248*7c478bd9Sstevel@tonic-gate bkmem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 249*7c478bd9Sstevel@tonic-gate bkmem_free((caddr_t)auth, sizeof (*auth)); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate /* 253*7c478bd9Sstevel@tonic-gate * Marshals (pre-serializes) an auth struct. 254*7c478bd9Sstevel@tonic-gate * sets private data, au_marshed and au_mpos 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate static void 257*7c478bd9Sstevel@tonic-gate marshal_new_auth(AUTH *auth) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate XDR xdr_stream; 260*7c478bd9Sstevel@tonic-gate XDR *xdrs = &xdr_stream; 261*7c478bd9Sstevel@tonic-gate struct audata *au = AUTH_PRIVATE(auth); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 264*7c478bd9Sstevel@tonic-gate if ((!xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 265*7c478bd9Sstevel@tonic-gate (!xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { 266*7c478bd9Sstevel@tonic-gate dprintf("marshal_new_auth - Fatal marshalling problem"); 267*7c478bd9Sstevel@tonic-gate } else { 268*7c478bd9Sstevel@tonic-gate au->au_mpos = XDR_GETPOS(xdrs); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate XDR_DESTROY(xdrs); 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate static struct auth_ops * 275*7c478bd9Sstevel@tonic-gate authunix_ops(void) 276*7c478bd9Sstevel@tonic-gate { 277*7c478bd9Sstevel@tonic-gate static struct auth_ops ops; 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate if (ops.ah_nextverf == 0) { 280*7c478bd9Sstevel@tonic-gate ops.ah_nextverf = authunix_nextverf; 281*7c478bd9Sstevel@tonic-gate ops.ah_marshal = authunix_marshal; 282*7c478bd9Sstevel@tonic-gate ops.ah_validate = authunix_validate; 283*7c478bd9Sstevel@tonic-gate ops.ah_refresh = authunix_refresh; 284*7c478bd9Sstevel@tonic-gate ops.ah_destroy = authunix_destroy; 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate return (&ops); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * XDR for unix authentication parameters. 291*7c478bd9Sstevel@tonic-gate */ 292*7c478bd9Sstevel@tonic-gate bool_t 293*7c478bd9Sstevel@tonic-gate xdr_authunix_parms(XDR *xdrs, struct authunix_parms *p) 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate if (xdr_u_int(xdrs, &(p->aup_time)) && 296*7c478bd9Sstevel@tonic-gate xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) && 297*7c478bd9Sstevel@tonic-gate xdr_int(xdrs, (int *)&(p->aup_uid)) && 298*7c478bd9Sstevel@tonic-gate xdr_int(xdrs, (int *)&(p->aup_gid)) && 299*7c478bd9Sstevel@tonic-gate xdr_array(xdrs, (caddr_t *)&(p->aup_gids), 300*7c478bd9Sstevel@tonic-gate &(p->aup_len), NGRPS, sizeof (int), xdr_int)) { 301*7c478bd9Sstevel@tonic-gate return (TRUE); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate return (FALSE); 304*7c478bd9Sstevel@tonic-gate } 305