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 * Adapted for use by the boot program. 39 * 40 * auth_unix.c, Implements UNIX style authentication parameters. 41 * 42 * The system is very weak. The client uses no encryption for its 43 * credentials and only sends null verifiers. The server sends backs 44 * null verifiers or optionally a verifier that suggests a new short hand 45 * for the credentials. 46 */ 47 48 #include <stdlib.h> 49 #include <sys/sysmacros.h> 50 #include <rpc/types.h> 51 #include <rpc/xdr.h> 52 #include <rpc/auth.h> 53 #include "clnt.h" 54 #include <rpc/auth_unix.h> 55 #include <sys/promif.h> 56 #include <sys/salib.h> 57 #include <sys/bootdebug.h> 58 #include "nfs_inet.h" 59 60 static struct auth_ops *authunix_ops(); 61 /* 62 * This struct is pointed to by the ah_private field of an auth_handle. 63 */ 64 struct audata { 65 struct opaque_auth au_origcred; /* original credentials */ 66 struct opaque_auth au_shcred; /* short hand cred */ 67 uint_t au_shfaults; /* short hand cache faults */ 68 char au_marshed[MAX_AUTH_BYTES]; 69 uint_t au_mpos; /* xdr pos at end of marshed */ 70 }; 71 #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 72 73 static void marshal_new_auth(AUTH *); 74 75 #define dprintf if (boothowto & RB_DEBUG) printf 76 77 /* 78 * Create a unix style authenticator. 79 * Returns an auth handle with the given stuff in it. 80 */ 81 AUTH * 82 authunix_create(char *machname, uid_t uid, gid_t gid, int len, gid_t *aup_gids) 83 { 84 struct authunix_parms aup; 85 char mymem[MAX_AUTH_BYTES]; 86 XDR xdrs; 87 AUTH *auth; 88 struct audata *au; 89 90 /* 91 * Allocate and set up auth handle 92 */ 93 auth = (AUTH *) bkmem_alloc(sizeof (*auth)); 94 if (auth == NULL) { 95 prom_panic("authunix_create: Cannot allocate memory."); 96 return (NULL); 97 } 98 99 au = (struct audata *)bkmem_alloc(sizeof (*au)); 100 if (au == NULL) { 101 prom_panic("authunix_create: Cannot allocate memory."); 102 return (NULL); 103 } 104 105 /* setup authenticator. */ 106 auth->ah_ops = authunix_ops(); 107 auth->ah_private = (caddr_t)au; 108 109 /* structure copies */ 110 auth->ah_verf = au->au_shcred = _null_auth; 111 112 au->au_shfaults = 0; 113 114 /* 115 * fill in param struct from the given params 116 */ 117 aup.aup_time = prom_gettime() / 1000; 118 aup.aup_machname = machname; 119 aup.aup_uid = uid; 120 aup.aup_gid = gid; 121 aup.aup_len = (uint_t)len; 122 aup.aup_gids = (gid_t *)aup_gids; 123 124 /* 125 * Serialize the parameters into origcred 126 */ 127 xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 128 if (!xdr_authunix_parms(&xdrs, &aup)) { 129 prom_panic("authunix_create: xdr_authunix_parms failed"); 130 bkmem_free(auth->ah_private, sizeof (struct audata)); 131 bkmem_free((caddr_t)auth, sizeof (*auth)); 132 return ((AUTH *)0); 133 } 134 au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 135 au->au_origcred.oa_flavor = (uint_t)AUTH_UNIX; 136 if ((au->au_origcred.oa_base = bkmem_alloc((uint_t)len)) == NULL) { 137 prom_panic("authunix_create: memory alloc failed"); 138 bkmem_free(auth->ah_private, sizeof (struct audata)); 139 bkmem_free((caddr_t)auth, sizeof (*auth)); 140 return ((AUTH *)0); 141 } 142 (void) bcopy(mymem, au->au_origcred.oa_base, (uint_t)len); 143 144 /* 145 * set auth handle to reflect new cred. 146 */ 147 auth->ah_cred = au->au_origcred; 148 marshal_new_auth(auth); 149 return (auth); 150 } 151 152 /* 153 * authunix operations 154 */ 155 156 /* ARGSUSED */ 157 static void 158 authunix_nextverf(AUTH *auth) 159 { 160 } 161 162 /* ARGSUSED */ 163 static bool_t 164 authunix_marshal(AUTH *auth, XDR *xdrs, cred_t *cr) 165 { 166 struct audata *au = AUTH_PRIVATE(auth); 167 168 return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 169 } 170 171 static bool_t 172 authunix_validate(AUTH *auth, struct opaque_auth *verf) 173 { 174 struct audata *au; 175 XDR xdrs; 176 177 if (verf->oa_flavor == AUTH_SHORT) { 178 au = AUTH_PRIVATE(auth); 179 180 181 xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 182 XDR_DECODE); 183 184 if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 185 auth->ah_cred = au->au_shcred; 186 } else { 187 xdrs.x_op = XDR_FREE; 188 (void) xdr_opaque_auth(&xdrs, &au->au_shcred); 189 au->au_shcred.oa_base = 0; 190 auth->ah_cred = au->au_origcred; 191 } 192 marshal_new_auth(auth); 193 } 194 195 return (TRUE); 196 } 197 198 /*ARGSUSED*/ 199 static bool_t 200 authunix_refresh(AUTH *auth, struct rpc_msg *msg, cred_t *cr) 201 { 202 struct audata *au = AUTH_PRIVATE(auth); 203 struct authunix_parms aup; 204 XDR xdrs; 205 int stat; 206 207 if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 208 /* there is no hope. Punt */ 209 return (FALSE); 210 } 211 au->au_shfaults ++; 212 213 /* first deserialize the creds back into a struct authunix_parms */ 214 aup.aup_machname = (char *)0; 215 aup.aup_gids = (gid_t *)0; 216 xdrmem_create(&xdrs, au->au_origcred.oa_base, 217 au->au_origcred.oa_length, XDR_DECODE); 218 stat = xdr_authunix_parms(&xdrs, &aup); 219 if (!stat) 220 goto done; 221 222 /* update the time and serialize in place */ 223 aup.aup_time = (prom_gettime() / 1000); 224 xdrs.x_op = XDR_ENCODE; 225 XDR_SETPOS(&xdrs, 0); 226 stat = xdr_authunix_parms(&xdrs, &aup); 227 if (!stat) 228 goto done; 229 auth->ah_cred = au->au_origcred; 230 marshal_new_auth(auth); 231 done: 232 /* free the struct authunix_parms created by deserializing */ 233 xdrs.x_op = XDR_FREE; 234 (void) xdr_authunix_parms(&xdrs, &aup); 235 XDR_DESTROY(&xdrs); 236 return (stat); 237 } 238 239 static void 240 authunix_destroy(AUTH *auth) 241 { 242 struct audata *au = AUTH_PRIVATE(auth); 243 244 if (au->au_shcred.oa_base != NULL) 245 bkmem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 246 bkmem_free(auth->ah_private, sizeof (struct audata)); 247 if (auth->ah_verf.oa_base != NULL) 248 bkmem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 249 bkmem_free((caddr_t)auth, sizeof (*auth)); 250 } 251 252 /* 253 * Marshals (pre-serializes) an auth struct. 254 * sets private data, au_marshed and au_mpos 255 */ 256 static void 257 marshal_new_auth(AUTH *auth) 258 { 259 XDR xdr_stream; 260 XDR *xdrs = &xdr_stream; 261 struct audata *au = AUTH_PRIVATE(auth); 262 263 xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 264 if ((!xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 265 (!xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { 266 dprintf("marshal_new_auth - Fatal marshalling problem"); 267 } else { 268 au->au_mpos = XDR_GETPOS(xdrs); 269 } 270 XDR_DESTROY(xdrs); 271 } 272 273 274 static struct auth_ops * 275 authunix_ops(void) 276 { 277 static struct auth_ops ops; 278 279 if (ops.ah_nextverf == 0) { 280 ops.ah_nextverf = authunix_nextverf; 281 ops.ah_marshal = authunix_marshal; 282 ops.ah_validate = authunix_validate; 283 ops.ah_refresh = authunix_refresh; 284 ops.ah_destroy = authunix_destroy; 285 } 286 return (&ops); 287 } 288 289 /* 290 * XDR for unix authentication parameters. 291 */ 292 bool_t 293 xdr_authunix_parms(XDR *xdrs, struct authunix_parms *p) 294 { 295 if (xdr_u_int(xdrs, &(p->aup_time)) && 296 xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) && 297 xdr_int(xdrs, (int *)&(p->aup_uid)) && 298 xdr_int(xdrs, (int *)&(p->aup_gid)) && 299 xdr_array(xdrs, (caddr_t *)&(p->aup_gids), 300 &(p->aup_len), NGRPS, sizeof (int), xdr_int)) { 301 return (TRUE); 302 } 303 return (FALSE); 304 } 305