18360efbdSAlfred Perlstein /* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */ 28360efbdSAlfred Perlstein 399064799SGarrett Wollman /* 499064799SGarrett Wollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 599064799SGarrett Wollman * unrestricted use provided that this legend is included on all tape 699064799SGarrett Wollman * media and as a part of the software program in whole or part. Users 799064799SGarrett Wollman * may copy or modify Sun RPC without charge, but are not authorized 899064799SGarrett Wollman * to license or distribute it to anyone else except as part of a product or 999064799SGarrett Wollman * program developed by the user. 1099064799SGarrett Wollman * 1199064799SGarrett Wollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1299064799SGarrett Wollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1399064799SGarrett Wollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1499064799SGarrett Wollman * 1599064799SGarrett Wollman * Sun RPC is provided with no support and without any obligation on the 1699064799SGarrett Wollman * part of Sun Microsystems, Inc. to assist in its use, correction, 1799064799SGarrett Wollman * modification or enhancement. 1899064799SGarrett Wollman * 1999064799SGarrett Wollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2099064799SGarrett Wollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2199064799SGarrett Wollman * OR ANY PART THEREOF. 2299064799SGarrett Wollman * 2399064799SGarrett Wollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2499064799SGarrett Wollman * or profits or other special, indirect and consequential damages, even if 2599064799SGarrett Wollman * Sun has been advised of the possibility of such damages. 2699064799SGarrett Wollman * 2799064799SGarrett Wollman * Sun Microsystems, Inc. 2899064799SGarrett Wollman * 2550 Garcia Avenue 2999064799SGarrett Wollman * Mountain View, California 94043 3099064799SGarrett Wollman */ 3199064799SGarrett Wollman 328360efbdSAlfred Perlstein #include <sys/cdefs.h> 3399064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 347f3dea24SPeter Wemm static char *rcsid = "$FreeBSD$"; 358360efbdSAlfred Perlstein static char *sccsid = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 368360efbdSAlfred Perlstein static char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC"; 3799064799SGarrett Wollman #endif 3899064799SGarrett Wollman 3999064799SGarrett Wollman /* 4099064799SGarrett Wollman * auth_unix.c, Implements UNIX style authentication parameters. 4199064799SGarrett Wollman * 4299064799SGarrett Wollman * Copyright (C) 1984, Sun Microsystems, Inc. 4399064799SGarrett Wollman * 4499064799SGarrett Wollman * The system is very weak. The client uses no encryption for it's 4599064799SGarrett Wollman * credentials and only sends null verifiers. The server sends backs 4699064799SGarrett Wollman * null verifiers or optionally a verifier that suggests a new short hand 4799064799SGarrett Wollman * for the credentials. 4899064799SGarrett Wollman * 4999064799SGarrett Wollman */ 5099064799SGarrett Wollman 518360efbdSAlfred Perlstein #include "reentrant.h" 528360efbdSAlfred Perlstein #include "namespace.h" 538360efbdSAlfred Perlstein #include <sys/param.h> 548360efbdSAlfred Perlstein 558360efbdSAlfred Perlstein #include <assert.h> 568360efbdSAlfred Perlstein #include <err.h> 5799064799SGarrett Wollman #include <stdio.h> 5899064799SGarrett Wollman #include <stdlib.h> 594c3af266SPoul-Henning Kamp #include <unistd.h> 604c3af266SPoul-Henning Kamp #include <string.h> 6199064799SGarrett Wollman 6299064799SGarrett Wollman #include <rpc/types.h> 6399064799SGarrett Wollman #include <rpc/xdr.h> 6499064799SGarrett Wollman #include <rpc/auth.h> 6599064799SGarrett Wollman #include <rpc/auth_unix.h> 668360efbdSAlfred Perlstein #include "un-namespace.h" 6799064799SGarrett Wollman 688360efbdSAlfred Perlstein /* auth_unix.c */ 698360efbdSAlfred Perlstein static void authunix_nextverf (AUTH *); 708360efbdSAlfred Perlstein static bool_t authunix_marshal (AUTH *, XDR *); 718360efbdSAlfred Perlstein static bool_t authunix_validate (AUTH *, struct opaque_auth *); 728360efbdSAlfred Perlstein static bool_t authunix_refresh (AUTH *, void *); 738360efbdSAlfred Perlstein static void authunix_destroy (AUTH *); 748360efbdSAlfred Perlstein static void marshal_new_auth (AUTH *); 758360efbdSAlfred Perlstein static struct auth_ops *authunix_ops (void); 7699064799SGarrett Wollman 7799064799SGarrett Wollman /* 7899064799SGarrett Wollman * This struct is pointed to by the ah_private field of an auth_handle. 7999064799SGarrett Wollman */ 8099064799SGarrett Wollman struct audata { 8199064799SGarrett Wollman struct opaque_auth au_origcred; /* original credentials */ 8299064799SGarrett Wollman struct opaque_auth au_shcred; /* short hand cred */ 8399064799SGarrett Wollman u_long au_shfaults; /* short hand cache faults */ 8499064799SGarrett Wollman char au_marshed[MAX_AUTH_BYTES]; 8599064799SGarrett Wollman u_int au_mpos; /* xdr pos at end of marshed */ 8699064799SGarrett Wollman }; 8799064799SGarrett Wollman #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 8899064799SGarrett Wollman 8999064799SGarrett Wollman /* 9099064799SGarrett Wollman * Create a unix style authenticator. 9199064799SGarrett Wollman * Returns an auth handle with the given stuff in it. 9299064799SGarrett Wollman */ 9399064799SGarrett Wollman AUTH * 9499064799SGarrett Wollman authunix_create(machname, uid, gid, len, aup_gids) 9599064799SGarrett Wollman char *machname; 9699064799SGarrett Wollman int uid; 9799064799SGarrett Wollman int gid; 988360efbdSAlfred Perlstein int len; 9999064799SGarrett Wollman int *aup_gids; 10099064799SGarrett Wollman { 10199064799SGarrett Wollman struct authunix_parms aup; 10299064799SGarrett Wollman char mymem[MAX_AUTH_BYTES]; 10399064799SGarrett Wollman struct timeval now; 10499064799SGarrett Wollman XDR xdrs; 1058360efbdSAlfred Perlstein AUTH *auth; 1068360efbdSAlfred Perlstein struct audata *au; 10799064799SGarrett Wollman 10899064799SGarrett Wollman /* 10999064799SGarrett Wollman * Allocate and set up auth handle 11099064799SGarrett Wollman */ 1118360efbdSAlfred Perlstein au = NULL; 1128360efbdSAlfred Perlstein auth = mem_alloc(sizeof(*auth)); 113c4473420SPeter Wemm #ifndef _KERNEL 11499064799SGarrett Wollman if (auth == NULL) { 1158360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1168360efbdSAlfred Perlstein goto cleanup_authunix_create; 11799064799SGarrett Wollman } 11899064799SGarrett Wollman #endif 1198360efbdSAlfred Perlstein au = mem_alloc(sizeof(*au)); 120c4473420SPeter Wemm #ifndef _KERNEL 12199064799SGarrett Wollman if (au == NULL) { 1228360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1238360efbdSAlfred Perlstein goto cleanup_authunix_create; 12499064799SGarrett Wollman } 12599064799SGarrett Wollman #endif 1268360efbdSAlfred Perlstein auth->ah_ops = authunix_ops(); 12799064799SGarrett Wollman auth->ah_private = (caddr_t)au; 12899064799SGarrett Wollman auth->ah_verf = au->au_shcred = _null_auth; 12999064799SGarrett Wollman au->au_shfaults = 0; 1308360efbdSAlfred Perlstein au->au_origcred.oa_base = NULL; 13199064799SGarrett Wollman 13299064799SGarrett Wollman /* 13399064799SGarrett Wollman * fill in param struct from the given params 13499064799SGarrett Wollman */ 1358360efbdSAlfred Perlstein (void)gettimeofday(&now, NULL); 13699064799SGarrett Wollman aup.aup_time = now.tv_sec; 13799064799SGarrett Wollman aup.aup_machname = machname; 13899064799SGarrett Wollman aup.aup_uid = uid; 13999064799SGarrett Wollman aup.aup_gid = gid; 14099064799SGarrett Wollman aup.aup_len = (u_int)len; 14199064799SGarrett Wollman aup.aup_gids = aup_gids; 14299064799SGarrett Wollman 14399064799SGarrett Wollman /* 14499064799SGarrett Wollman * Serialize the parameters into origcred 14599064799SGarrett Wollman */ 14699064799SGarrett Wollman xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 14799064799SGarrett Wollman if (! xdr_authunix_parms(&xdrs, &aup)) 14899064799SGarrett Wollman abort(); 14999064799SGarrett Wollman au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 15099064799SGarrett Wollman au->au_origcred.oa_flavor = AUTH_UNIX; 151c4473420SPeter Wemm #ifdef _KERNEL 15299064799SGarrett Wollman au->au_origcred.oa_base = mem_alloc((u_int) len); 15399064799SGarrett Wollman #else 15499064799SGarrett Wollman if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { 1558360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1568360efbdSAlfred Perlstein goto cleanup_authunix_create; 15799064799SGarrett Wollman } 15899064799SGarrett Wollman #endif 1598360efbdSAlfred Perlstein memmove(au->au_origcred.oa_base, mymem, (size_t)len); 16099064799SGarrett Wollman 16199064799SGarrett Wollman /* 16299064799SGarrett Wollman * set auth handle to reflect new cred. 16399064799SGarrett Wollman */ 16499064799SGarrett Wollman auth->ah_cred = au->au_origcred; 16599064799SGarrett Wollman marshal_new_auth(auth); 16699064799SGarrett Wollman return (auth); 1678360efbdSAlfred Perlstein #ifndef _KERNEL 1688360efbdSAlfred Perlstein cleanup_authunix_create: 1698360efbdSAlfred Perlstein if (auth) 1708360efbdSAlfred Perlstein mem_free(auth, sizeof(*auth)); 1718360efbdSAlfred Perlstein if (au) { 1728360efbdSAlfred Perlstein if (au->au_origcred.oa_base) 1738360efbdSAlfred Perlstein mem_free(au->au_origcred.oa_base, (u_int)len); 1748360efbdSAlfred Perlstein mem_free(au, sizeof(*au)); 1758360efbdSAlfred Perlstein } 1768360efbdSAlfred Perlstein return (NULL); 1778360efbdSAlfred Perlstein #endif 17899064799SGarrett Wollman } 17999064799SGarrett Wollman 18099064799SGarrett Wollman /* 18199064799SGarrett Wollman * Returns an auth handle with parameters determined by doing lots of 18299064799SGarrett Wollman * syscalls. 18399064799SGarrett Wollman */ 18499064799SGarrett Wollman AUTH * 18599064799SGarrett Wollman authunix_create_default() 18699064799SGarrett Wollman { 1878360efbdSAlfred Perlstein int len; 1888360efbdSAlfred Perlstein char machname[MAXHOSTNAMELEN + 1]; 1898360efbdSAlfred Perlstein uid_t uid; 1908360efbdSAlfred Perlstein gid_t gid; 1918360efbdSAlfred Perlstein gid_t gids[NGRPS]; 19299064799SGarrett Wollman 1938360efbdSAlfred Perlstein if (gethostname(machname, sizeof machname) == -1) 19499064799SGarrett Wollman abort(); 1958360efbdSAlfred Perlstein machname[sizeof(machname) - 1] = 0; 1968360efbdSAlfred Perlstein uid = geteuid(); 1978360efbdSAlfred Perlstein gid = getegid(); 1988360efbdSAlfred Perlstein if ((len = getgroups(NGRPS, gids)) < 0) 19999064799SGarrett Wollman abort(); 2008360efbdSAlfred Perlstein /* XXX: interface problem; those should all have been unsigned */ 2018360efbdSAlfred Perlstein return (authunix_create(machname, (int)uid, (int)gid, len, 2028360efbdSAlfred Perlstein (int *)gids)); 20399064799SGarrett Wollman } 20499064799SGarrett Wollman 20599064799SGarrett Wollman /* 20699064799SGarrett Wollman * authunix operations 20799064799SGarrett Wollman */ 20899064799SGarrett Wollman 2098360efbdSAlfred Perlstein /* ARGSUSED */ 21099064799SGarrett Wollman static void 21199064799SGarrett Wollman authunix_nextverf(auth) 21299064799SGarrett Wollman AUTH *auth; 21399064799SGarrett Wollman { 21499064799SGarrett Wollman /* no action necessary */ 21599064799SGarrett Wollman } 21699064799SGarrett Wollman 21799064799SGarrett Wollman static bool_t 21899064799SGarrett Wollman authunix_marshal(auth, xdrs) 21999064799SGarrett Wollman AUTH *auth; 22099064799SGarrett Wollman XDR *xdrs; 22199064799SGarrett Wollman { 2228360efbdSAlfred Perlstein struct audata *au; 22399064799SGarrett Wollman 2248360efbdSAlfred Perlstein assert(auth != NULL); 2258360efbdSAlfred Perlstein assert(xdrs != NULL); 2268360efbdSAlfred Perlstein 2278360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 22899064799SGarrett Wollman return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 22999064799SGarrett Wollman } 23099064799SGarrett Wollman 23199064799SGarrett Wollman static bool_t 23299064799SGarrett Wollman authunix_validate(auth, verf) 2338360efbdSAlfred Perlstein AUTH *auth; 2348360efbdSAlfred Perlstein struct opaque_auth *verf; 23599064799SGarrett Wollman { 2368360efbdSAlfred Perlstein struct audata *au; 23799064799SGarrett Wollman XDR xdrs; 23899064799SGarrett Wollman 2398360efbdSAlfred Perlstein assert(auth != NULL); 2408360efbdSAlfred Perlstein assert(verf != NULL); 2418360efbdSAlfred Perlstein 2428360efbdSAlfred Perlstein if (verf->oa_flavor == AUTH_SHORT) { 24399064799SGarrett Wollman au = AUTH_PRIVATE(auth); 2448360efbdSAlfred Perlstein xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 2458360efbdSAlfred Perlstein XDR_DECODE); 24699064799SGarrett Wollman 24799064799SGarrett Wollman if (au->au_shcred.oa_base != NULL) { 24899064799SGarrett Wollman mem_free(au->au_shcred.oa_base, 24999064799SGarrett Wollman au->au_shcred.oa_length); 25099064799SGarrett Wollman au->au_shcred.oa_base = NULL; 25199064799SGarrett Wollman } 25299064799SGarrett Wollman if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 25399064799SGarrett Wollman auth->ah_cred = au->au_shcred; 25499064799SGarrett Wollman } else { 25599064799SGarrett Wollman xdrs.x_op = XDR_FREE; 25699064799SGarrett Wollman (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 25799064799SGarrett Wollman au->au_shcred.oa_base = NULL; 25899064799SGarrett Wollman auth->ah_cred = au->au_origcred; 25999064799SGarrett Wollman } 26099064799SGarrett Wollman marshal_new_auth(auth); 26199064799SGarrett Wollman } 26299064799SGarrett Wollman return (TRUE); 26399064799SGarrett Wollman } 26499064799SGarrett Wollman 26599064799SGarrett Wollman static bool_t 2668360efbdSAlfred Perlstein authunix_refresh(AUTH *auth, void *dummy) 26799064799SGarrett Wollman { 2688360efbdSAlfred Perlstein struct audata *au = AUTH_PRIVATE(auth); 26999064799SGarrett Wollman struct authunix_parms aup; 27099064799SGarrett Wollman struct timeval now; 27199064799SGarrett Wollman XDR xdrs; 2728360efbdSAlfred Perlstein int stat; 2738360efbdSAlfred Perlstein 2748360efbdSAlfred Perlstein assert(auth != NULL); 27599064799SGarrett Wollman 27699064799SGarrett Wollman if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 27799064799SGarrett Wollman /* there is no hope. Punt */ 27899064799SGarrett Wollman return (FALSE); 27999064799SGarrett Wollman } 28099064799SGarrett Wollman au->au_shfaults ++; 28199064799SGarrett Wollman 28299064799SGarrett Wollman /* first deserialize the creds back into a struct authunix_parms */ 28399064799SGarrett Wollman aup.aup_machname = NULL; 2848360efbdSAlfred Perlstein aup.aup_gids = NULL; 28599064799SGarrett Wollman xdrmem_create(&xdrs, au->au_origcred.oa_base, 28699064799SGarrett Wollman au->au_origcred.oa_length, XDR_DECODE); 28799064799SGarrett Wollman stat = xdr_authunix_parms(&xdrs, &aup); 28899064799SGarrett Wollman if (! stat) 28999064799SGarrett Wollman goto done; 29099064799SGarrett Wollman 29199064799SGarrett Wollman /* update the time and serialize in place */ 2928360efbdSAlfred Perlstein (void)gettimeofday(&now, NULL); 29399064799SGarrett Wollman aup.aup_time = now.tv_sec; 29499064799SGarrett Wollman xdrs.x_op = XDR_ENCODE; 29599064799SGarrett Wollman XDR_SETPOS(&xdrs, 0); 29699064799SGarrett Wollman stat = xdr_authunix_parms(&xdrs, &aup); 29799064799SGarrett Wollman if (! stat) 29899064799SGarrett Wollman goto done; 29999064799SGarrett Wollman auth->ah_cred = au->au_origcred; 30099064799SGarrett Wollman marshal_new_auth(auth); 30199064799SGarrett Wollman done: 30299064799SGarrett Wollman /* free the struct authunix_parms created by deserializing */ 30399064799SGarrett Wollman xdrs.x_op = XDR_FREE; 30499064799SGarrett Wollman (void)xdr_authunix_parms(&xdrs, &aup); 30599064799SGarrett Wollman XDR_DESTROY(&xdrs); 30699064799SGarrett Wollman return (stat); 30799064799SGarrett Wollman } 30899064799SGarrett Wollman 30999064799SGarrett Wollman static void 31099064799SGarrett Wollman authunix_destroy(auth) 3118360efbdSAlfred Perlstein AUTH *auth; 31299064799SGarrett Wollman { 3138360efbdSAlfred Perlstein struct audata *au; 31499064799SGarrett Wollman 3158360efbdSAlfred Perlstein assert(auth != NULL); 3168360efbdSAlfred Perlstein 3178360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 31899064799SGarrett Wollman mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 31999064799SGarrett Wollman 32099064799SGarrett Wollman if (au->au_shcred.oa_base != NULL) 32199064799SGarrett Wollman mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 32299064799SGarrett Wollman 32399064799SGarrett Wollman mem_free(auth->ah_private, sizeof(struct audata)); 32499064799SGarrett Wollman 32599064799SGarrett Wollman if (auth->ah_verf.oa_base != NULL) 32699064799SGarrett Wollman mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 32799064799SGarrett Wollman 3288360efbdSAlfred Perlstein mem_free(auth, sizeof(*auth)); 32999064799SGarrett Wollman } 33099064799SGarrett Wollman 33199064799SGarrett Wollman /* 33299064799SGarrett Wollman * Marshals (pre-serializes) an auth struct. 33399064799SGarrett Wollman * sets private data, au_marshed and au_mpos 33499064799SGarrett Wollman */ 3354c3af266SPoul-Henning Kamp static void 33699064799SGarrett Wollman marshal_new_auth(auth) 3378360efbdSAlfred Perlstein AUTH *auth; 33899064799SGarrett Wollman { 33999064799SGarrett Wollman XDR xdr_stream; 3408360efbdSAlfred Perlstein XDR *xdrs = &xdr_stream; 3418360efbdSAlfred Perlstein struct audata *au; 34299064799SGarrett Wollman 3438360efbdSAlfred Perlstein assert(auth != NULL); 3448360efbdSAlfred Perlstein 3458360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 34699064799SGarrett Wollman xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 34799064799SGarrett Wollman if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 3488360efbdSAlfred Perlstein (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 3498360efbdSAlfred Perlstein warnx("auth_none.c - Fatal marshalling problem"); 3508360efbdSAlfred Perlstein else 35199064799SGarrett Wollman au->au_mpos = XDR_GETPOS(xdrs); 35299064799SGarrett Wollman XDR_DESTROY(xdrs); 35399064799SGarrett Wollman } 3548360efbdSAlfred Perlstein 3558360efbdSAlfred Perlstein static struct auth_ops * 3568360efbdSAlfred Perlstein authunix_ops() 3578360efbdSAlfred Perlstein { 3588360efbdSAlfred Perlstein static struct auth_ops ops; 3598360efbdSAlfred Perlstein extern mutex_t ops_lock; 3608360efbdSAlfred Perlstein 3618360efbdSAlfred Perlstein /* VARIABLES PROTECTED BY ops_lock: ops */ 3628360efbdSAlfred Perlstein 3638360efbdSAlfred Perlstein mutex_lock(&ops_lock); 3648360efbdSAlfred Perlstein if (ops.ah_nextverf == NULL) { 3658360efbdSAlfred Perlstein ops.ah_nextverf = authunix_nextverf; 3668360efbdSAlfred Perlstein ops.ah_marshal = authunix_marshal; 3678360efbdSAlfred Perlstein ops.ah_validate = authunix_validate; 3688360efbdSAlfred Perlstein ops.ah_refresh = authunix_refresh; 3698360efbdSAlfred Perlstein ops.ah_destroy = authunix_destroy; 3708360efbdSAlfred Perlstein } 3718360efbdSAlfred Perlstein mutex_unlock(&ops_lock); 3728360efbdSAlfred Perlstein return (&ops); 3738360efbdSAlfred Perlstein } 374