auth_unix.c revision 194494
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: head/lib/libc/rpc/auth_unix.c 194494 2009-06-19 15:58:24Z brooks $"); 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; 971901Swollman int uid; 981901Swollman int gid; 9974462Salfred int len; 1001901Swollman 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{ 188194494Sbrooks int ngids; 189194494Sbrooks long ngids_max; 19074462Salfred char machname[MAXHOSTNAMELEN + 1]; 19174462Salfred uid_t uid; 19274462Salfred gid_t gid; 193194494Sbrooks gid_t *gids; 1941901Swollman 195194494Sbrooks ngids_max = sysconf(_SC_NGROUPS_MAX) + 1; 196194494Sbrooks gids = malloc(sizeof(gid_t) * ngids_max); 197194494Sbrooks if (gids == NULL) 198194494Sbrooks return (NULL); 199194494Sbrooks 20074462Salfred if (gethostname(machname, sizeof machname) == -1) 2011901Swollman abort(); 20274462Salfred machname[sizeof(machname) - 1] = 0; 20374462Salfred uid = geteuid(); 20474462Salfred gid = getegid(); 205194494Sbrooks if ((ngids = getgroups(ngids_max, gids)) < 0) 2061901Swollman abort(); 207194494Sbrooks if (ngids > NGRPS) 208194494Sbrooks ngids = NGRPS; 20974462Salfred /* XXX: interface problem; those should all have been unsigned */ 210194494Sbrooks return (authunix_create(machname, (int)uid, (int)gid, ngids, 21174462Salfred (int *)gids)); 2121901Swollman} 2131901Swollman 2141901Swollman/* 2151901Swollman * authunix operations 2161901Swollman */ 2171901Swollman 21874462Salfred/* ARGSUSED */ 2191901Swollmanstatic void 2201901Swollmanauthunix_nextverf(auth) 2211901Swollman AUTH *auth; 2221901Swollman{ 2231901Swollman /* no action necessary */ 2241901Swollman} 2251901Swollman 2261901Swollmanstatic bool_t 2271901Swollmanauthunix_marshal(auth, xdrs) 2281901Swollman AUTH *auth; 2291901Swollman XDR *xdrs; 2301901Swollman{ 23174462Salfred struct audata *au; 2321901Swollman 23374462Salfred assert(auth != NULL); 23474462Salfred assert(xdrs != NULL); 23574462Salfred 23674462Salfred au = AUTH_PRIVATE(auth); 2371901Swollman return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); 2381901Swollman} 2391901Swollman 2401901Swollmanstatic bool_t 2411901Swollmanauthunix_validate(auth, verf) 24274462Salfred AUTH *auth; 24374462Salfred struct opaque_auth *verf; 2441901Swollman{ 24574462Salfred struct audata *au; 2461901Swollman XDR xdrs; 2471901Swollman 24874462Salfred assert(auth != NULL); 24974462Salfred assert(verf != NULL); 25074462Salfred 25174462Salfred if (verf->oa_flavor == AUTH_SHORT) { 2521901Swollman au = AUTH_PRIVATE(auth); 25374462Salfred xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, 25474462Salfred XDR_DECODE); 2551901Swollman 2561901Swollman if (au->au_shcred.oa_base != NULL) { 2571901Swollman mem_free(au->au_shcred.oa_base, 2581901Swollman au->au_shcred.oa_length); 2591901Swollman au->au_shcred.oa_base = NULL; 2601901Swollman } 2611901Swollman if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { 2621901Swollman auth->ah_cred = au->au_shcred; 2631901Swollman } else { 2641901Swollman xdrs.x_op = XDR_FREE; 2651901Swollman (void)xdr_opaque_auth(&xdrs, &au->au_shcred); 2661901Swollman au->au_shcred.oa_base = NULL; 2671901Swollman auth->ah_cred = au->au_origcred; 2681901Swollman } 2691901Swollman marshal_new_auth(auth); 2701901Swollman } 2711901Swollman return (TRUE); 2721901Swollman} 2731901Swollman 2741901Swollmanstatic bool_t 27574462Salfredauthunix_refresh(AUTH *auth, void *dummy) 2761901Swollman{ 27774462Salfred struct audata *au = AUTH_PRIVATE(auth); 2781901Swollman struct authunix_parms aup; 2791901Swollman struct timeval now; 2801901Swollman XDR xdrs; 28174462Salfred int stat; 2821901Swollman 28374462Salfred assert(auth != NULL); 28474462Salfred 2851901Swollman if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { 2861901Swollman /* there is no hope. Punt */ 2871901Swollman return (FALSE); 2881901Swollman } 2891901Swollman au->au_shfaults ++; 2901901Swollman 2911901Swollman /* first deserialize the creds back into a struct authunix_parms */ 2921901Swollman aup.aup_machname = NULL; 29374462Salfred aup.aup_gids = NULL; 2941901Swollman xdrmem_create(&xdrs, au->au_origcred.oa_base, 2951901Swollman au->au_origcred.oa_length, XDR_DECODE); 2961901Swollman stat = xdr_authunix_parms(&xdrs, &aup); 2978870Srgrimes if (! stat) 2981901Swollman goto done; 2991901Swollman 3001901Swollman /* update the time and serialize in place */ 30174462Salfred (void)gettimeofday(&now, NULL); 3021901Swollman aup.aup_time = now.tv_sec; 3031901Swollman xdrs.x_op = XDR_ENCODE; 3041901Swollman XDR_SETPOS(&xdrs, 0); 3051901Swollman stat = xdr_authunix_parms(&xdrs, &aup); 3061901Swollman if (! stat) 3071901Swollman goto done; 3081901Swollman auth->ah_cred = au->au_origcred; 3091901Swollman marshal_new_auth(auth); 3101901Swollmandone: 3111901Swollman /* free the struct authunix_parms created by deserializing */ 3121901Swollman xdrs.x_op = XDR_FREE; 3131901Swollman (void)xdr_authunix_parms(&xdrs, &aup); 3141901Swollman XDR_DESTROY(&xdrs); 3151901Swollman return (stat); 3161901Swollman} 3171901Swollman 3181901Swollmanstatic void 3191901Swollmanauthunix_destroy(auth) 32074462Salfred AUTH *auth; 3211901Swollman{ 32274462Salfred struct audata *au; 3231901Swollman 32474462Salfred assert(auth != NULL); 32574462Salfred 32674462Salfred au = AUTH_PRIVATE(auth); 3271901Swollman mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); 3281901Swollman 3291901Swollman if (au->au_shcred.oa_base != NULL) 3301901Swollman mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); 3311901Swollman 3321901Swollman mem_free(auth->ah_private, sizeof(struct audata)); 3331901Swollman 3341901Swollman if (auth->ah_verf.oa_base != NULL) 3351901Swollman mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); 3361901Swollman 33774462Salfred mem_free(auth, sizeof(*auth)); 3381901Swollman} 3391901Swollman 3401901Swollman/* 3411901Swollman * Marshals (pre-serializes) an auth struct. 3421901Swollman * sets private data, au_marshed and au_mpos 3431901Swollman */ 34411666Sphkstatic void 3451901Swollmanmarshal_new_auth(auth) 34674462Salfred AUTH *auth; 3471901Swollman{ 34874462Salfred XDR xdr_stream; 34974462Salfred XDR *xdrs = &xdr_stream; 35074462Salfred struct audata *au; 3511901Swollman 35274462Salfred assert(auth != NULL); 35374462Salfred 35474462Salfred au = AUTH_PRIVATE(auth); 3551901Swollman xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); 3561901Swollman if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || 35774462Salfred (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) 35874462Salfred warnx("auth_none.c - Fatal marshalling problem"); 35974462Salfred else 3601901Swollman au->au_mpos = XDR_GETPOS(xdrs); 3611901Swollman XDR_DESTROY(xdrs); 3621901Swollman} 36374462Salfred 36474462Salfredstatic struct auth_ops * 36574462Salfredauthunix_ops() 36674462Salfred{ 36774462Salfred static struct auth_ops ops; 36874462Salfred 36974462Salfred /* VARIABLES PROTECTED BY ops_lock: ops */ 37074462Salfred 37174462Salfred mutex_lock(&ops_lock); 37274462Salfred if (ops.ah_nextverf == NULL) { 37374462Salfred ops.ah_nextverf = authunix_nextverf; 37474462Salfred ops.ah_marshal = authunix_marshal; 37574462Salfred ops.ah_validate = authunix_validate; 37674462Salfred ops.ah_refresh = authunix_refresh; 37774462Salfred ops.ah_destroy = authunix_destroy; 37874462Salfred } 37974462Salfred mutex_unlock(&ops_lock); 38074462Salfred return (&ops); 38174462Salfred} 382