license changed to LGPL: added COPYING file, changed source file comments

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2012-03-19 12:24:43 -04:00
parent 6f8f4d8e3f
commit bbb1ed696c
88 changed files with 4784 additions and 5040 deletions

View file

@ -1,218 +1,213 @@
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
#if defined(LIBC_SCCS) && !defined(lint)
static char *sccsid = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";
#endif
//#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/rpc/auth_none.c,v 1.12 2002/03/22 23:18:35 obrien Exp $");
*/
/*
* auth_none.c
* Creates a client authentication handle for passing "null"
* credentials and verifiers to remote systems.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
#if defined(LIBC_SCCS) && !defined(lint)
static char *sccsid = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
static char *sccsid = "@(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";
#endif
//#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/rpc/auth_none.c,v 1.12 2002/03/22 23:18:35 obrien Exp $");
*/
/*
* auth_none.c
* Creates a client authentication handle for passing "null"
* credentials and verifiers to remote systems.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
* Kevin Coffman <kwc@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
#include <assert.h>
#include <stdlib.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#define MAX_MARSHAL_SIZE 20
/*
* Authenticator operations routines
*/
static bool_t authnone_marshal (AUTH *, XDR *, u_int *);
static void authnone_verf (AUTH *);
static bool_t authnone_validate (AUTH *, struct opaque_auth *, u_int);
static bool_t authnone_refresh (AUTH *, void *);
static void authnone_destroy (AUTH *);
extern bool_t xdr_opaque_auth();
static struct auth_ops *authnone_ops();
static struct authnone_private {
AUTH no_client;
char marshalled_client[MAX_MARSHAL_SIZE];
u_int mcnt;
} *authnone_private;
AUTH *
authnone_create()
{
struct authnone_private *ap = authnone_private;
XDR xdr_stream;
XDR *xdrs;
extern mutex_t authnone_lock;
mutex_lock(&authnone_lock);
if (ap == 0) {
ap = (struct authnone_private *)calloc(1, sizeof (*ap));
if (ap == 0) {
mutex_unlock(&authnone_lock);
return (0);
}
authnone_private = ap;
}
if (!ap->mcnt) {
ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
ap->no_client.ah_ops = authnone_ops();
xdrs = &xdr_stream;
xdrmem_create(xdrs, ap->marshalled_client,
(u_int)MAX_MARSHAL_SIZE, XDR_ENCODE);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
ap->mcnt = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
}
mutex_unlock(&authnone_lock);
return (&ap->no_client);
}
/*ARGSUSED*/
static bool_t
authnone_marshal(AUTH *client, XDR *xdrs, u_int *seq)
{
struct authnone_private *ap;
bool_t dummy;
extern mutex_t authnone_lock;
assert(xdrs != NULL);
ap = authnone_private;
if (ap == NULL) {
mutex_unlock(&authnone_lock);
return (FALSE);
}
dummy = (*xdrs->x_ops->x_putbytes)(xdrs,
ap->marshalled_client, ap->mcnt);
mutex_unlock(&authnone_lock);
return (dummy);
}
/* All these unused parameters are required to keep ANSI-C from grumbling */
/*ARGSUSED*/
static void
authnone_verf(AUTH *client)
{
}
/*ARGSUSED*/
static bool_t
authnone_validate(AUTH *client, struct opaque_auth *opaque, u_int seq)
{
return (TRUE);
}
/*ARGSUSED*/
static bool_t
authnone_refresh(AUTH *client, void *dummy)
{
return (FALSE);
}
/*ARGSUSED*/
static void
authnone_destroy(AUTH *client)
{
}
static int
authnone_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args)
{
return ((*func)(xdrs, args));
}
static int
authnone_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq)
{
return ((*func)(xdrs, args));
}
static struct auth_ops *
authnone_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authnone_verf;
ops.ah_marshal = authnone_marshal;
ops.ah_validate = authnone_validate;
ops.ah_refresh = authnone_refresh;
ops.ah_destroy = authnone_destroy;
ops.ah_wrap = authnone_wrap;
ops.ah_unwrap = authnone_unwrap;
}
mutex_unlock(&ops_lock);
return (&ops);
}
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
#include <assert.h>
#include <stdlib.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#define MAX_MARSHAL_SIZE 20
/*
* Authenticator operations routines
*/
static bool_t authnone_marshal (AUTH *, XDR *, u_int *);
static void authnone_verf (AUTH *);
static bool_t authnone_validate (AUTH *, struct opaque_auth *, u_int);
static bool_t authnone_refresh (AUTH *, void *);
static void authnone_destroy (AUTH *);
extern bool_t xdr_opaque_auth();
static struct auth_ops *authnone_ops();
static struct authnone_private {
AUTH no_client;
char marshalled_client[MAX_MARSHAL_SIZE];
u_int mcnt;
} *authnone_private;
AUTH *
authnone_create()
{
struct authnone_private *ap = authnone_private;
XDR xdr_stream;
XDR *xdrs;
extern mutex_t authnone_lock;
mutex_lock(&authnone_lock);
if (ap == 0) {
ap = (struct authnone_private *)calloc(1, sizeof (*ap));
if (ap == 0) {
mutex_unlock(&authnone_lock);
return (0);
}
authnone_private = ap;
}
if (!ap->mcnt) {
ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
ap->no_client.ah_ops = authnone_ops();
xdrs = &xdr_stream;
xdrmem_create(xdrs, ap->marshalled_client,
(u_int)MAX_MARSHAL_SIZE, XDR_ENCODE);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
ap->mcnt = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
}
mutex_unlock(&authnone_lock);
return (&ap->no_client);
}
/*ARGSUSED*/
static bool_t
authnone_marshal(AUTH *client, XDR *xdrs, u_int *seq)
{
struct authnone_private *ap;
bool_t dummy;
extern mutex_t authnone_lock;
assert(xdrs != NULL);
ap = authnone_private;
if (ap == NULL) {
mutex_unlock(&authnone_lock);
return (FALSE);
}
dummy = (*xdrs->x_ops->x_putbytes)(xdrs,
ap->marshalled_client, ap->mcnt);
mutex_unlock(&authnone_lock);
return (dummy);
}
/* All these unused parameters are required to keep ANSI-C from grumbling */
/*ARGSUSED*/
static void
authnone_verf(AUTH *client)
{
}
/*ARGSUSED*/
static bool_t
authnone_validate(AUTH *client, struct opaque_auth *opaque, u_int seq)
{
return (TRUE);
}
/*ARGSUSED*/
static bool_t
authnone_refresh(AUTH *client, void *dummy)
{
return (FALSE);
}
/*ARGSUSED*/
static void
authnone_destroy(AUTH *client)
{
}
static int
authnone_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args)
{
return ((*func)(xdrs, args));
}
static int
authnone_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq)
{
return ((*func)(xdrs, args));
}
static struct auth_ops *
authnone_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authnone_verf;
ops.ah_marshal = authnone_marshal;
ops.ah_validate = authnone_validate;
ops.ah_refresh = authnone_refresh;
ops.ah_destroy = authnone_destroy;
ops.ah_wrap = authnone_wrap;
ops.ah_unwrap = authnone_unwrap;
}
mutex_unlock(&ops_lock);
return (&ops);
}

View file

@ -1,27 +1,22 @@
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
*
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>

View file

@ -1,409 +1,404 @@
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//#include <sys/cdefs.h>
/*
* auth_unix.c, Implements UNIX style authentication parameters.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* The system is very weak. The client uses no encryption for it's
* credentials and only sends null verifiers. The server sends backs
* null verifiers or optionally a verifier that suggests a new short hand
* for the credentials.
*
*/
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//#include <sys/cdefs.h>
/*
* auth_unix.c, Implements UNIX style authentication parameters.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* The system is very weak. The client uses no encryption for it's
* credentials and only sends null verifiers. The server sends backs
* null verifiers or optionally a verifier that suggests a new short hand
* for the credentials.
*
*/
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
* Kevin Coffman <kwc@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
//#include <sys/param.h>
#include <assert.h>
//#include <err.h>
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <string.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_unix.h>
/* auth_unix.c */
static void authunix_nextverf (AUTH *);
static bool_t authunix_marshal (AUTH *, XDR *, u_int *seq);
static bool_t authunix_validate (AUTH *, struct opaque_auth *, u_int);
static bool_t authunix_refresh (AUTH *, void *);
static void authunix_destroy (AUTH *);
static void marshal_new_auth (AUTH *);
static struct auth_ops *authunix_ops (void);
/*
* This struct is pointed to by the ah_private field of an auth_handle.
*/
struct audata {
struct opaque_auth au_origcred; /* original credentials */
struct opaque_auth au_shcred; /* short hand cred */
u_long au_shfaults; /* short hand cache faults */
char au_marshed[MAX_AUTH_BYTES];
u_int au_mpos; /* xdr pos at end of marshed */
};
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
/*
* Create a unix style authenticator.
* Returns an auth handle with the given stuff in it.
*/
AUTH *
authunix_create(machname, uid, gid, len, aup_gids)
char *machname;
uid_t uid;
gid_t gid;
int len;
gid_t *aup_gids;
{
struct authunix_parms aup;
char mymem[MAX_AUTH_BYTES];
struct timeval now;
XDR xdrs;
AUTH *auth;
struct audata *au;
/*
* Allocate and set up auth handle
*/
au = NULL;
auth = mem_alloc(sizeof(*auth));
#ifndef _KERNEL
if (auth == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
au = mem_alloc(sizeof(*au));
#ifndef _KERNEL
if (au == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
auth->ah_ops = authunix_ops();
auth->ah_private = (caddr_t)au;
auth->ah_verf = au->au_shcred = _null_auth;
au->au_shfaults = 0;
au->au_origcred.oa_base = NULL;
/*
* fill in param struct from the given params
*/
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
aup.aup_machname = machname;
aup.aup_uid = uid;
aup.aup_gid = gid;
aup.aup_len = (u_int)len;
aup.aup_gids = aup_gids;
/*
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
if (! xdr_authunix_parms(&xdrs, &aup))
abort();
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
#ifdef _KERNEL
au->au_origcred.oa_base = mem_alloc((u_int) len);
#else
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
memmove(au->au_origcred.oa_base, mymem, (size_t)len);
/*
* set auth handle to reflect new cred.
*/
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
return (auth);
#ifndef _KERNEL
cleanup_authunix_create:
if (auth)
mem_free(auth, sizeof(*auth));
if (au) {
if (au->au_origcred.oa_base)
mem_free(au->au_origcred.oa_base, (u_int)len);
mem_free(au, sizeof(*au));
}
return (NULL);
#endif
}
/*
* Returns an auth handle with parameters determined by doing lots of
* syscalls.
*/
AUTH *
authunix_create_default()
{
int len;
char machname[MAXHOSTNAMELEN + 1];
uid_t uid;
gid_t gid;
gid_t gids[NGRPS];
if (gethostname(machname, sizeof machname) == -1)
abort();
machname[sizeof(machname) - 1] = 0;
#if 0
uid = geteuid();
gid = getegid();
if ((len = getgroups(NGRPS, gids)) < 0)
abort();
#else
// XXX Need to figure out what to do here!
uid = 666;
gid = 777;
gids[0] = 0;
len = 0;
#endif
/* XXX: interface problem; those should all have been unsigned */
return (authunix_create(machname, uid, gid, len, gids));
}
/*
* authunix operations
*/
/* ARGSUSED */
static void
authunix_nextverf(auth)
AUTH *auth;
{
/* no action necessary */
}
static bool_t
authunix_marshal(auth, xdrs, seq)
AUTH *auth;
XDR *xdrs;
u_int *seq;
{
struct audata *au;
assert(auth != NULL);
assert(xdrs != NULL);
au = AUTH_PRIVATE(auth);
return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
}
static bool_t
authunix_validate(auth, verf, seq)
AUTH *auth;
struct opaque_auth *verf;
u_int seq;
{
struct audata *au;
XDR xdrs;
assert(auth != NULL);
assert(verf != NULL);
if (verf->oa_flavor == AUTH_SHORT) {
au = AUTH_PRIVATE(auth);
xdrmem_create(&xdrs, verf->oa_base, verf->oa_length,
XDR_DECODE);
if (au->au_shcred.oa_base != NULL) {
mem_free(au->au_shcred.oa_base,
au->au_shcred.oa_length);
au->au_shcred.oa_base = NULL;
}
if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
auth->ah_cred = au->au_shcred;
} else {
xdrs.x_op = XDR_FREE;
(void)xdr_opaque_auth(&xdrs, &au->au_shcred);
au->au_shcred.oa_base = NULL;
auth->ah_cred = au->au_origcred;
}
marshal_new_auth(auth);
}
return (TRUE);
}
static bool_t
authunix_refresh(AUTH *auth, void *dummy)
{
struct audata *au = AUTH_PRIVATE(auth);
struct authunix_parms aup;
struct timeval now;
XDR xdrs;
int stat;
assert(auth != NULL);
if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
/* there is no hope. Punt */
return (FALSE);
}
au->au_shfaults ++;
/* first deserialize the creds back into a struct authunix_parms */
aup.aup_machname = NULL;
aup.aup_gids = NULL;
xdrmem_create(&xdrs, au->au_origcred.oa_base,
au->au_origcred.oa_length, XDR_DECODE);
stat = xdr_authunix_parms(&xdrs, &aup);
if (! stat)
goto done;
/* update the time and serialize in place */
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
xdrs.x_op = XDR_ENCODE;
XDR_SETPOS(&xdrs, 0);
stat = xdr_authunix_parms(&xdrs, &aup);
if (! stat)
goto done;
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
done:
/* free the struct authunix_parms created by deserializing */
xdrs.x_op = XDR_FREE;
(void)xdr_authunix_parms(&xdrs, &aup);
XDR_DESTROY(&xdrs);
return (stat);
}
static void
authunix_destroy(auth)
AUTH *auth;
{
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
if (au->au_shcred.oa_base != NULL)
mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
mem_free(auth->ah_private, sizeof(struct audata));
if (auth->ah_verf.oa_base != NULL)
mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
mem_free(auth, sizeof(*auth));
}
/*
* Marshals (pre-serializes) an auth struct.
* sets private data, au_marshed and au_mpos
*/
static void
marshal_new_auth(auth)
AUTH *auth;
{
XDR xdr_stream;
XDR *xdrs = &xdr_stream;
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
(! xdr_opaque_auth(xdrs, &(auth->ah_verf))))
assert(0); // XXX
// XXX warnx("auth_none.c - Fatal marshalling problem");
else
au->au_mpos = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
}
static bool_t
authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq)
{
return ((*func)(xdrs, args));
}
static struct auth_ops *
authunix_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authunix_nextverf;
ops.ah_marshal = authunix_marshal;
ops.ah_validate = authunix_validate;
ops.ah_refresh = authunix_refresh;
ops.ah_destroy = authunix_destroy;
ops.ah_wrap = authunix_wrap;
ops.ah_unwrap = authunix_wrap;
}
mutex_unlock(&ops_lock);
return (&ops);
}
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
//#include <sys/param.h>
#include <assert.h>
//#include <err.h>
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <string.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_unix.h>
/* auth_unix.c */
static void authunix_nextverf (AUTH *);
static bool_t authunix_marshal (AUTH *, XDR *, u_int *seq);
static bool_t authunix_validate (AUTH *, struct opaque_auth *, u_int);
static bool_t authunix_refresh (AUTH *, void *);
static void authunix_destroy (AUTH *);
static void marshal_new_auth (AUTH *);
static struct auth_ops *authunix_ops (void);
/*
* This struct is pointed to by the ah_private field of an auth_handle.
*/
struct audata {
struct opaque_auth au_origcred; /* original credentials */
struct opaque_auth au_shcred; /* short hand cred */
u_long au_shfaults; /* short hand cache faults */
char au_marshed[MAX_AUTH_BYTES];
u_int au_mpos; /* xdr pos at end of marshed */
};
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
/*
* Create a unix style authenticator.
* Returns an auth handle with the given stuff in it.
*/
AUTH *
authunix_create(machname, uid, gid, len, aup_gids)
char *machname;
uid_t uid;
gid_t gid;
int len;
gid_t *aup_gids;
{
struct authunix_parms aup;
char mymem[MAX_AUTH_BYTES];
struct timeval now;
XDR xdrs;
AUTH *auth;
struct audata *au;
/*
* Allocate and set up auth handle
*/
au = NULL;
auth = mem_alloc(sizeof(*auth));
#ifndef _KERNEL
if (auth == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
au = mem_alloc(sizeof(*au));
#ifndef _KERNEL
if (au == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
auth->ah_ops = authunix_ops();
auth->ah_private = (caddr_t)au;
auth->ah_verf = au->au_shcred = _null_auth;
au->au_shfaults = 0;
au->au_origcred.oa_base = NULL;
/*
* fill in param struct from the given params
*/
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
aup.aup_machname = machname;
aup.aup_uid = uid;
aup.aup_gid = gid;
aup.aup_len = (u_int)len;
aup.aup_gids = aup_gids;
/*
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
if (! xdr_authunix_parms(&xdrs, &aup))
abort();
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
#ifdef _KERNEL
au->au_origcred.oa_base = mem_alloc((u_int) len);
#else
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
// XXX warnx("authunix_create: out of memory");
goto cleanup_authunix_create;
}
#endif
memmove(au->au_origcred.oa_base, mymem, (size_t)len);
/*
* set auth handle to reflect new cred.
*/
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
return (auth);
#ifndef _KERNEL
cleanup_authunix_create:
if (auth)
mem_free(auth, sizeof(*auth));
if (au) {
if (au->au_origcred.oa_base)
mem_free(au->au_origcred.oa_base, (u_int)len);
mem_free(au, sizeof(*au));
}
return (NULL);
#endif
}
/*
* Returns an auth handle with parameters determined by doing lots of
* syscalls.
*/
AUTH *
authunix_create_default()
{
int len;
char machname[MAXHOSTNAMELEN + 1];
uid_t uid;
gid_t gid;
gid_t gids[NGRPS];
if (gethostname(machname, sizeof machname) == -1)
abort();
machname[sizeof(machname) - 1] = 0;
#if 0
uid = geteuid();
gid = getegid();
if ((len = getgroups(NGRPS, gids)) < 0)
abort();
#else
// XXX Need to figure out what to do here!
uid = 666;
gid = 777;
gids[0] = 0;
len = 0;
#endif
/* XXX: interface problem; those should all have been unsigned */
return (authunix_create(machname, uid, gid, len, gids));
}
/*
* authunix operations
*/
/* ARGSUSED */
static void
authunix_nextverf(auth)
AUTH *auth;
{
/* no action necessary */
}
static bool_t
authunix_marshal(auth, xdrs, seq)
AUTH *auth;
XDR *xdrs;
u_int *seq;
{
struct audata *au;
assert(auth != NULL);
assert(xdrs != NULL);
au = AUTH_PRIVATE(auth);
return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
}
static bool_t
authunix_validate(auth, verf, seq)
AUTH *auth;
struct opaque_auth *verf;
u_int seq;
{
struct audata *au;
XDR xdrs;
assert(auth != NULL);
assert(verf != NULL);
if (verf->oa_flavor == AUTH_SHORT) {
au = AUTH_PRIVATE(auth);
xdrmem_create(&xdrs, verf->oa_base, verf->oa_length,
XDR_DECODE);
if (au->au_shcred.oa_base != NULL) {
mem_free(au->au_shcred.oa_base,
au->au_shcred.oa_length);
au->au_shcred.oa_base = NULL;
}
if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
auth->ah_cred = au->au_shcred;
} else {
xdrs.x_op = XDR_FREE;
(void)xdr_opaque_auth(&xdrs, &au->au_shcred);
au->au_shcred.oa_base = NULL;
auth->ah_cred = au->au_origcred;
}
marshal_new_auth(auth);
}
return (TRUE);
}
static bool_t
authunix_refresh(AUTH *auth, void *dummy)
{
struct audata *au = AUTH_PRIVATE(auth);
struct authunix_parms aup;
struct timeval now;
XDR xdrs;
int stat;
assert(auth != NULL);
if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
/* there is no hope. Punt */
return (FALSE);
}
au->au_shfaults ++;
/* first deserialize the creds back into a struct authunix_parms */
aup.aup_machname = NULL;
aup.aup_gids = NULL;
xdrmem_create(&xdrs, au->au_origcred.oa_base,
au->au_origcred.oa_length, XDR_DECODE);
stat = xdr_authunix_parms(&xdrs, &aup);
if (! stat)
goto done;
/* update the time and serialize in place */
(void)gettimeofday(&now, NULL);
aup.aup_time = now.tv_sec;
xdrs.x_op = XDR_ENCODE;
XDR_SETPOS(&xdrs, 0);
stat = xdr_authunix_parms(&xdrs, &aup);
if (! stat)
goto done;
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
done:
/* free the struct authunix_parms created by deserializing */
xdrs.x_op = XDR_FREE;
(void)xdr_authunix_parms(&xdrs, &aup);
XDR_DESTROY(&xdrs);
return (stat);
}
static void
authunix_destroy(auth)
AUTH *auth;
{
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
if (au->au_shcred.oa_base != NULL)
mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
mem_free(auth->ah_private, sizeof(struct audata));
if (auth->ah_verf.oa_base != NULL)
mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
mem_free(auth, sizeof(*auth));
}
/*
* Marshals (pre-serializes) an auth struct.
* sets private data, au_marshed and au_mpos
*/
static void
marshal_new_auth(auth)
AUTH *auth;
{
XDR xdr_stream;
XDR *xdrs = &xdr_stream;
struct audata *au;
assert(auth != NULL);
au = AUTH_PRIVATE(auth);
xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
(! xdr_opaque_auth(xdrs, &(auth->ah_verf))))
assert(0); // XXX
// XXX warnx("auth_none.c - Fatal marshalling problem");
else
au->au_mpos = XDR_GETPOS(xdrs);
XDR_DESTROY(xdrs);
}
static bool_t
authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t func, caddr_t args, u_int seq)
{
return ((*func)(xdrs, args));
}
static struct auth_ops *
authunix_ops()
{
static struct auth_ops ops;
extern mutex_t ops_lock;
/* VARIABLES PROTECTED BY ops_lock: ops */
mutex_lock(&ops_lock);
if (ops.ah_nextverf == NULL) {
ops.ah_nextverf = authunix_nextverf;
ops.ah_marshal = authunix_marshal;
ops.ah_validate = authunix_validate;
ops.ah_refresh = authunix_refresh;
ops.ah_destroy = authunix_destroy;
ops.ah_wrap = authunix_wrap;
ops.ah_unwrap = authunix_wrap;
}
mutex_unlock(&ops_lock);
return (&ops);
}

View file

@ -1,27 +1,22 @@
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
*
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>

View file

@ -1,480 +1,475 @@
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1986-1996,1998 by Sun Microsystems, Inc.
* All rights reserved.
*/
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1986-1996,1998 by Sun Microsystems, Inc.
* All rights reserved.
*/
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
* Kevin Coffman <kwc@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
#include <sys/types.h>
//#include <sys/fcntl.h>
#include <fcntl.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <netinet/tcp.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
//#include <netdb.h>
//#include <syslog.h>
#include <rpc/rpc.h>
#include <rpc/nettype.h>
//#include <unistd.h>
#include "rpc_com.h"
extern bool_t __rpc_is_local_host(const char *);
#if 0 /* WINDOWS */
int __rpc_raise_fd(int);
#endif
#ifndef NETIDLEN
#define NETIDLEN 32
#endif
/*
* Generic client creation with version checking the value of
* vers_out is set to the highest server supported value
* vers_low <= vers_out <= vers_high AND an error results
* if this can not be done.
*
* It calls clnt_create_vers_timed() with a NULL value for the timeout
* pointer, which indicates that the default timeout should be used.
*/
CLIENT *
clnt_create_vers(const char *hostname, const rpcprog_t prog, rpcvers_t *vers_out,
const rpcvers_t vers_low, const rpcvers_t vers_high, const char *nettype)
{
return (clnt_create_vers_timed(hostname, prog, vers_out, vers_low,
vers_high, nettype, NULL));
}
/*
* This the routine has the same definition as clnt_create_vers(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*/
CLIENT *
clnt_create_vers_timed(const char *hostname, const rpcprog_t prog,
rpcvers_t *vers_out, const rpcvers_t vers_low_in, const rpcvers_t vers_high_in,
const char *nettype, const struct timeval *tp)
{
CLIENT *clnt;
struct timeval to;
enum clnt_stat rpc_stat;
struct rpc_err rpcerr;
rpcvers_t vers_high = vers_high_in;
rpcvers_t vers_low = vers_low_in;
clnt = clnt_create_timed(hostname, prog, vers_high, nettype, tp);
if (clnt == NULL) {
return (NULL);
}
to.tv_sec = 10;
to.tv_usec = 0;
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void,
(char *)NULL, (xdrproc_t)xdr_void, (char *)NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
while (rpc_stat == RPC_PROGVERSMISMATCH && vers_high > vers_low) {
unsigned int minvers, maxvers;
clnt_geterr(clnt, &rpcerr);
minvers = rpcerr.re_vers.low;
maxvers = rpcerr.re_vers.high;
if (maxvers < vers_high)
vers_high = maxvers;
else
vers_high--;
if (minvers > vers_low)
vers_low = minvers;
if (vers_low > vers_high) {
goto error;
}
CLNT_CONTROL(clnt, CLSET_VERS, (char *)&vers_high);
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void,
(char *)NULL, (xdrproc_t)xdr_void,
(char *)NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
}
clnt_geterr(clnt, &rpcerr);
error:
rpc_createerr.cf_stat = rpc_stat;
rpc_createerr.cf_error = rpcerr;
clnt_destroy(clnt);
return (NULL);
}
/*
* Top level client creation routine.
* Generic client creation: takes (servers name, program-number, nettype) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s.
*
* It tries for all the netids in that particular class of netid until
* it succeeds.
* XXX The error message in the case of failure will be the one
* pertaining to the last create error.
*
* It calls clnt_create_timed() with the default timeout.
*/
CLIENT *
clnt_create(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const char *nettype)
{
return (clnt_create_timed(hostname, prog, vers, nettype, NULL));
}
/*
* This the routine has the same definition as clnt_create(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*
* This function calls clnt_tp_create_timed().
*/
CLIENT *
clnt_create_timed(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const char *netclass, const struct timeval *tp)
{
struct netconfig *nconf;
CLIENT *clnt = NULL;
void *handle;
enum clnt_stat save_cf_stat = RPC_SUCCESS;
struct rpc_err save_cf_error;
char nettype_array[NETIDLEN];
char *nettype = &nettype_array[0];
if (netclass == NULL)
nettype = NULL;
else {
size_t len = strlen(netclass);
if (len >= sizeof (nettype_array)) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
strcpy(nettype, netclass);
}
if ((handle = __rpc_setconf((char *)nettype)) == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
rpc_createerr.cf_stat = RPC_SUCCESS;
while (clnt == NULL) {
if ((nconf = __rpc_getconf(handle)) == NULL) {
if (rpc_createerr.cf_stat == RPC_SUCCESS)
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
break;
}
#ifdef CLNT_DEBUG
printf("trying netid %s\n", nconf->nc_netid);
#endif
clnt = clnt_tp_create_timed(hostname, prog, vers, nconf, tp);
if (clnt)
break;
else {
/*
* Since we didn't get a name-to-address
* translation failure here, we remember
* this particular error. The object of
* this is to enable us to return to the
* caller a more-specific error than the
* unhelpful ``Name to address translation
* failed'' which might well occur if we
* merely returned the last error (because
* the local loopbacks are typically the
* last ones in /etc/netconfig and the most
* likely to be unable to translate a host
* name). We also check for a more
* meaningful error than ``unknown host
* name'' for the same reasons.
*/
if (rpc_createerr.cf_stat != RPC_N2AXLATEFAILURE &&
rpc_createerr.cf_stat != RPC_UNKNOWNHOST) {
save_cf_stat = rpc_createerr.cf_stat;
save_cf_error = rpc_createerr.cf_error;
}
}
}
/*
* Attempt to return an error more specific than ``Name to address
* translation failed'' or ``unknown host name''
*/
if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE ||
rpc_createerr.cf_stat == RPC_UNKNOWNHOST) &&
(save_cf_stat != RPC_SUCCESS)) {
rpc_createerr.cf_stat = save_cf_stat;
rpc_createerr.cf_error = save_cf_error;
}
__rpc_endconf(handle);
return (clnt);
}
/*
* Generic client creation: takes (servers name, program-number, netconf) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control()
* It finds out the server address from rpcbind and calls clnt_tli_create().
*
* It calls clnt_tp_create_timed() with the default timeout.
*/
CLIENT *
clnt_tp_create(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const struct netconfig *nconf)
{
return (clnt_tp_create_timed(hostname, prog, vers, nconf, NULL));
}
/*
* This has the same definition as clnt_tp_create(), except it
* takes an additional parameter - a pointer to a timeval structure.
* A NULL value for the timeout pointer indicates that the default
* value for the timeout should be used.
*/
CLIENT *
clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const struct netconfig *nconf, const struct timeval *tp)
{
struct netbuf *svcaddr; /* servers address */
CLIENT *cl = NULL; /* client handle */
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
/*
* Get the address of the server
*/
if ((svcaddr = __rpcb_findaddr_timed(prog, vers,
(struct netconfig *)nconf, (char *)hostname,
&cl, (struct timeval *)tp)) == NULL) {
/* appropriate error number is set by rpcbind libraries */
return (NULL);
}
if (cl == NULL) {
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0, NULL, NULL, NULL);
} else {
/* Reuse the CLIENT handle and change the appropriate fields */
if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) {
if (cl->cl_netid == NULL)
cl->cl_netid = strdup(nconf->nc_netid);
if (cl->cl_tp == NULL)
cl->cl_tp = strdup(nconf->nc_device);
(void) CLNT_CONTROL(cl, CLSET_PROG, (void *)&prog);
(void) CLNT_CONTROL(cl, CLSET_VERS, (void *)&vers);
} else {
CLNT_DESTROY(cl);
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0, NULL, NULL, NULL);
}
}
free(svcaddr->buf);
free(svcaddr);
return (cl);
}
/*
* Generic client creation: returns client handle.
* Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control().
* If fd is RPC_ANYFD, it will be opened using nconf.
* It will be bound if not so.
* If sizes are 0; appropriate defaults will be chosen.
*/
CLIENT *
clnt_tli_create(const SOCKET fd_in, const struct netconfig *nconf,
struct netbuf *svcaddr, const rpcprog_t prog, const rpcvers_t vers,
const uint sendsz, const uint recvsz,
int (*callback_xdr)(void *, void *),
int (*callback_function)(void *, void *, void **),
void *callback_args)
{
CLIENT *cl; /* client handle */
bool_t madefd = FALSE; /* whether fd opened here */
long servtype;
BOOL one = TRUE;
struct __rpc_sockinfo si;
extern int __rpc_minfd;
SOCKET fd = fd_in;
if (fd == RPC_ANYFD) {
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
fd = __rpc_nconf2fd(nconf);
if (fd == INVALID_SOCKET)
goto err;
#if 0
if (fd < __rpc_minfd)
fd = __rpc_raise_fd(fd);
#endif
madefd = TRUE;
servtype = nconf->nc_semantics;
bindresvport(fd, NULL);
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
} else {
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
servtype = __rpc_socktype2seman(si.si_socktype);
if (servtype == -1) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
}
if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */
goto err1;
}
switch (servtype) {
case NC_TPI_COTS:
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz,
callback_xdr, callback_function, callback_args);
break;
case NC_TPI_COTS_ORD:
if (nconf &&
((strcmp(nconf->nc_protofmly, "inet") == 0) ||
(strcmp(nconf->nc_protofmly, "inet6") == 0))) {
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one,
sizeof (one));
}
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz,
callback_xdr, callback_function, callback_args);
break;
case NC_TPI_CLTS:
cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
break;
default:
goto err;
}
if (cl == NULL)
goto err1; /* borrow errors from clnt_dg/vc creates */
if (nconf) {
cl->cl_netid = strdup(nconf->nc_netid);
cl->cl_tp = strdup(nconf->nc_device);
} else {
cl->cl_netid = "";
cl->cl_tp = "";
}
if (madefd) {
(void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL);
/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL); */
};
return (cl);
err:
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
err1: if (madefd)
(void)closesocket(fd);
return (NULL);
}
#if 0 /* WINDOWS */
/*
* To avoid conflicts with the "magic" file descriptors (0, 1, and 2),
* we try to not use them. The __rpc_raise_fd() routine will dup
* a descriptor to a higher value. If we fail to do it, we continue
* to use the old one (and hope for the best).
*/
int __rpc_minfd = 3;
int
__rpc_raise_fd(int fd)
{
int nfd;
if (fd >= __rpc_minfd)
return (fd);
if ((nfd = fcntl(fd, F_DUPFD, __rpc_minfd)) == -1)
return (fd);
if (fsync(nfd) == -1) {
closesocket(nfd);
return (fd);
}
if (closesocket(fd) == -1) {
/* this is okay, we will syslog an error, then use the new fd */
(void) syslog(LOG_ERR,
"could not close() fd %d; mem & fd leak", fd);
}
return (nfd);
}
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>
//#include <pthread.h>
#include <reentrant.h>
#include <sys/types.h>
//#include <sys/fcntl.h>
#include <fcntl.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <netinet/tcp.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
//#include <netdb.h>
//#include <syslog.h>
#include <rpc/rpc.h>
#include <rpc/nettype.h>
//#include <unistd.h>
#include "rpc_com.h"
extern bool_t __rpc_is_local_host(const char *);
#if 0 /* WINDOWS */
int __rpc_raise_fd(int);
#endif
#ifndef NETIDLEN
#define NETIDLEN 32
#endif
/*
* Generic client creation with version checking the value of
* vers_out is set to the highest server supported value
* vers_low <= vers_out <= vers_high AND an error results
* if this can not be done.
*
* It calls clnt_create_vers_timed() with a NULL value for the timeout
* pointer, which indicates that the default timeout should be used.
*/
CLIENT *
clnt_create_vers(const char *hostname, const rpcprog_t prog, rpcvers_t *vers_out,
const rpcvers_t vers_low, const rpcvers_t vers_high, const char *nettype)
{
return (clnt_create_vers_timed(hostname, prog, vers_out, vers_low,
vers_high, nettype, NULL));
}
/*
* This the routine has the same definition as clnt_create_vers(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*/
CLIENT *
clnt_create_vers_timed(const char *hostname, const rpcprog_t prog,
rpcvers_t *vers_out, const rpcvers_t vers_low_in, const rpcvers_t vers_high_in,
const char *nettype, const struct timeval *tp)
{
CLIENT *clnt;
struct timeval to;
enum clnt_stat rpc_stat;
struct rpc_err rpcerr;
rpcvers_t vers_high = vers_high_in;
rpcvers_t vers_low = vers_low_in;
clnt = clnt_create_timed(hostname, prog, vers_high, nettype, tp);
if (clnt == NULL) {
return (NULL);
}
to.tv_sec = 10;
to.tv_usec = 0;
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void,
(char *)NULL, (xdrproc_t)xdr_void, (char *)NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
while (rpc_stat == RPC_PROGVERSMISMATCH && vers_high > vers_low) {
unsigned int minvers, maxvers;
clnt_geterr(clnt, &rpcerr);
minvers = rpcerr.re_vers.low;
maxvers = rpcerr.re_vers.high;
if (maxvers < vers_high)
vers_high = maxvers;
else
vers_high--;
if (minvers > vers_low)
vers_low = minvers;
if (vers_low > vers_high) {
goto error;
}
CLNT_CONTROL(clnt, CLSET_VERS, (char *)&vers_high);
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t)xdr_void,
(char *)NULL, (xdrproc_t)xdr_void,
(char *)NULL, to);
if (rpc_stat == RPC_SUCCESS) {
*vers_out = vers_high;
return (clnt);
}
}
clnt_geterr(clnt, &rpcerr);
error:
rpc_createerr.cf_stat = rpc_stat;
rpc_createerr.cf_error = rpcerr;
clnt_destroy(clnt);
return (NULL);
}
/*
* Top level client creation routine.
* Generic client creation: takes (servers name, program-number, nettype) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s.
*
* It tries for all the netids in that particular class of netid until
* it succeeds.
* XXX The error message in the case of failure will be the one
* pertaining to the last create error.
*
* It calls clnt_create_timed() with the default timeout.
*/
CLIENT *
clnt_create(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const char *nettype)
{
return (clnt_create_timed(hostname, prog, vers, nettype, NULL));
}
/*
* This the routine has the same definition as clnt_create(),
* except it takes an additional timeout parameter - a pointer to
* a timeval structure. A NULL value for the pointer indicates
* that the default timeout value should be used.
*
* This function calls clnt_tp_create_timed().
*/
CLIENT *
clnt_create_timed(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const char *netclass, const struct timeval *tp)
{
struct netconfig *nconf;
CLIENT *clnt = NULL;
void *handle;
enum clnt_stat save_cf_stat = RPC_SUCCESS;
struct rpc_err save_cf_error;
char nettype_array[NETIDLEN];
char *nettype = &nettype_array[0];
if (netclass == NULL)
nettype = NULL;
else {
size_t len = strlen(netclass);
if (len >= sizeof (nettype_array)) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
strcpy(nettype, netclass);
}
if ((handle = __rpc_setconf((char *)nettype)) == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
rpc_createerr.cf_stat = RPC_SUCCESS;
while (clnt == NULL) {
if ((nconf = __rpc_getconf(handle)) == NULL) {
if (rpc_createerr.cf_stat == RPC_SUCCESS)
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
break;
}
#ifdef CLNT_DEBUG
printf("trying netid %s\n", nconf->nc_netid);
#endif
clnt = clnt_tp_create_timed(hostname, prog, vers, nconf, tp);
if (clnt)
break;
else {
/*
* Since we didn't get a name-to-address
* translation failure here, we remember
* this particular error. The object of
* this is to enable us to return to the
* caller a more-specific error than the
* unhelpful ``Name to address translation
* failed'' which might well occur if we
* merely returned the last error (because
* the local loopbacks are typically the
* last ones in /etc/netconfig and the most
* likely to be unable to translate a host
* name). We also check for a more
* meaningful error than ``unknown host
* name'' for the same reasons.
*/
if (rpc_createerr.cf_stat != RPC_N2AXLATEFAILURE &&
rpc_createerr.cf_stat != RPC_UNKNOWNHOST) {
save_cf_stat = rpc_createerr.cf_stat;
save_cf_error = rpc_createerr.cf_error;
}
}
}
/*
* Attempt to return an error more specific than ``Name to address
* translation failed'' or ``unknown host name''
*/
if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE ||
rpc_createerr.cf_stat == RPC_UNKNOWNHOST) &&
(save_cf_stat != RPC_SUCCESS)) {
rpc_createerr.cf_stat = save_cf_stat;
rpc_createerr.cf_error = save_cf_error;
}
__rpc_endconf(handle);
return (clnt);
}
/*
* Generic client creation: takes (servers name, program-number, netconf) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control()
* It finds out the server address from rpcbind and calls clnt_tli_create().
*
* It calls clnt_tp_create_timed() with the default timeout.
*/
CLIENT *
clnt_tp_create(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const struct netconfig *nconf)
{
return (clnt_tp_create_timed(hostname, prog, vers, nconf, NULL));
}
/*
* This has the same definition as clnt_tp_create(), except it
* takes an additional parameter - a pointer to a timeval structure.
* A NULL value for the timeout pointer indicates that the default
* value for the timeout should be used.
*/
CLIENT *
clnt_tp_create_timed(const char *hostname, const rpcprog_t prog, const rpcvers_t vers,
const struct netconfig *nconf, const struct timeval *tp)
{
struct netbuf *svcaddr; /* servers address */
CLIENT *cl = NULL; /* client handle */
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
/*
* Get the address of the server
*/
if ((svcaddr = __rpcb_findaddr_timed(prog, vers,
(struct netconfig *)nconf, (char *)hostname,
&cl, (struct timeval *)tp)) == NULL) {
/* appropriate error number is set by rpcbind libraries */
return (NULL);
}
if (cl == NULL) {
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0, NULL, NULL, NULL);
} else {
/* Reuse the CLIENT handle and change the appropriate fields */
if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) {
if (cl->cl_netid == NULL)
cl->cl_netid = strdup(nconf->nc_netid);
if (cl->cl_tp == NULL)
cl->cl_tp = strdup(nconf->nc_device);
(void) CLNT_CONTROL(cl, CLSET_PROG, (void *)&prog);
(void) CLNT_CONTROL(cl, CLSET_VERS, (void *)&vers);
} else {
CLNT_DESTROY(cl);
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
prog, vers, 0, 0, NULL, NULL, NULL);
}
}
free(svcaddr->buf);
free(svcaddr);
return (cl);
}
/*
* Generic client creation: returns client handle.
* Default options are set, which the user can
* change using the rpc equivalent of _ioctl()'s : clnt_control().
* If fd is RPC_ANYFD, it will be opened using nconf.
* It will be bound if not so.
* If sizes are 0; appropriate defaults will be chosen.
*/
CLIENT *
clnt_tli_create(const SOCKET fd_in, const struct netconfig *nconf,
struct netbuf *svcaddr, const rpcprog_t prog, const rpcvers_t vers,
const uint sendsz, const uint recvsz,
int (*callback_xdr)(void *, void *),
int (*callback_function)(void *, void *, void **),
void *callback_args)
{
CLIENT *cl; /* client handle */
bool_t madefd = FALSE; /* whether fd opened here */
long servtype;
BOOL one = TRUE;
struct __rpc_sockinfo si;
extern int __rpc_minfd;
SOCKET fd = fd_in;
if (fd == RPC_ANYFD) {
if (nconf == NULL) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
fd = __rpc_nconf2fd(nconf);
if (fd == INVALID_SOCKET)
goto err;
#if 0
if (fd < __rpc_minfd)
fd = __rpc_raise_fd(fd);
#endif
madefd = TRUE;
servtype = nconf->nc_semantics;
bindresvport(fd, NULL);
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
} else {
if (!__rpc_fd2sockinfo(fd, &si))
goto err;
servtype = __rpc_socktype2seman(si.si_socktype);
if (servtype == -1) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
return (NULL);
}
}
if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */
goto err1;
}
switch (servtype) {
case NC_TPI_COTS:
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz,
callback_xdr, callback_function, callback_args);
break;
case NC_TPI_COTS_ORD:
if (nconf &&
((strcmp(nconf->nc_protofmly, "inet") == 0) ||
(strcmp(nconf->nc_protofmly, "inet6") == 0))) {
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one,
sizeof (one));
}
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz,
callback_xdr, callback_function, callback_args);
break;
case NC_TPI_CLTS:
cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
break;
default:
goto err;
}
if (cl == NULL)
goto err1; /* borrow errors from clnt_dg/vc creates */
if (nconf) {
cl->cl_netid = strdup(nconf->nc_netid);
cl->cl_tp = strdup(nconf->nc_device);
} else {
cl->cl_netid = "";
cl->cl_tp = "";
}
if (madefd) {
(void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL);
/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, NULL); */
};
return (cl);
err:
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = errno;
err1: if (madefd)
(void)closesocket(fd);
return (NULL);
}
#if 0 /* WINDOWS */
/*
* To avoid conflicts with the "magic" file descriptors (0, 1, and 2),
* we try to not use them. The __rpc_raise_fd() routine will dup
* a descriptor to a higher value. If we fail to do it, we continue
* to use the old one (and hope for the best).
*/
int __rpc_minfd = 3;
int
__rpc_raise_fd(int fd)
{
int nfd;
if (fd >= __rpc_minfd)
return (fd);
if ((nfd = fcntl(fd, F_DUPFD, __rpc_minfd)) == -1)
return (fd);
if (fsync(nfd) == -1) {
closesocket(nfd);
return (fd);
}
if (closesocket(fd) == -1) {
/* this is okay, we will syslog an error, then use the new fd */
(void) syslog(LOG_ERR,
"could not close() fd %d; mem & fd leak", fd);
}
return (nfd);
}
#endif

View file

@ -45,31 +45,27 @@
* Now go hang yourself.
*/
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
*
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>
//#include <pthread.h>

View file

@ -1,415 +1,410 @@
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* rpc_prot.c
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* This set of routines implements the rpc message definition,
* its serializer and some common rpc utility routines.
* The routines are meant for various implementations of rpc -
* they are NOT for the rpc client or rpc service implementations!
* Because authentication stuff is easy and is part of rpc, the opaque
* routines are also in this program.
*/
/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
/*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* rpc_prot.c
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*
* This set of routines implements the rpc message definition,
* its serializer and some common rpc utility routines.
* The routines are meant for various implementations of rpc -
* they are NOT for the rpc client or rpc service implementations!
* Because authentication stuff is easy and is part of rpc, the opaque
* routines are also in this program.
*/
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
* Kevin Coffman <kwc@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#include <wintirpc.h>
//#include <sys/param.h>
#include <assert.h>
#include <rpc/rpc.h>
static void accepted(enum accept_stat, struct rpc_err *);
static void rejected(enum reject_stat, struct rpc_err *);
/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
extern struct opaque_auth _null_auth;
/*
* XDR an opaque authentication struct
* (see auth.h)
*/
bool_t
xdr_opaque_auth(xdrs, ap)
XDR *xdrs;
struct opaque_auth *ap;
{
assert(xdrs != NULL);
assert(ap != NULL);
if (xdr_enum(xdrs, &(ap->oa_flavor)))
return (xdr_bytes(xdrs, &ap->oa_base,
&ap->oa_length, MAX_AUTH_BYTES));
return (FALSE);
}
/*
* XDR a DES block
*/
bool_t
xdr_des_block(xdrs, blkp)
XDR *xdrs;
des_block *blkp;
{
assert(xdrs != NULL);
assert(blkp != NULL);
return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block)));
}
/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
/*
* XDR the MSG_ACCEPTED part of a reply message union
*/
bool_t
xdr_accepted_reply(xdrs, ar)
XDR *xdrs;
struct accepted_reply *ar;
{
assert(xdrs != NULL);
assert(ar != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
return (FALSE);
if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
return (FALSE);
switch (ar->ar_stat) {
case SUCCESS:
return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
case PROG_MISMATCH:
if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
return (FALSE);
return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
case GARBAGE_ARGS:
case SYSTEM_ERR:
case PROC_UNAVAIL:
case PROG_UNAVAIL:
break;
}
return (TRUE); /* TRUE => open ended set of problems */
}
/*
* XDR the MSG_DENIED part of a reply message union
*/
bool_t
xdr_rejected_reply(xdrs, rr)
XDR *xdrs;
struct rejected_reply *rr;
{
assert(xdrs != NULL);
assert(rr != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
return (FALSE);
switch (rr->rj_stat) {
case RPC_MISMATCH:
if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
return (FALSE);
return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
case AUTH_ERROR:
return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
}
/* NOTREACHED */
assert(0);
return (FALSE);
}
static const struct xdr_discrim reply_dscrm[3] = {
{ (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
{ (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
{ __dontcare__, NULL_xdrproc_t } };
/*
* XDR a reply message
*/
bool_t
xdr_replymsg(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
if (
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
(rmsg->rm_direction == REPLY) )
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t));
return (FALSE);
}
/*
* XDR a reply message in pieces, first xid and direction, then union
*/
bool_t
xdr_getxiddir(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
return (xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)));
}
bool_t
xdr_getreplyunion(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t));
}
bool_t
xdr_getcallbody(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
if (
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_prog)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_vers)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_proc)) &&
xdr_opaque_auth(xdrs, &(rmsg->rm_call.cb_cred)) )
return (xdr_opaque_auth(xdrs, &(rmsg->rm_call.cb_verf)));
return FALSE;
}
/*
* Serializes the "static part" of a call message header.
* The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
* The rm_xid is not really static, but the user can easily munge on the fly.
*/
bool_t
xdr_callhdr(xdrs, cmsg)
XDR *xdrs;
struct rpc_msg *cmsg;
{
assert(xdrs != NULL);
assert(cmsg != NULL);
cmsg->rm_direction = CALL;
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
if (
(xdrs->x_op == XDR_ENCODE) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
return (FALSE);
}
/* ************************** Client utility routine ************* */
static void
accepted(acpt_stat, error)
enum accept_stat acpt_stat;
struct rpc_err *error;
{
assert(error != NULL);
switch (acpt_stat) {
case PROG_UNAVAIL:
error->re_status = RPC_PROGUNAVAIL;
return;
case PROG_MISMATCH:
error->re_status = RPC_PROGVERSMISMATCH;
return;
case PROC_UNAVAIL:
error->re_status = RPC_PROCUNAVAIL;
return;
case GARBAGE_ARGS:
error->re_status = RPC_CANTDECODEARGS;
return;
case SYSTEM_ERR:
error->re_status = RPC_SYSTEMERROR;
return;
case SUCCESS:
error->re_status = RPC_SUCCESS;
return;
}
/* NOTREACHED */
/* something's wrong, but we don't know what ... */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)MSG_ACCEPTED;
error->re_lb.s2 = (int32_t)acpt_stat;
}
static void
rejected(rjct_stat, error)
enum reject_stat rjct_stat;
struct rpc_err *error;
{
assert(error != NULL);
switch (rjct_stat) {
case RPC_MISMATCH:
error->re_status = RPC_VERSMISMATCH;
return;
case AUTH_ERROR:
error->re_status = RPC_AUTHERROR;
return;
}
/* something's wrong, but we don't know what ... */
/* NOTREACHED */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)MSG_DENIED;
error->re_lb.s2 = (int32_t)rjct_stat;
}
/*
* given a reply message, fills in the error
*/
void
_seterr_reply(msg, error)
struct rpc_msg *msg;
struct rpc_err *error;
{
assert(msg != NULL);
assert(error != NULL);
/* optimized for normal, SUCCESSful case */
switch (msg->rm_reply.rp_stat) {
case MSG_ACCEPTED:
if (msg->acpted_rply.ar_stat == SUCCESS) {
error->re_status = RPC_SUCCESS;
return;
}
accepted(msg->acpted_rply.ar_stat, error);
break;
case MSG_DENIED:
rejected(msg->rjcted_rply.rj_stat, error);
break;
default:
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat);
break;
}
switch (error->re_status) {
case RPC_VERSMISMATCH:
error->re_vers.low = msg->rjcted_rply.rj_vers.low;
error->re_vers.high = msg->rjcted_rply.rj_vers.high;
break;
case RPC_AUTHERROR:
error->re_why = msg->rjcted_rply.rj_why;
break;
case RPC_PROGVERSMISMATCH:
error->re_vers.low = msg->acpted_rply.ar_vers.low;
error->re_vers.high = msg->acpted_rply.ar_vers.high;
break;
case RPC_FAILED:
case RPC_SUCCESS:
case RPC_PROGNOTREGISTERED:
case RPC_PMAPFAILURE:
case RPC_UNKNOWNPROTO:
case RPC_UNKNOWNHOST:
case RPC_SYSTEMERROR:
case RPC_CANTDECODEARGS:
case RPC_PROCUNAVAIL:
case RPC_PROGUNAVAIL:
case RPC_TIMEDOUT:
case RPC_CANTRECV:
case RPC_CANTSEND:
case RPC_CANTDECODERES:
case RPC_CANTENCODEARGS:
default:
break;
}
}
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>
//#include <sys/param.h>
#include <assert.h>
#include <rpc/rpc.h>
static void accepted(enum accept_stat, struct rpc_err *);
static void rejected(enum reject_stat, struct rpc_err *);
/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
extern struct opaque_auth _null_auth;
/*
* XDR an opaque authentication struct
* (see auth.h)
*/
bool_t
xdr_opaque_auth(xdrs, ap)
XDR *xdrs;
struct opaque_auth *ap;
{
assert(xdrs != NULL);
assert(ap != NULL);
if (xdr_enum(xdrs, &(ap->oa_flavor)))
return (xdr_bytes(xdrs, &ap->oa_base,
&ap->oa_length, MAX_AUTH_BYTES));
return (FALSE);
}
/*
* XDR a DES block
*/
bool_t
xdr_des_block(xdrs, blkp)
XDR *xdrs;
des_block *blkp;
{
assert(xdrs != NULL);
assert(blkp != NULL);
return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block)));
}
/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
/*
* XDR the MSG_ACCEPTED part of a reply message union
*/
bool_t
xdr_accepted_reply(xdrs, ar)
XDR *xdrs;
struct accepted_reply *ar;
{
assert(xdrs != NULL);
assert(ar != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
return (FALSE);
if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
return (FALSE);
switch (ar->ar_stat) {
case SUCCESS:
return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
case PROG_MISMATCH:
if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
return (FALSE);
return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
case GARBAGE_ARGS:
case SYSTEM_ERR:
case PROC_UNAVAIL:
case PROG_UNAVAIL:
break;
}
return (TRUE); /* TRUE => open ended set of problems */
}
/*
* XDR the MSG_DENIED part of a reply message union
*/
bool_t
xdr_rejected_reply(xdrs, rr)
XDR *xdrs;
struct rejected_reply *rr;
{
assert(xdrs != NULL);
assert(rr != NULL);
/* personalized union, rather than calling xdr_union */
if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
return (FALSE);
switch (rr->rj_stat) {
case RPC_MISMATCH:
if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
return (FALSE);
return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
case AUTH_ERROR:
return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
}
/* NOTREACHED */
assert(0);
return (FALSE);
}
static const struct xdr_discrim reply_dscrm[3] = {
{ (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
{ (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
{ __dontcare__, NULL_xdrproc_t } };
/*
* XDR a reply message
*/
bool_t
xdr_replymsg(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
if (
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
(rmsg->rm_direction == REPLY) )
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t));
return (FALSE);
}
/*
* XDR a reply message in pieces, first xid and direction, then union
*/
bool_t
xdr_getxiddir(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
return (xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)));
}
bool_t
xdr_getreplyunion(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
NULL_xdrproc_t));
}
bool_t
xdr_getcallbody(xdrs, rmsg)
XDR *xdrs;
struct rpc_msg *rmsg;
{
assert(xdrs != NULL);
assert(rmsg != NULL);
if (
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_prog)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_vers)) &&
xdr_u_int32_t(xdrs, &(rmsg->rm_call.cb_proc)) &&
xdr_opaque_auth(xdrs, &(rmsg->rm_call.cb_cred)) )
return (xdr_opaque_auth(xdrs, &(rmsg->rm_call.cb_verf)));
return FALSE;
}
/*
* Serializes the "static part" of a call message header.
* The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
* The rm_xid is not really static, but the user can easily munge on the fly.
*/
bool_t
xdr_callhdr(xdrs, cmsg)
XDR *xdrs;
struct rpc_msg *cmsg;
{
assert(xdrs != NULL);
assert(cmsg != NULL);
cmsg->rm_direction = CALL;
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
if (
(xdrs->x_op == XDR_ENCODE) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
return (FALSE);
}
/* ************************** Client utility routine ************* */
static void
accepted(acpt_stat, error)
enum accept_stat acpt_stat;
struct rpc_err *error;
{
assert(error != NULL);
switch (acpt_stat) {
case PROG_UNAVAIL:
error->re_status = RPC_PROGUNAVAIL;
return;
case PROG_MISMATCH:
error->re_status = RPC_PROGVERSMISMATCH;
return;
case PROC_UNAVAIL:
error->re_status = RPC_PROCUNAVAIL;
return;
case GARBAGE_ARGS:
error->re_status = RPC_CANTDECODEARGS;
return;
case SYSTEM_ERR:
error->re_status = RPC_SYSTEMERROR;
return;
case SUCCESS:
error->re_status = RPC_SUCCESS;
return;
}
/* NOTREACHED */
/* something's wrong, but we don't know what ... */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)MSG_ACCEPTED;
error->re_lb.s2 = (int32_t)acpt_stat;
}
static void
rejected(rjct_stat, error)
enum reject_stat rjct_stat;
struct rpc_err *error;
{
assert(error != NULL);
switch (rjct_stat) {
case RPC_MISMATCH:
error->re_status = RPC_VERSMISMATCH;
return;
case AUTH_ERROR:
error->re_status = RPC_AUTHERROR;
return;
}
/* something's wrong, but we don't know what ... */
/* NOTREACHED */
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)MSG_DENIED;
error->re_lb.s2 = (int32_t)rjct_stat;
}
/*
* given a reply message, fills in the error
*/
void
_seterr_reply(msg, error)
struct rpc_msg *msg;
struct rpc_err *error;
{
assert(msg != NULL);
assert(error != NULL);
/* optimized for normal, SUCCESSful case */
switch (msg->rm_reply.rp_stat) {
case MSG_ACCEPTED:
if (msg->acpted_rply.ar_stat == SUCCESS) {
error->re_status = RPC_SUCCESS;
return;
}
accepted(msg->acpted_rply.ar_stat, error);
break;
case MSG_DENIED:
rejected(msg->rjcted_rply.rj_stat, error);
break;
default:
error->re_status = RPC_FAILED;
error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat);
break;
}
switch (error->re_status) {
case RPC_VERSMISMATCH:
error->re_vers.low = msg->rjcted_rply.rj_vers.low;
error->re_vers.high = msg->rjcted_rply.rj_vers.high;
break;
case RPC_AUTHERROR:
error->re_why = msg->rjcted_rply.rj_why;
break;
case RPC_PROGVERSMISMATCH:
error->re_vers.low = msg->acpted_rply.ar_vers.low;
error->re_vers.high = msg->acpted_rply.ar_vers.high;
break;
case RPC_FAILED:
case RPC_SUCCESS:
case RPC_PROGNOTREGISTERED:
case RPC_PMAPFAILURE:
case RPC_UNKNOWNPROTO:
case RPC_UNKNOWNHOST:
case RPC_SYSTEMERROR:
case RPC_CANTDECODEARGS:
case RPC_PROCUNAVAIL:
case RPC_PROGUNAVAIL:
case RPC_TIMEDOUT:
case RPC_CANTRECV:
case RPC_CANTSEND:
case RPC_CANTDECODERES:
case RPC_CANTENCODEARGS:
default:
break;
}
}

View file

@ -1,24 +1,22 @@
/* Copyright (c) 2010
* The Regents of the University of Michigan
* All Rights Reserved
/* NFSv4.1 client for Windows
* Copyright © 2012 The Regents of the University of Michigan
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* without any warranty; without even the implied warranty of merchantability
* or fitness for a particular purpose. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA
*/
#include <wintirpc.h>

File diff suppressed because it is too large Load diff