Path: blob/main/crypto/krb5/src/lib/rpc/auth_unix.c
39536 views
/* @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC */1/*2* Copyright (c) 2010, Oracle America, Inc.3*4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions are met:8*9* * Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* * Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in14* the documentation and/or other materials provided with the15* distribution.16*17* * Neither the name of the "Oracle America, Inc." nor the names of18* its contributors may be used to endorse or promote products19* derived from this software without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS22* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED23* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A24* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT25* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,26* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED27* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR28* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF29* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING30* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS31* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.32*/33#if !defined(lint) && defined(SCCSIDS)34static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";35#endif3637/*38* auth_unix.c, Implements UNIX style authentication parameters.39*40* The system is very weak. The client uses no encryption for its41* credentials and only sends null verifiers. The server sends backs42* null verifiers or optionally a verifier that suggests a new short hand43* for the credentials.44*45*/4647#include "autoconf.h"48#include <stdio.h>49#include <unistd.h>50#include <string.h>5152#include <gssrpc/types.h>53#include <gssrpc/xdr.h>54#include <gssrpc/auth.h>55#include <gssrpc/auth_unix.h>5657/*58* Unix authenticator operations vector59*/60static void authunix_nextverf(AUTH *);61static bool_t authunix_marshal(AUTH *, XDR *);62static bool_t authunix_validate(AUTH *, struct opaque_auth *);63static bool_t authunix_refresh(AUTH *, struct rpc_msg *);64static void authunix_destroy(AUTH *);65static bool_t authunix_wrap(AUTH *, XDR *, xdrproc_t, caddr_t);6667static struct auth_ops auth_unix_ops = {68authunix_nextverf,69authunix_marshal,70authunix_validate,71authunix_refresh,72authunix_destroy,73authunix_wrap,74authunix_wrap75};7677/*78* This struct is pointed to by the ah_private field of an auth_handle.79*/80struct audata {81struct opaque_auth au_origcred; /* original credentials */82struct opaque_auth au_shcred; /* short hand cred */83uint32_t au_shfaults; /* short hand cache faults */84char au_marshed[MAX_AUTH_BYTES];85u_int au_mpos; /* xdr pos at end of marshed */86};87#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)8889static void marshal_new_auth(AUTH *);909192/*93* Create a unix style authenticator.94* Returns an auth handle with the given stuff in it.95*/96AUTH *97authunix_create(98char *machname,99int uid,100int gid,101int len,102int *aup_gids)103{104struct authunix_parms aup;105char mymem[MAX_AUTH_BYTES];106struct timeval now;107XDR xdrs;108AUTH *auth;109struct audata *au;110111/*112* Allocate and set up auth handle113*/114auth = (AUTH *)mem_alloc(sizeof(*auth));115#ifndef KERNEL116if (auth == NULL) {117(void)fprintf(stderr, "authunix_create: out of memory\n");118return (NULL);119}120#endif121au = (struct audata *)mem_alloc(sizeof(*au));122#ifndef KERNEL123if (au == NULL) {124(void)fprintf(stderr, "authunix_create: out of memory\n");125return (NULL);126}127#endif128auth->ah_ops = &auth_unix_ops;129auth->ah_private = (caddr_t)au;130auth->ah_verf = au->au_shcred = gssrpc__null_auth;131au->au_shfaults = 0;132133/*134* fill in param struct from the given params135*/136(void)gettimeofday(&now, (struct timezone *)0);137aup.aup_time = now.tv_sec;138aup.aup_machname = machname;139aup.aup_uid = uid;140aup.aup_gid = gid;141aup.aup_len = (u_int)len;142aup.aup_gids = aup_gids;143144/*145* Serialize the parameters into origcred146*/147xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);148if (! xdr_authunix_parms(&xdrs, &aup))149abort();150au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);151au->au_origcred.oa_flavor = AUTH_UNIX;152#ifdef KERNEL153au->au_origcred.oa_base = mem_alloc((u_int) len);154#else155if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {156(void)fprintf(stderr, "authunix_create: out of memory\n");157return (NULL);158}159#endif160memmove(au->au_origcred.oa_base, mymem, (u_int)len);161162/*163* set auth handle to reflect new cred.164*/165auth->ah_cred = au->au_origcred;166marshal_new_auth(auth);167return (auth);168}169170/*171* Returns an auth handle with parameters determined by doing lots of172* syscalls.173*/174AUTH *175authunix_create_default(void)176{177int len;178char machname[MAX_MACHINE_NAME + 1];179int uid;180int gid;181GETGROUPS_T gids[NGRPS];182int igids[NGRPS], i;183184if (gethostname(machname, MAX_MACHINE_NAME) == -1)185abort();186machname[MAX_MACHINE_NAME] = 0;187uid = geteuid();188gid = getegid();189if ((len = getgroups(NGRPS, gids)) < 0)190abort();191for(i = 0; i < NGRPS; i++) {192igids[i] = gids[i];193}194return (authunix_create(machname, uid, gid, len, igids));195}196197/*198* authunix operations199*/200201static void202authunix_nextverf(AUTH *auth)203{204/* no action necessary */205}206207static bool_t208authunix_marshal(AUTH *auth, XDR *xdrs)209{210struct audata *au = AUTH_PRIVATE(auth);211212return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));213}214215static bool_t216authunix_validate(AUTH *auth, struct opaque_auth *verf)217{218struct audata *au;219XDR xdrs;220221if (verf->oa_flavor == AUTH_SHORT) {222au = AUTH_PRIVATE(auth);223xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, XDR_DECODE);224225if (au->au_shcred.oa_base != NULL) {226mem_free(au->au_shcred.oa_base,227au->au_shcred.oa_length);228au->au_shcred.oa_base = NULL;229}230if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {231auth->ah_cred = au->au_shcred;232} else {233xdrs.x_op = XDR_FREE;234(void)xdr_opaque_auth(&xdrs, &au->au_shcred);235au->au_shcred.oa_base = NULL;236auth->ah_cred = au->au_origcred;237}238marshal_new_auth(auth);239}240return (TRUE);241}242243static bool_t244authunix_refresh(AUTH *auth, struct rpc_msg *msg)245{246struct audata *au = AUTH_PRIVATE(auth);247struct authunix_parms aup;248struct timeval now;249XDR xdrs;250int stat;251252if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {253/* there is no hope. Punt */254return (FALSE);255}256au->au_shfaults ++;257258/* first deserialize the creds back into a struct authunix_parms */259aup.aup_machname = NULL;260aup.aup_gids = (int *)NULL;261xdrmem_create(&xdrs, au->au_origcred.oa_base,262au->au_origcred.oa_length, XDR_DECODE);263stat = xdr_authunix_parms(&xdrs, &aup);264if (! stat)265goto done;266267/* update the time and serialize in place */268(void)gettimeofday(&now, (struct timezone *)0);269aup.aup_time = now.tv_sec;270xdrs.x_op = XDR_ENCODE;271XDR_SETPOS(&xdrs, 0);272stat = xdr_authunix_parms(&xdrs, &aup);273if (! stat)274goto done;275auth->ah_cred = au->au_origcred;276marshal_new_auth(auth);277done:278/* free the struct authunix_parms created by deserializing */279xdrs.x_op = XDR_FREE;280(void)xdr_authunix_parms(&xdrs, &aup);281XDR_DESTROY(&xdrs);282return (stat);283}284285static void286authunix_destroy(AUTH *auth)287{288struct audata *au = AUTH_PRIVATE(auth);289290mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);291292if (au->au_shcred.oa_base != NULL)293mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);294295mem_free(auth->ah_private, sizeof(struct audata));296297if (auth->ah_verf.oa_base != NULL)298mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);299300mem_free((caddr_t)auth, sizeof(*auth));301}302303/*304* Marshals (pre-serializes) an auth struct.305* sets private data, au_marshed and au_mpos306*/307static void308marshal_new_auth(AUTH *auth)309{310XDR xdr_stream;311XDR *xdrs = &xdr_stream;312struct audata *au = AUTH_PRIVATE(auth);313314xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);315if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||316(! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {317perror("auth_none.c - Fatal marshalling problem");318} else {319au->au_mpos = XDR_GETPOS(xdrs);320}321XDR_DESTROY(xdrs);322}323324static bool_t325authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere)326{327return ((*xfunc)(xdrs, xwhere));328}329330331