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 3299064799SGarrett Wollman #if defined(LIBC_SCCS) && !defined(lint) 33a986ef57SDavid E. O'Brien static char *sccsid2 = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 348360efbdSAlfred Perlstein static char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC"; 3599064799SGarrett Wollman #endif 36d3d20c82SDavid E. O'Brien #include <sys/cdefs.h> 37d3d20c82SDavid E. O'Brien __FBSDID("$FreeBSD$"); 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 "namespace.h" 529f5afc13SIan Dowse #include "reentrant.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" 67235baf26SDaniel Eischen #include "mt_misc.h" 6899064799SGarrett Wollman 698360efbdSAlfred Perlstein /* auth_unix.c */ 708360efbdSAlfred Perlstein static void authunix_nextverf (AUTH *); 718360efbdSAlfred Perlstein static bool_t authunix_marshal (AUTH *, XDR *); 728360efbdSAlfred Perlstein static bool_t authunix_validate (AUTH *, struct opaque_auth *); 738360efbdSAlfred Perlstein static bool_t authunix_refresh (AUTH *, void *); 748360efbdSAlfred Perlstein static void authunix_destroy (AUTH *); 758360efbdSAlfred Perlstein static void marshal_new_auth (AUTH *); 768360efbdSAlfred Perlstein static struct auth_ops *authunix_ops (void); 7799064799SGarrett Wollman 7899064799SGarrett Wollman /* 7999064799SGarrett Wollman * This struct is pointed to by the ah_private field of an auth_handle. 8099064799SGarrett Wollman */ 8199064799SGarrett Wollman struct audata { 8299064799SGarrett Wollman struct opaque_auth au_origcred; /* original credentials */ 8399064799SGarrett Wollman struct opaque_auth au_shcred; /* short hand cred */ 8499064799SGarrett Wollman u_long au_shfaults; /* short hand cache faults */ 8599064799SGarrett Wollman char au_marshed[MAX_AUTH_BYTES]; 8699064799SGarrett Wollman u_int au_mpos; /* xdr pos at end of marshed */ 8799064799SGarrett Wollman }; 8899064799SGarrett Wollman #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 8999064799SGarrett Wollman 9099064799SGarrett Wollman /* 9199064799SGarrett Wollman * Create a unix style authenticator. 9299064799SGarrett Wollman * Returns an auth handle with the given stuff in it. 9399064799SGarrett Wollman */ 9499064799SGarrett Wollman AUTH * 9599064799SGarrett Wollman authunix_create(machname, uid, gid, len, aup_gids) 9699064799SGarrett Wollman char *machname; 9799064799SGarrett Wollman int uid; 9899064799SGarrett Wollman int gid; 998360efbdSAlfred Perlstein int len; 10099064799SGarrett Wollman int *aup_gids; 10199064799SGarrett Wollman { 10299064799SGarrett Wollman struct authunix_parms aup; 10399064799SGarrett Wollman char mymem[MAX_AUTH_BYTES]; 10499064799SGarrett Wollman struct timeval now; 10599064799SGarrett Wollman XDR xdrs; 1068360efbdSAlfred Perlstein AUTH *auth; 1078360efbdSAlfred Perlstein struct audata *au; 10899064799SGarrett Wollman 10999064799SGarrett Wollman /* 11099064799SGarrett Wollman * Allocate and set up auth handle 11199064799SGarrett Wollman */ 1128360efbdSAlfred Perlstein au = NULL; 1138360efbdSAlfred Perlstein auth = mem_alloc(sizeof(*auth)); 114c4473420SPeter Wemm #ifndef _KERNEL 11599064799SGarrett Wollman if (auth == NULL) { 1168360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1178360efbdSAlfred Perlstein goto cleanup_authunix_create; 11899064799SGarrett Wollman } 11999064799SGarrett Wollman #endif 1208360efbdSAlfred Perlstein au = mem_alloc(sizeof(*au)); 121c4473420SPeter Wemm #ifndef _KERNEL 12299064799SGarrett Wollman if (au == NULL) { 1238360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1248360efbdSAlfred Perlstein goto cleanup_authunix_create; 12599064799SGarrett Wollman } 12699064799SGarrett Wollman #endif 1278360efbdSAlfred Perlstein auth->ah_ops = authunix_ops(); 12899064799SGarrett Wollman auth->ah_private = (caddr_t)au; 12999064799SGarrett Wollman auth->ah_verf = au->au_shcred = _null_auth; 13099064799SGarrett Wollman au->au_shfaults = 0; 1318360efbdSAlfred Perlstein au->au_origcred.oa_base = NULL; 13299064799SGarrett Wollman 13399064799SGarrett Wollman /* 13499064799SGarrett Wollman * fill in param struct from the given params 13599064799SGarrett Wollman */ 1368360efbdSAlfred Perlstein (void)gettimeofday(&now, NULL); 13799064799SGarrett Wollman aup.aup_time = now.tv_sec; 13899064799SGarrett Wollman aup.aup_machname = machname; 13999064799SGarrett Wollman aup.aup_uid = uid; 14099064799SGarrett Wollman aup.aup_gid = gid; 14199064799SGarrett Wollman aup.aup_len = (u_int)len; 14299064799SGarrett Wollman aup.aup_gids = aup_gids; 14399064799SGarrett Wollman 14499064799SGarrett Wollman /* 14599064799SGarrett Wollman * Serialize the parameters into origcred 14699064799SGarrett Wollman */ 14799064799SGarrett Wollman xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 14899064799SGarrett Wollman if (! xdr_authunix_parms(&xdrs, &aup)) 14999064799SGarrett Wollman abort(); 15099064799SGarrett Wollman au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 15199064799SGarrett Wollman au->au_origcred.oa_flavor = AUTH_UNIX; 152c4473420SPeter Wemm #ifdef _KERNEL 15399064799SGarrett Wollman au->au_origcred.oa_base = mem_alloc((u_int) len); 15499064799SGarrett Wollman #else 15599064799SGarrett Wollman if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { 1568360efbdSAlfred Perlstein warnx("authunix_create: out of memory"); 1578360efbdSAlfred Perlstein goto cleanup_authunix_create; 15899064799SGarrett Wollman } 15999064799SGarrett Wollman #endif 1608360efbdSAlfred Perlstein memmove(au->au_origcred.oa_base, mymem, (size_t)len); 16199064799SGarrett Wollman 16299064799SGarrett Wollman /* 16399064799SGarrett Wollman * set auth handle to reflect new cred. 16499064799SGarrett Wollman */ 16599064799SGarrett Wollman auth->ah_cred = au->au_origcred; 16699064799SGarrett Wollman marshal_new_auth(auth); 16799064799SGarrett Wollman return (auth); 1688360efbdSAlfred Perlstein #ifndef _KERNEL 1698360efbdSAlfred Perlstein cleanup_authunix_create: 1708360efbdSAlfred Perlstein if (auth) 1718360efbdSAlfred Perlstein mem_free(auth, sizeof(*auth)); 1728360efbdSAlfred Perlstein if (au) { 1738360efbdSAlfred Perlstein if (au->au_origcred.oa_base) 1748360efbdSAlfred Perlstein mem_free(au->au_origcred.oa_base, (u_int)len); 1758360efbdSAlfred Perlstein mem_free(au, sizeof(*au)); 1768360efbdSAlfred Perlstein } 1778360efbdSAlfred Perlstein return (NULL); 1788360efbdSAlfred Perlstein #endif 17999064799SGarrett Wollman } 18099064799SGarrett Wollman 18199064799SGarrett Wollman /* 18299064799SGarrett Wollman * Returns an auth handle with parameters determined by doing lots of 18399064799SGarrett Wollman * syscalls. 18499064799SGarrett Wollman */ 18599064799SGarrett Wollman AUTH * 18699064799SGarrett Wollman authunix_create_default() 18799064799SGarrett Wollman { 1888360efbdSAlfred Perlstein int len; 1898360efbdSAlfred Perlstein char machname[MAXHOSTNAMELEN + 1]; 1908360efbdSAlfred Perlstein uid_t uid; 1918360efbdSAlfred Perlstein gid_t gid; 1928360efbdSAlfred Perlstein gid_t gids[NGRPS]; 19399064799SGarrett Wollman 1948360efbdSAlfred Perlstein if (gethostname(machname, sizeof machname) == -1) 19599064799SGarrett Wollman abort(); 1968360efbdSAlfred Perlstein machname[sizeof(machname) - 1] = 0; 1978360efbdSAlfred Perlstein uid = geteuid(); 1988360efbdSAlfred Perlstein gid = getegid(); 1998360efbdSAlfred Perlstein if ((len = getgroups(NGRPS, gids)) < 0) 20099064799SGarrett Wollman abort(); 2018360efbdSAlfred Perlstein /* XXX: interface problem; those should all have been unsigned */ 2028360efbdSAlfred Perlstein return (authunix_create(machname, (int)uid, (int)gid, len, 2038360efbdSAlfred Perlstein (int *)gids)); 20499064799SGarrett Wollman } 20599064799SGarrett Wollman 20699064799SGarrett Wollman /* 20799064799SGarrett Wollman * authunix operations 20899064799SGarrett Wollman */ 20999064799SGarrett Wollman 2108360efbdSAlfred Perlstein /* ARGSUSED */ 21199064799SGarrett Wollman static void 21299064799SGarrett Wollman authunix_nextverf(auth) 21399064799SGarrett Wollman AUTH *auth; 21499064799SGarrett Wollman { 21599064799SGarrett Wollman /* no action necessary */ 21699064799SGarrett Wollman } 21799064799SGarrett Wollman 21899064799SGarrett Wollman static bool_t 21999064799SGarrett Wollman authunix_marshal(auth, xdrs) 22099064799SGarrett Wollman AUTH *auth; 22199064799SGarrett Wollman XDR *xdrs; 22299064799SGarrett Wollman { 2238360efbdSAlfred Perlstein struct audata *au; 22499064799SGarrett Wollman 2258360efbdSAlfred Perlstein assert(auth != NULL); 2268360efbdSAlfred Perlstein assert(xdrs != NULL); 2278360efbdSAlfred Perlstein 2288360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 22999064799SGarrett Wollman return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 23099064799SGarrett Wollman } 23199064799SGarrett Wollman 23299064799SGarrett Wollman static bool_t 23399064799SGarrett Wollman authunix_validate(auth, verf) 2348360efbdSAlfred Perlstein AUTH *auth; 2358360efbdSAlfred Perlstein struct opaque_auth *verf; 23699064799SGarrett Wollman { 2378360efbdSAlfred Perlstein struct audata *au; 23899064799SGarrett Wollman XDR xdrs; 23999064799SGarrett Wollman 2408360efbdSAlfred Perlstein assert(auth != NULL); 2418360efbdSAlfred Perlstein assert(verf != NULL); 2428360efbdSAlfred Perlstein 2438360efbdSAlfred Perlstein if (verf->oa_flavor == AUTH_SHORT) { 24499064799SGarrett Wollman au = AUTH_PRIVATE(auth); 2458360efbdSAlfred Perlstein xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 2468360efbdSAlfred Perlstein XDR_DECODE); 24799064799SGarrett Wollman 24899064799SGarrett Wollman if (au->au_shcred.oa_base != NULL) { 24999064799SGarrett Wollman mem_free(au->au_shcred.oa_base, 25099064799SGarrett Wollman au->au_shcred.oa_length); 25199064799SGarrett Wollman au->au_shcred.oa_base = NULL; 25299064799SGarrett Wollman } 25399064799SGarrett Wollman if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 25499064799SGarrett Wollman auth->ah_cred = au->au_shcred; 25599064799SGarrett Wollman } else { 25699064799SGarrett Wollman xdrs.x_op = XDR_FREE; 25799064799SGarrett Wollman (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 25899064799SGarrett Wollman au->au_shcred.oa_base = NULL; 25999064799SGarrett Wollman auth->ah_cred = au->au_origcred; 26099064799SGarrett Wollman } 26199064799SGarrett Wollman marshal_new_auth(auth); 26299064799SGarrett Wollman } 26399064799SGarrett Wollman return (TRUE); 26499064799SGarrett Wollman } 26599064799SGarrett Wollman 26699064799SGarrett Wollman static bool_t 2678360efbdSAlfred Perlstein authunix_refresh(AUTH *auth, void *dummy) 26899064799SGarrett Wollman { 2698360efbdSAlfred Perlstein struct audata *au = AUTH_PRIVATE(auth); 27099064799SGarrett Wollman struct authunix_parms aup; 27199064799SGarrett Wollman struct timeval now; 27299064799SGarrett Wollman XDR xdrs; 2738360efbdSAlfred Perlstein int stat; 2748360efbdSAlfred Perlstein 2758360efbdSAlfred Perlstein assert(auth != NULL); 27699064799SGarrett Wollman 27799064799SGarrett Wollman if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 27899064799SGarrett Wollman /* there is no hope. Punt */ 27999064799SGarrett Wollman return (FALSE); 28099064799SGarrett Wollman } 28199064799SGarrett Wollman au->au_shfaults ++; 28299064799SGarrett Wollman 28399064799SGarrett Wollman /* first deserialize the creds back into a struct authunix_parms */ 28499064799SGarrett Wollman aup.aup_machname = NULL; 2858360efbdSAlfred Perlstein aup.aup_gids = NULL; 28699064799SGarrett Wollman xdrmem_create(&xdrs, au->au_origcred.oa_base, 28799064799SGarrett Wollman au->au_origcred.oa_length, XDR_DECODE); 28899064799SGarrett Wollman stat = xdr_authunix_parms(&xdrs, &aup); 28999064799SGarrett Wollman if (! stat) 29099064799SGarrett Wollman goto done; 29199064799SGarrett Wollman 29299064799SGarrett Wollman /* update the time and serialize in place */ 2938360efbdSAlfred Perlstein (void)gettimeofday(&now, NULL); 29499064799SGarrett Wollman aup.aup_time = now.tv_sec; 29599064799SGarrett Wollman xdrs.x_op = XDR_ENCODE; 29699064799SGarrett Wollman XDR_SETPOS(&xdrs, 0); 29799064799SGarrett Wollman stat = xdr_authunix_parms(&xdrs, &aup); 29899064799SGarrett Wollman if (! stat) 29999064799SGarrett Wollman goto done; 30099064799SGarrett Wollman auth->ah_cred = au->au_origcred; 30199064799SGarrett Wollman marshal_new_auth(auth); 30299064799SGarrett Wollman done: 30399064799SGarrett Wollman /* free the struct authunix_parms created by deserializing */ 30499064799SGarrett Wollman xdrs.x_op = XDR_FREE; 30599064799SGarrett Wollman (void)xdr_authunix_parms(&xdrs, &aup); 30699064799SGarrett Wollman XDR_DESTROY(&xdrs); 30799064799SGarrett Wollman return (stat); 30899064799SGarrett Wollman } 30999064799SGarrett Wollman 31099064799SGarrett Wollman static void 31199064799SGarrett Wollman authunix_destroy(auth) 3128360efbdSAlfred Perlstein AUTH *auth; 31399064799SGarrett Wollman { 3148360efbdSAlfred Perlstein struct audata *au; 31599064799SGarrett Wollman 3168360efbdSAlfred Perlstein assert(auth != NULL); 3178360efbdSAlfred Perlstein 3188360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 31999064799SGarrett Wollman mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 32099064799SGarrett Wollman 32199064799SGarrett Wollman if (au->au_shcred.oa_base != NULL) 32299064799SGarrett Wollman mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 32399064799SGarrett Wollman 32499064799SGarrett Wollman mem_free(auth->ah_private, sizeof(struct audata)); 32599064799SGarrett Wollman 32699064799SGarrett Wollman if (auth->ah_verf.oa_base != NULL) 32799064799SGarrett Wollman mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 32899064799SGarrett Wollman 3298360efbdSAlfred Perlstein mem_free(auth, sizeof(*auth)); 33099064799SGarrett Wollman } 33199064799SGarrett Wollman 33299064799SGarrett Wollman /* 33399064799SGarrett Wollman * Marshals (pre-serializes) an auth struct. 33499064799SGarrett Wollman * sets private data, au_marshed and au_mpos 33599064799SGarrett Wollman */ 3364c3af266SPoul-Henning Kamp static void 33799064799SGarrett Wollman marshal_new_auth(auth) 3388360efbdSAlfred Perlstein AUTH *auth; 33999064799SGarrett Wollman { 34099064799SGarrett Wollman XDR xdr_stream; 3418360efbdSAlfred Perlstein XDR *xdrs = &xdr_stream; 3428360efbdSAlfred Perlstein struct audata *au; 34399064799SGarrett Wollman 3448360efbdSAlfred Perlstein assert(auth != NULL); 3458360efbdSAlfred Perlstein 3468360efbdSAlfred Perlstein au = AUTH_PRIVATE(auth); 34799064799SGarrett Wollman xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 34899064799SGarrett Wollman if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 3498360efbdSAlfred Perlstein (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 3508360efbdSAlfred Perlstein warnx("auth_none.c - Fatal marshalling problem"); 3518360efbdSAlfred Perlstein else 35299064799SGarrett Wollman au->au_mpos = XDR_GETPOS(xdrs); 35399064799SGarrett Wollman XDR_DESTROY(xdrs); 35499064799SGarrett Wollman } 3558360efbdSAlfred Perlstein 3568360efbdSAlfred Perlstein static struct auth_ops * 3578360efbdSAlfred Perlstein authunix_ops() 3588360efbdSAlfred Perlstein { 3598360efbdSAlfred Perlstein static struct auth_ops ops; 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