174462Salfred/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */ 274462Salfred 31901Swollman/* 41901Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 51901Swollman * unrestricted use provided that this legend is included on all tape 61901Swollman * media and as a part of the software program in whole or part. Users 71901Swollman * may copy or modify Sun RPC without charge, but are not authorized 81901Swollman * to license or distribute it to anyone else except as part of a product or 91901Swollman * program developed by the user. 108870Srgrimes * 111901Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 121901Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 131901Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 148870Srgrimes * 151901Swollman * Sun RPC is provided with no support and without any obligation on the 161901Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 171901Swollman * modification or enhancement. 181901Swollman * 191901Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 201901Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 211901Swollman * OR ANY PART THEREOF. 228870Srgrimes * 231901Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 241901Swollman * or profits or other special, indirect and consequential damages, even if 251901Swollman * Sun has been advised of the possibility of such damages. 268870Srgrimes * 271901Swollman * Sun Microsystems, Inc. 281901Swollman * 2550 Garcia Avenue 291901Swollman * Mountain View, California 94043 301901Swollman */ 311901Swollman 321901Swollman#if defined(LIBC_SCCS) && !defined(lint) 33136581Sobrienstatic char *sccsid2 = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 3474462Salfredstatic char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC"; 351901Swollman#endif 3692990Sobrien#include <sys/cdefs.h> 3792990Sobrien__FBSDID("$FreeBSD$"); 381901Swollman 391901Swollman/* 408870Srgrimes * auth_unix.c, Implements UNIX style authentication parameters. 418870Srgrimes * 421901Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 431901Swollman * 441901Swollman * The system is very weak. The client uses no encryption for it's 451901Swollman * credentials and only sends null verifiers. The server sends backs 461901Swollman * null verifiers or optionally a verifier that suggests a new short hand 471901Swollman * for the credentials. 481901Swollman * 491901Swollman */ 501901Swollman 5175094Siedowse#include "namespace.h" 5274462Salfred#include "reentrant.h" 5374462Salfred#include <sys/param.h> 5474462Salfred 5574462Salfred#include <assert.h> 5674462Salfred#include <err.h> 571901Swollman#include <stdio.h> 581901Swollman#include <stdlib.h> 5911666Sphk#include <unistd.h> 6011666Sphk#include <string.h> 611901Swollman 621901Swollman#include <rpc/types.h> 631901Swollman#include <rpc/xdr.h> 641901Swollman#include <rpc/auth.h> 651901Swollman#include <rpc/auth_unix.h> 6674462Salfred#include "un-namespace.h" 67156090Sdeischen#include "mt_misc.h" 681901Swollman 6974462Salfred/* auth_unix.c */ 7074462Salfredstatic void authunix_nextverf (AUTH *); 7174462Salfredstatic bool_t authunix_marshal (AUTH *, XDR *); 7274462Salfredstatic bool_t authunix_validate (AUTH *, struct opaque_auth *); 7374462Salfredstatic bool_t authunix_refresh (AUTH *, void *); 7474462Salfredstatic void authunix_destroy (AUTH *); 7574462Salfredstatic void marshal_new_auth (AUTH *); 7674462Salfredstatic struct auth_ops *authunix_ops (void); 771901Swollman 781901Swollman/* 791901Swollman * This struct is pointed to by the ah_private field of an auth_handle. 801901Swollman */ 811901Swollmanstruct audata { 821901Swollman struct opaque_auth au_origcred; /* original credentials */ 831901Swollman struct opaque_auth au_shcred; /* short hand cred */ 841901Swollman u_long au_shfaults; /* short hand cache faults */ 851901Swollman char au_marshed[MAX_AUTH_BYTES]; 861901Swollman u_int au_mpos; /* xdr pos at end of marshed */ 871901Swollman}; 881901Swollman#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) 891901Swollman 901994Swollman/* 911901Swollman * Create a unix style authenticator. 921901Swollman * Returns an auth handle with the given stuff in it. 931901Swollman */ 941901SwollmanAUTH * 951901Swollmanauthunix_create(machname, uid, gid, len, aup_gids) 961901Swollman char *machname; 97241181Spfg u_int uid; 98241181Spfg u_int gid; 9974462Salfred int len; 100241181Spfg u_int *aup_gids; 1011901Swollman{ 1021901Swollman struct authunix_parms aup; 1031901Swollman char mymem[MAX_AUTH_BYTES]; 1041901Swollman struct timeval now; 1051901Swollman XDR xdrs; 10674462Salfred AUTH *auth; 10774462Salfred struct audata *au; 1081901Swollman 1091901Swollman /* 1101901Swollman * Allocate and set up auth handle 1111901Swollman */ 11274462Salfred au = NULL; 11374462Salfred auth = mem_alloc(sizeof(*auth)); 11455206Speter#ifndef _KERNEL 1151901Swollman if (auth == NULL) { 11674462Salfred warnx("authunix_create: out of memory"); 11774462Salfred goto cleanup_authunix_create; 1181901Swollman } 1191901Swollman#endif 12074462Salfred au = mem_alloc(sizeof(*au)); 12155206Speter#ifndef _KERNEL 1221901Swollman if (au == NULL) { 12374462Salfred warnx("authunix_create: out of memory"); 12474462Salfred goto cleanup_authunix_create; 1251901Swollman } 1261901Swollman#endif 12774462Salfred auth->ah_ops = authunix_ops(); 1281901Swollman auth->ah_private = (caddr_t)au; 1291901Swollman auth->ah_verf = au->au_shcred = _null_auth; 1301901Swollman au->au_shfaults = 0; 13174462Salfred au->au_origcred.oa_base = NULL; 1321901Swollman 1331901Swollman /* 1341901Swollman * fill in param struct from the given params 1351901Swollman */ 13674462Salfred (void)gettimeofday(&now, NULL); 1371901Swollman aup.aup_time = now.tv_sec; 1381901Swollman aup.aup_machname = machname; 1391901Swollman aup.aup_uid = uid; 1401901Swollman aup.aup_gid = gid; 14174462Salfred aup.aup_len = (u_int)len; 1421901Swollman aup.aup_gids = aup_gids; 1431901Swollman 1441901Swollman /* 1451901Swollman * Serialize the parameters into origcred 1461901Swollman */ 1471901Swollman xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); 14874462Salfred if (! xdr_authunix_parms(&xdrs, &aup)) 1491901Swollman abort(); 1501901Swollman au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); 1511901Swollman au->au_origcred.oa_flavor = AUTH_UNIX; 15255206Speter#ifdef _KERNEL 1531901Swollman au->au_origcred.oa_base = mem_alloc((u_int) len); 1541901Swollman#else 1551901Swollman if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { 15674462Salfred warnx("authunix_create: out of memory"); 15774462Salfred goto cleanup_authunix_create; 1581901Swollman } 1591901Swollman#endif 16074462Salfred memmove(au->au_origcred.oa_base, mymem, (size_t)len); 1611901Swollman 1621901Swollman /* 1631901Swollman * set auth handle to reflect new cred. 1641901Swollman */ 1651901Swollman auth->ah_cred = au->au_origcred; 1661901Swollman marshal_new_auth(auth); 1671901Swollman return (auth); 16874462Salfred#ifndef _KERNEL 16974462Salfred cleanup_authunix_create: 17074462Salfred if (auth) 17174462Salfred mem_free(auth, sizeof(*auth)); 17274462Salfred if (au) { 17374462Salfred if (au->au_origcred.oa_base) 17474462Salfred mem_free(au->au_origcred.oa_base, (u_int)len); 17574462Salfred mem_free(au, sizeof(*au)); 17674462Salfred } 17774462Salfred return (NULL); 17874462Salfred#endif 1791901Swollman} 1801901Swollman 1811901Swollman/* 1821901Swollman * Returns an auth handle with parameters determined by doing lots of 1831901Swollman * syscalls. 1841901Swollman */ 1851901SwollmanAUTH * 1861901Swollmanauthunix_create_default() 1871901Swollman{ 188235143Skib AUTH *auth; 189194494Sbrooks int ngids; 190194494Sbrooks long ngids_max; 19174462Salfred char machname[MAXHOSTNAMELEN + 1]; 19274462Salfred uid_t uid; 19374462Salfred gid_t gid; 194194494Sbrooks gid_t *gids; 1951901Swollman 196194494Sbrooks ngids_max = sysconf(_SC_NGROUPS_MAX) + 1; 197194494Sbrooks gids = malloc(sizeof(gid_t) * ngids_max); 198194494Sbrooks if (gids == NULL) 199194494Sbrooks return (NULL); 200194494Sbrooks 20174462Salfred if (gethostname(machname, sizeof machname) == -1) 2021901Swollman abort(); 20374462Salfred machname[sizeof(machname) - 1] = 0; 20474462Salfred uid = geteuid(); 20574462Salfred gid = getegid(); 206194494Sbrooks if ((ngids = getgroups(ngids_max, gids)) < 0) 2071901Swollman abort(); 208194494Sbrooks if (ngids > NGRPS) 209194494Sbrooks ngids = NGRPS; 210241181Spfg /* XXX: interface problem; we should translate from uid_t and gid_t */ 211241141Spfg auth = authunix_create(machname, uid, gid, ngids, gids); 212235143Skib free(gids); 213235143Skib return (auth); 2141901Swollman} 2151901Swollman 2161901Swollman/* 2171901Swollman * authunix operations 2181901Swollman */ 2191901Swollman 22074462Salfred/* ARGSUSED */ 2211901Swollmanstatic void 2221901Swollmanauthunix_nextverf(auth) 2231901Swollman AUTH *auth; 2241901Swollman{ 2251901Swollman /* no action necessary */ 2261901Swollman} 2271901Swollman 2281901Swollmanstatic bool_t 2291901Swollmanauthunix_marshal(auth, xdrs) 2301901Swollman AUTH *auth; 2311901Swollman XDR *xdrs; 2321901Swollman{ 23374462Salfred struct audata *au; 2341901Swollman 23574462Salfred assert(auth != NULL); 23674462Salfred assert(xdrs != NULL); 23774462Salfred 23874462Salfred au = AUTH_PRIVATE(auth); 2391901Swollman return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 2401901Swollman} 2411901Swollman 2421901Swollmanstatic bool_t 2431901Swollmanauthunix_validate(auth, verf) 24474462Salfred AUTH *auth; 24574462Salfred struct opaque_auth *verf; 2461901Swollman{ 24774462Salfred struct audata *au; 2481901Swollman XDR xdrs; 2491901Swollman 25074462Salfred assert(auth != NULL); 25174462Salfred assert(verf != NULL); 25274462Salfred 25374462Salfred if (verf->oa_flavor == AUTH_SHORT) { 2541901Swollman au = AUTH_PRIVATE(auth); 25574462Salfred xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 25674462Salfred XDR_DECODE); 2571901Swollman 2581901Swollman if (au->au_shcred.oa_base != NULL) { 2591901Swollman mem_free(au->au_shcred.oa_base, 2601901Swollman au->au_shcred.oa_length); 2611901Swollman au->au_shcred.oa_base = NULL; 2621901Swollman } 2631901Swollman if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 2641901Swollman auth->ah_cred = au->au_shcred; 2651901Swollman } else { 2661901Swollman xdrs.x_op = XDR_FREE; 2671901Swollman (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 2681901Swollman au->au_shcred.oa_base = NULL; 2691901Swollman auth->ah_cred = au->au_origcred; 2701901Swollman } 2711901Swollman marshal_new_auth(auth); 2721901Swollman } 2731901Swollman return (TRUE); 2741901Swollman} 2751901Swollman 2761901Swollmanstatic bool_t 27774462Salfredauthunix_refresh(AUTH *auth, void *dummy) 2781901Swollman{ 27974462Salfred struct audata *au = AUTH_PRIVATE(auth); 2801901Swollman struct authunix_parms aup; 2811901Swollman struct timeval now; 2821901Swollman XDR xdrs; 28374462Salfred int stat; 2841901Swollman 28574462Salfred assert(auth != NULL); 28674462Salfred 2871901Swollman if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 2881901Swollman /* there is no hope. Punt */ 2891901Swollman return (FALSE); 2901901Swollman } 2911901Swollman au->au_shfaults ++; 2921901Swollman 2931901Swollman /* first deserialize the creds back into a struct authunix_parms */ 2941901Swollman aup.aup_machname = NULL; 29574462Salfred aup.aup_gids = NULL; 2961901Swollman xdrmem_create(&xdrs, au->au_origcred.oa_base, 2971901Swollman au->au_origcred.oa_length, XDR_DECODE); 2981901Swollman stat = xdr_authunix_parms(&xdrs, &aup); 2998870Srgrimes if (! stat) 3001901Swollman goto done; 3011901Swollman 3021901Swollman /* update the time and serialize in place */ 30374462Salfred (void)gettimeofday(&now, NULL); 3041901Swollman aup.aup_time = now.tv_sec; 3051901Swollman xdrs.x_op = XDR_ENCODE; 3061901Swollman XDR_SETPOS(&xdrs, 0); 3071901Swollman stat = xdr_authunix_parms(&xdrs, &aup); 3081901Swollman if (! stat) 3091901Swollman goto done; 3101901Swollman auth->ah_cred = au->au_origcred; 3111901Swollman marshal_new_auth(auth); 3121901Swollmandone: 3131901Swollman /* free the struct authunix_parms created by deserializing */ 3141901Swollman xdrs.x_op = XDR_FREE; 3151901Swollman (void)xdr_authunix_parms(&xdrs, &aup); 3161901Swollman XDR_DESTROY(&xdrs); 3171901Swollman return (stat); 3181901Swollman} 3191901Swollman 3201901Swollmanstatic void 3211901Swollmanauthunix_destroy(auth) 32274462Salfred AUTH *auth; 3231901Swollman{ 32474462Salfred struct audata *au; 3251901Swollman 32674462Salfred assert(auth != NULL); 32774462Salfred 32874462Salfred au = AUTH_PRIVATE(auth); 3291901Swollman mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 3301901Swollman 3311901Swollman if (au->au_shcred.oa_base != NULL) 3321901Swollman mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 3331901Swollman 3341901Swollman mem_free(auth->ah_private, sizeof(struct audata)); 3351901Swollman 3361901Swollman if (auth->ah_verf.oa_base != NULL) 3371901Swollman mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 3381901Swollman 33974462Salfred mem_free(auth, sizeof(*auth)); 3401901Swollman} 3411901Swollman 3421901Swollman/* 3431901Swollman * Marshals (pre-serializes) an auth struct. 3441901Swollman * sets private data, au_marshed and au_mpos 3451901Swollman */ 34611666Sphkstatic void 3471901Swollmanmarshal_new_auth(auth) 34874462Salfred AUTH *auth; 3491901Swollman{ 35074462Salfred XDR xdr_stream; 35174462Salfred XDR *xdrs = &xdr_stream; 35274462Salfred struct audata *au; 3531901Swollman 35474462Salfred assert(auth != NULL); 35574462Salfred 35674462Salfred au = AUTH_PRIVATE(auth); 3571901Swollman xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 3581901Swollman if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 35974462Salfred (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 36074462Salfred warnx("auth_none.c - Fatal marshalling problem"); 36174462Salfred else 3621901Swollman au->au_mpos = XDR_GETPOS(xdrs); 3631901Swollman XDR_DESTROY(xdrs); 3641901Swollman} 36574462Salfred 36674462Salfredstatic struct auth_ops * 36774462Salfredauthunix_ops() 36874462Salfred{ 36974462Salfred static struct auth_ops ops; 37074462Salfred 37174462Salfred /* VARIABLES PROTECTED BY ops_lock: ops */ 37274462Salfred 37374462Salfred mutex_lock(&ops_lock); 37474462Salfred if (ops.ah_nextverf == NULL) { 37574462Salfred ops.ah_nextverf = authunix_nextverf; 37674462Salfred ops.ah_marshal = authunix_marshal; 37774462Salfred ops.ah_validate = authunix_validate; 37874462Salfred ops.ah_refresh = authunix_refresh; 37974462Salfred ops.ah_destroy = authunix_destroy; 38074462Salfred } 38174462Salfred mutex_unlock(&ops_lock); 38274462Salfred return (&ops); 38374462Salfred} 384