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:
parent
6f8f4d8e3f
commit
bbb1ed696c
88 changed files with 4784 additions and 5040 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue