auth_unix.c revision 177685
1177633Sdfr/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */ 2177633Sdfr 3177633Sdfr/* 4177633Sdfr * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5177633Sdfr * unrestricted use provided that this legend is included on all tape 6177633Sdfr * media and as a part of the software program in whole or part. Users 7177633Sdfr * may copy or modify Sun RPC without charge, but are not authorized 8177633Sdfr * to license or distribute it to anyone else except as part of a product or 9177633Sdfr * program developed by the user. 10177633Sdfr * 11177633Sdfr * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12177633Sdfr * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13177633Sdfr * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14177633Sdfr * 15177633Sdfr * Sun RPC is provided with no support and without any obligation on the 16177633Sdfr * part of Sun Microsystems, Inc. to assist in its use, correction, 17177633Sdfr * modification or enhancement. 18177633Sdfr * 19177633Sdfr * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20177633Sdfr * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21177633Sdfr * OR ANY PART THEREOF. 22177633Sdfr * 23177633Sdfr * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24177633Sdfr * or profits or other special, indirect and consequential damages, even if 25177633Sdfr * Sun has been advised of the possibility of such damages. 26177633Sdfr * 27177633Sdfr * Sun Microsystems, Inc. 28177633Sdfr * 2550 Garcia Avenue 29177633Sdfr * Mountain View, California 94043 30177633Sdfr */ 31177633Sdfr 32177633Sdfr#if defined(LIBC_SCCS) && !defined(lint) 33177633Sdfrstatic char *sccsid2 = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 34177633Sdfrstatic char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC"; 35177633Sdfr#endif 36177633Sdfr#include <sys/cdefs.h> 37177633Sdfr__FBSDID("$FreeBSD: head/sys/rpc/auth_unix.c 177685 2008-03-28 09:50:32Z dfr $"); 38177633Sdfr 39177633Sdfr/* 40177633Sdfr * auth_unix.c, Implements UNIX style authentication parameters. 41177633Sdfr * 42177633Sdfr * Copyright (C) 1984, Sun Microsystems, Inc. 43177633Sdfr * 44177633Sdfr * The system is very weak. The client uses no encryption for it's 45177633Sdfr * credentials and only sends null verifiers. The server sends backs 46177633Sdfr * null verifiers or optionally a verifier that suggests a new short hand 47177633Sdfr * for the credentials. 48177633Sdfr * 49177633Sdfr */ 50177633Sdfr 51177633Sdfr#include <sys/param.h> 52177633Sdfr#include <sys/systm.h> 53177633Sdfr#include <sys/lock.h> 54177633Sdfr#include <sys/malloc.h> 55177633Sdfr#include <sys/mutex.h> 56177633Sdfr#include <sys/ucred.h> 57177633Sdfr 58177633Sdfr#include <rpc/types.h> 59177633Sdfr#include <rpc/xdr.h> 60177633Sdfr#include <rpc/auth.h> 61177633Sdfr 62177685Sdfr#include <rpc/rpc_com.h> 63177633Sdfr 64177633Sdfr/* auth_unix.c */ 65177633Sdfrstatic void authunix_nextverf (AUTH *); 66177633Sdfrstatic bool_t authunix_marshal (AUTH *, XDR *); 67177633Sdfrstatic bool_t authunix_validate (AUTH *, struct opaque_auth *); 68177633Sdfrstatic bool_t authunix_refresh (AUTH *, void *); 69177633Sdfrstatic void authunix_destroy (AUTH *); 70177633Sdfrstatic void marshal_new_auth (AUTH *); 71177633Sdfr 72177633Sdfrstatic struct auth_ops authunix_ops = { 73177633Sdfr .ah_nextverf = authunix_nextverf, 74177633Sdfr .ah_marshal = authunix_marshal, 75177633Sdfr .ah_validate = authunix_validate, 76177633Sdfr .ah_refresh = authunix_refresh, 77177633Sdfr .ah_destroy = authunix_destroy 78177633Sdfr}; 79177633Sdfr 80177633Sdfr/* 81177633Sdfr * This struct is pointed to by the ah_private field of an auth_handle. 82177633Sdfr */ 83177633Sdfrstruct audata { 84177633Sdfr struct opaque_auth au_origcred; /* original credentials */ 85177633Sdfr struct opaque_auth au_shcred; /* short hand cred */ 86177633Sdfr u_long au_shfaults; /* short hand cache faults */ 87177633Sdfr char au_marshed[MAX_AUTH_BYTES]; 88177633Sdfr u_int au_mpos; /* xdr pos at end of marshed */ 89177633Sdfr}; 90177633Sdfr#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 91177633Sdfr 92177633Sdfr/* 93177633Sdfr * Create a unix style authenticator. 94177633Sdfr * Returns an auth handle with the given stuff in it. 95177633Sdfr */ 96177633SdfrAUTH * 97177633Sdfrauthunix_create(struct ucred *cred) 98177633Sdfr{ 99177633Sdfr struct xucred xcr; 100177633Sdfr char mymem[MAX_AUTH_BYTES]; 101177633Sdfr XDR xdrs; 102177633Sdfr AUTH *auth; 103177633Sdfr struct audata *au; 104177633Sdfr struct timeval now; 105177633Sdfr uint32_t time; 106177633Sdfr int len; 107177633Sdfr 108177633Sdfr /* 109177633Sdfr * Allocate and set up auth handle 110177633Sdfr */ 111177633Sdfr au = NULL; 112177633Sdfr auth = mem_alloc(sizeof(*auth)); 113177633Sdfr#ifndef _KERNEL 114177633Sdfr if (auth == NULL) { 115177633Sdfr printf("authunix_create: out of memory"); 116177633Sdfr goto cleanup_authunix_create; 117177633Sdfr } 118177633Sdfr#endif 119177633Sdfr au = mem_alloc(sizeof(*au)); 120177633Sdfr#ifndef _KERNEL 121177633Sdfr if (au == NULL) { 122177633Sdfr printf("authunix_create: out of memory"); 123177633Sdfr goto cleanup_authunix_create; 124177633Sdfr } 125177633Sdfr#endif 126177633Sdfr auth->ah_ops = &authunix_ops; 127177633Sdfr auth->ah_private = (caddr_t)au; 128177633Sdfr auth->ah_verf = au->au_shcred = _null_auth; 129177633Sdfr au->au_shfaults = 0; 130177633Sdfr au->au_origcred.oa_base = NULL; 131177633Sdfr 132177633Sdfr getmicrotime(&now); 133177633Sdfr time = now.tv_sec; 134177633Sdfr 135177633Sdfr /* 136177633Sdfr * Serialize the parameters into origcred 137177633Sdfr */ 138177633Sdfr xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 139177633Sdfr cru2x(cred, &xcr); 140177633Sdfr if (! xdr_authunix_parms(&xdrs, &time, &xcr)) 141177633Sdfr panic("authunix_create: failed to encode creds"); 142177633Sdfr au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 143177633Sdfr au->au_origcred.oa_flavor = AUTH_UNIX; 144177633Sdfr#ifdef _KERNEL 145177633Sdfr au->au_origcred.oa_base = mem_alloc((u_int) len); 146177633Sdfr#else 147177633Sdfr if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { 148177633Sdfr printf("authunix_create: out of memory"); 149177633Sdfr goto cleanup_authunix_create; 150177633Sdfr } 151177633Sdfr#endif 152177633Sdfr memcpy(au->au_origcred.oa_base, mymem, (size_t)len); 153177633Sdfr 154177633Sdfr /* 155177633Sdfr * set auth handle to reflect new cred. 156177633Sdfr */ 157177633Sdfr auth->ah_cred = au->au_origcred; 158177633Sdfr marshal_new_auth(auth); 159177633Sdfr return (auth); 160177633Sdfr#ifndef _KERNEL 161177633Sdfr cleanup_authunix_create: 162177633Sdfr if (auth) 163177633Sdfr mem_free(auth, sizeof(*auth)); 164177633Sdfr if (au) { 165177633Sdfr if (au->au_origcred.oa_base) 166177633Sdfr mem_free(au->au_origcred.oa_base, (u_int)len); 167177633Sdfr mem_free(au, sizeof(*au)); 168177633Sdfr } 169177633Sdfr return (NULL); 170177633Sdfr#endif 171177633Sdfr} 172177633Sdfr 173177633Sdfr/* 174177633Sdfr * authunix operations 175177633Sdfr */ 176177633Sdfr 177177633Sdfr/* ARGSUSED */ 178177633Sdfrstatic void 179177633Sdfrauthunix_nextverf(AUTH *auth) 180177633Sdfr{ 181177633Sdfr /* no action necessary */ 182177633Sdfr} 183177633Sdfr 184177633Sdfrstatic bool_t 185177633Sdfrauthunix_marshal(AUTH *auth, XDR *xdrs) 186177633Sdfr{ 187177633Sdfr struct audata *au; 188177633Sdfr 189177633Sdfr au = AUTH_PRIVATE(auth); 190177633Sdfr return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 191177633Sdfr} 192177633Sdfr 193177633Sdfrstatic bool_t 194177633Sdfrauthunix_validate(AUTH *auth, struct opaque_auth *verf) 195177633Sdfr{ 196177633Sdfr struct audata *au; 197177633Sdfr XDR xdrs; 198177633Sdfr 199177633Sdfr if (verf->oa_flavor == AUTH_SHORT) { 200177633Sdfr au = AUTH_PRIVATE(auth); 201177633Sdfr xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 202177633Sdfr XDR_DECODE); 203177633Sdfr 204177633Sdfr if (au->au_shcred.oa_base != NULL) { 205177633Sdfr mem_free(au->au_shcred.oa_base, 206177633Sdfr au->au_shcred.oa_length); 207177633Sdfr au->au_shcred.oa_base = NULL; 208177633Sdfr } 209177633Sdfr if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 210177633Sdfr auth->ah_cred = au->au_shcred; 211177633Sdfr } else { 212177633Sdfr xdrs.x_op = XDR_FREE; 213177633Sdfr (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 214177633Sdfr au->au_shcred.oa_base = NULL; 215177633Sdfr auth->ah_cred = au->au_origcred; 216177633Sdfr } 217177633Sdfr marshal_new_auth(auth); 218177633Sdfr } 219177633Sdfr return (TRUE); 220177633Sdfr} 221177633Sdfr 222177633Sdfrstatic bool_t 223177633Sdfrauthunix_refresh(AUTH *auth, void *dummy) 224177633Sdfr{ 225177633Sdfr struct audata *au = AUTH_PRIVATE(auth); 226177633Sdfr struct xucred xcr; 227177633Sdfr uint32_t time; 228177633Sdfr struct timeval now; 229177633Sdfr XDR xdrs; 230177633Sdfr int stat; 231177633Sdfr 232177633Sdfr if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 233177633Sdfr /* there is no hope. Punt */ 234177633Sdfr return (FALSE); 235177633Sdfr } 236177633Sdfr au->au_shfaults ++; 237177633Sdfr 238177633Sdfr /* first deserialize the creds back into a struct ucred */ 239177633Sdfr xdrmem_create(&xdrs, au->au_origcred.oa_base, 240177633Sdfr au->au_origcred.oa_length, XDR_DECODE); 241177633Sdfr stat = xdr_authunix_parms(&xdrs, &time, &xcr); 242177633Sdfr if (! stat) 243177633Sdfr goto done; 244177633Sdfr 245177633Sdfr /* update the time and serialize in place */ 246177633Sdfr getmicrotime(&now); 247177633Sdfr time = now.tv_sec; 248177633Sdfr xdrs.x_op = XDR_ENCODE; 249177633Sdfr XDR_SETPOS(&xdrs, 0); 250177633Sdfr 251177633Sdfr stat = xdr_authunix_parms(&xdrs, &time, &xcr); 252177633Sdfr if (! stat) 253177633Sdfr goto done; 254177633Sdfr auth->ah_cred = au->au_origcred; 255177633Sdfr marshal_new_auth(auth); 256177633Sdfrdone: 257177633Sdfr XDR_DESTROY(&xdrs); 258177633Sdfr return (stat); 259177633Sdfr} 260177633Sdfr 261177633Sdfrstatic void 262177633Sdfrauthunix_destroy(AUTH *auth) 263177633Sdfr{ 264177633Sdfr struct audata *au; 265177633Sdfr 266177633Sdfr au = AUTH_PRIVATE(auth); 267177633Sdfr mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 268177633Sdfr 269177633Sdfr if (au->au_shcred.oa_base != NULL) 270177633Sdfr mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 271177633Sdfr 272177633Sdfr mem_free(auth->ah_private, sizeof(struct audata)); 273177633Sdfr 274177633Sdfr if (auth->ah_verf.oa_base != NULL) 275177633Sdfr mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 276177633Sdfr 277177633Sdfr mem_free(auth, sizeof(*auth)); 278177633Sdfr} 279177633Sdfr 280177633Sdfr/* 281177633Sdfr * Marshals (pre-serializes) an auth struct. 282177633Sdfr * sets private data, au_marshed and au_mpos 283177633Sdfr */ 284177633Sdfrstatic void 285177633Sdfrmarshal_new_auth(AUTH *auth) 286177633Sdfr{ 287177633Sdfr XDR xdr_stream; 288177633Sdfr XDR *xdrs = &xdr_stream; 289177633Sdfr struct audata *au; 290177633Sdfr 291177633Sdfr au = AUTH_PRIVATE(auth); 292177633Sdfr xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 293177633Sdfr if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 294177633Sdfr (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 295177633Sdfr printf("auth_none.c - Fatal marshalling problem"); 296177633Sdfr else 297177633Sdfr au->au_mpos = XDR_GETPOS(xdrs); 298177633Sdfr XDR_DESTROY(xdrs); 299177633Sdfr} 300