[Add] First commit
This commit is contained in:
BIN
.resource/libtirpc-1.3.1.tar.bz2
Executable file
BIN
.resource/libtirpc-1.3.1.tar.bz2
Executable file
Binary file not shown.
BIN
.resource/nfs-utils-2.5.2.tar.xz
Executable file
BIN
.resource/nfs-utils-2.5.2.tar.xz
Executable file
Binary file not shown.
BIN
.resource/rpcsvc-proto-1.4.2.tar.xz
Executable file
BIN
.resource/rpcsvc-proto-1.4.2.tar.xz
Executable file
Binary file not shown.
52
libtirpc-1.3.1/.gitignore
vendored
Normal file
52
libtirpc-1.3.1/.gitignore
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# files generated by autoconf, automake, autoheader and libtoolize
|
||||||
|
aclocal.m4
|
||||||
|
autom4te.cache
|
||||||
|
compile
|
||||||
|
config.guess
|
||||||
|
config.log
|
||||||
|
config.sub
|
||||||
|
configure
|
||||||
|
depcomp
|
||||||
|
install-sh
|
||||||
|
libtool
|
||||||
|
ltmain.sh
|
||||||
|
Makefile.in
|
||||||
|
missing
|
||||||
|
config.h.in
|
||||||
|
m4/*
|
||||||
|
libtirpc-*.tar.gz
|
||||||
|
# files generated by configure
|
||||||
|
confdefs.h
|
||||||
|
config.status
|
||||||
|
conftest
|
||||||
|
conftest.c
|
||||||
|
conftest.cpp
|
||||||
|
conftest.er1
|
||||||
|
conftest.err
|
||||||
|
.deps
|
||||||
|
Makefile
|
||||||
|
config.h
|
||||||
|
stamp-h1
|
||||||
|
libtirpc.pc
|
||||||
|
# file generated during compilation
|
||||||
|
*.o
|
||||||
|
.libs
|
||||||
|
lib*.a
|
||||||
|
src/libtirpc.la
|
||||||
|
src/libtirpc_la-*.lo
|
||||||
|
tirpc/stamp-h2
|
||||||
|
tirpc/tirpc-features.h
|
||||||
|
|
||||||
|
# generic editor backup et al
|
||||||
|
*~
|
||||||
|
.stgitmail.txt
|
||||||
|
# cscope database files
|
||||||
|
cscope.*
|
||||||
|
# files generated by patches
|
||||||
|
*.patch
|
||||||
|
*.rej
|
||||||
|
*.orig
|
||||||
|
# files generated by debugging
|
||||||
|
.gdb_history
|
||||||
|
.gdbinit
|
||||||
|
core
|
||||||
3
libtirpc-1.3.1/AUTHORS
Normal file
3
libtirpc-1.3.1/AUTHORS
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Gilles Quillard <gilles.quillard@bull.net>
|
||||||
|
Antoine Fraticelli <antoine.fraticelli@bull.net>
|
||||||
|
|
||||||
25
libtirpc-1.3.1/COPYING
Normal file
25
libtirpc-1.3.1/COPYING
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Copyright (c) Bull S.A. 2005 All Rights Reserved.
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||||
|
*/
|
||||||
|
|
||||||
206
libtirpc-1.3.1/ChangeLog
Normal file
206
libtirpc-1.3.1/ChangeLog
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
2008-11-19 Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
* Version 0.1.10 released.
|
||||||
|
|
||||||
|
commit 32ec5931e3debf208972d5146578f08dc113a9b6
|
||||||
|
Merge: 338af7f... 92cf0dd...
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Mon Nov 17 12:26:22 2008 -0500
|
||||||
|
|
||||||
|
Merge branch 'master' of git://git.infradead.org/~steved/libtirpc
|
||||||
|
|
||||||
|
commit 92cf0dde310ca341a2f29ff66b19eeb9994a649a
|
||||||
|
Author: Ian Kent <ikent@redhat.com>
|
||||||
|
Date: Tue Oct 28 11:19:07 2008 -0400
|
||||||
|
|
||||||
|
Fixed a warings the IPV6 client routines
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 338af7f9f00e096b65a6d823f885c4eeaf1d1f8c
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Mon Oct 27 12:46:54 2008 -0400
|
||||||
|
|
||||||
|
__rpc_taddr2uaddr_af() assumes the netbuf to always have a
|
||||||
|
non-zero data. This is a bad assumption and can lead to a
|
||||||
|
seg-fault. This patch adds a check for zero length and returns
|
||||||
|
NULL when found.
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit d9a5ae7079d001a9e3b9b384f9153f591a7158bd
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:10:43 2008 -0400
|
||||||
|
|
||||||
|
Fix __rpc_getconfip
|
||||||
|
|
||||||
|
__rpc_getconfip is supposed to return the first netconf
|
||||||
|
entry supporting tcp or udp, respectively. The code will
|
||||||
|
currently return the *last* entry, plus it will leak
|
||||||
|
memory when there is more than one such entry.
|
||||||
|
|
||||||
|
This patch fixes this issue.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 6c487efe74adb5c29f7bee5bd51b3ebef4968f7d
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:09:06 2008 -0400
|
||||||
|
|
||||||
|
Fix getpeereid
|
||||||
|
|
||||||
|
getpeereid fails because it uses an incorrect getsockopt call to obtain
|
||||||
|
the peer credentials on a AF_LOCAL socket. This in turn will cause all
|
||||||
|
RPC services to be registered with rpcbind to show up as having been
|
||||||
|
registered by "unknown".
|
||||||
|
|
||||||
|
This has a serious impact on security - a service owned by "unknown"
|
||||||
|
can essentially be unregistered (and thus replaced) by anyone.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 851b0f5c6dca22d634603f03f0a5e3e35c6db867
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:08:07 2008 -0400
|
||||||
|
|
||||||
|
svc_getcaller_netbuf macro seems broken
|
||||||
|
|
||||||
|
I haven't found any documentation, but the comment in the header
|
||||||
|
file seems to suggest that svc_getcaller_netbuf should return the
|
||||||
|
xp_rtaddr netbuf. Returning the address of the socket descripor
|
||||||
|
seems to be wrong at any rate.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit d94b92d5125242ce595c1baf42a1e6d1004b7756
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:06:54 2008 -0400
|
||||||
|
|
||||||
|
Introduce __rpc_set_netbuf helper
|
||||||
|
|
||||||
|
The RPC code contains a number of places where a netbuf
|
||||||
|
is initialized with some data. All the mem_alloc/memcpy
|
||||||
|
stuff is open-coded. Introduce a helper function and
|
||||||
|
convert the code.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit da5f9861ea3bae59c8eead26d38334721caa9f0a
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:05:20 2008 -0400
|
||||||
|
|
||||||
|
Kill map_ipv4_to_ipv6
|
||||||
|
|
||||||
|
After the change to svc_vc.c performed in the previous patch,
|
||||||
|
this function is no longer needed.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 59c374c4b507aeca957ed0096d98006edf601375
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:04:17 2008 -0400
|
||||||
|
|
||||||
|
Fix xp_raddr handling in svc_fd_create etc
|
||||||
|
|
||||||
|
Currently svc_fd_create tries to do some clever tricks
|
||||||
|
with IPv4/v6 address mapping.
|
||||||
|
|
||||||
|
This is broken for several reasons.
|
||||||
|
1. We don't want IPv4 based transport to look like IPv6
|
||||||
|
transports. Old applications compiled against tirpc
|
||||||
|
will expect AF_INET addresses, and are not equipped
|
||||||
|
to deal with AF_INET6.
|
||||||
|
2. There's a buffer overflow.
|
||||||
|
memcpy(&sin6, &ss, sizeof(ss));
|
||||||
|
copies a full struct sockaddr to a sockaddr_in6 on
|
||||||
|
the stack. Unlikely to be exploitable, but I wonder
|
||||||
|
if this ever worked....
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 628788c1cc84c86ee4cb36ee5d4fe8954e90fca5
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Tue Sep 16 11:32:31 2008 -0400
|
||||||
|
|
||||||
|
- Fixed version-info in src/Makefile.am to reflect the correct version
|
||||||
|
- Fixed some of warnings in: src/auth_time.c, src/clnt_dg.c and
|
||||||
|
src/clnt_raw.c
|
||||||
|
- Added some #ifdef NOTUSED around some code in src/rpbc_clnt.c
|
||||||
|
that was not being used...
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 9e7ba0c7a02031294fefadfbca42b3dd5f2d841f
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 16 08:46:29 2008 -0400
|
||||||
|
|
||||||
|
Fix for taddr2addr conversion bug of local addresses
|
||||||
|
|
||||||
|
When converting af_local socket addresses in taddr2uaddr, an incorrect
|
||||||
|
sizeof() would result in a truncated path string. As a result,
|
||||||
|
rpcbind will report the local /var/lib/rpcbind address to clients
|
||||||
|
as "/v" on a 32bit machine.
|
||||||
|
|
||||||
|
Signed-off-by: okir@suse.de
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit ea9f048761d0b9a2ab6310bffa07351f0b04d8c5
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 2 12:11:15 2008 -0400
|
||||||
|
|
||||||
|
Always make IPv6 sockets V6ONLY
|
||||||
|
|
||||||
|
Assume you have a netconfig file looking like this:
|
||||||
|
|
||||||
|
udp tpi_clts v inet udp - -
|
||||||
|
udp6 tpi_clts v inet6 udp - -
|
||||||
|
...
|
||||||
|
|
||||||
|
a call to svc_tli_create(... &someaddr, "udp") will fail to create an
|
||||||
|
IPv6 server socket. The problem is that on Linux, passive IPv6 sockets
|
||||||
|
will also accept packets/connections from IPv4, and will simply map
|
||||||
|
the sender's address to an IPv6 mapped IPv4 address. So if you want to
|
||||||
|
bind both a UDPv4 and UDPv6 socket to the same port, this will fail with
|
||||||
|
EADDRINUSE.
|
||||||
|
|
||||||
|
The way to avoid this behavior is to change the socket to V6ONLY,
|
||||||
|
which tells the kernel to avoid the autmatic mapping.
|
||||||
|
|
||||||
|
The change proposed in the patch below does this. I *think* this is
|
||||||
|
a good place to do this, as it will also fix applications that do not
|
||||||
|
use svc_tli_create() - such as rpcbind, which creates the sockets on
|
||||||
|
its own using __rpc_nconf2fd.
|
||||||
|
|
||||||
|
I think this also improves portability, as BSD code assumes BSD
|
||||||
|
behavior, where this mapping does not occur either.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 95c8f7227e6b15f2e430d7b87dadc95b2acd4a61
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 2 12:09:39 2008 -0400
|
||||||
|
|
||||||
|
Fix incorrect sizeof() in __rpc_getbroadifs
|
||||||
|
|
||||||
|
__rpc_getbroadifs returns bad broadcast addresses on 32bit
|
||||||
|
machines because when copying the broadcast addresses, ite
|
||||||
|
applies the sizeof() operator to a pointer to a sockaddr,
|
||||||
|
rather than the sockaddr itself.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
2004-10-13 Antoine Fraticelli <antoine.fraticellie@bull.net>
|
||||||
|
|
||||||
|
* Version 0.1 released.
|
||||||
|
|
||||||
|
2005-01-07 Gilles Quillard <Gilles.Quillard@bull.net>
|
||||||
|
|
||||||
|
* Version 0.1.5 Fix problems links to the use of Kerberos.
|
||||||
2
libtirpc-1.3.1/HACKING
Normal file
2
libtirpc-1.3.1/HACKING
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Patches can be sent to libtirpc-devel@lists.sourceforge.net with a CC
|
||||||
|
to linux-nfs@vger.kernel.org
|
||||||
370
libtirpc-1.3.1/INSTALL
Normal file
370
libtirpc-1.3.1/INSTALL
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
Installation Instructions
|
||||||
|
*************************
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
|
||||||
|
Inc.
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. This file is offered as-is,
|
||||||
|
without warranty of any kind.
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
Briefly, the shell command `./configure && make && make install'
|
||||||
|
should configure, build, and install this package. The following
|
||||||
|
more-detailed instructions are generic; see the `README' file for
|
||||||
|
instructions specific to this package. Some packages provide this
|
||||||
|
`INSTALL' file but do not implement all of the features documented
|
||||||
|
below. The lack of an optional feature in a given package is not
|
||||||
|
necessarily a bug. More recommendations for GNU packages can be found
|
||||||
|
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, and a
|
||||||
|
file `config.log' containing compiler output (useful mainly for
|
||||||
|
debugging `configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called `config.cache'
|
||||||
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
|
the results of its tests to speed up reconfiguring. Caching is
|
||||||
|
disabled by default to prevent problems with accidental use of stale
|
||||||
|
cache files.
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point `config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
|
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||||
|
you want to change it or regenerate `configure' using a newer version
|
||||||
|
of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system.
|
||||||
|
|
||||||
|
Running `configure' might take a while. While running, it prints
|
||||||
|
some messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package, generally using the just-built uninstalled binaries.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation. When installing into a prefix owned by root, it is
|
||||||
|
recommended that the package be configured and built as a regular
|
||||||
|
user, and only the `make install' phase executed with root
|
||||||
|
privileges.
|
||||||
|
|
||||||
|
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||||
|
this time using the binaries in their final installed location.
|
||||||
|
This target does not install anything. Running this target as a
|
||||||
|
regular user, particularly if the prior `make install' required
|
||||||
|
root privileges, verifies that the installation completed
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
6. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
7. Often, you can also type `make uninstall' to remove the installed
|
||||||
|
files again. In practice, not all packages have tested that
|
||||||
|
uninstallation works correctly, even though it is required by the
|
||||||
|
GNU Coding Standards.
|
||||||
|
|
||||||
|
8. Some packages, particularly those that use Automake, provide `make
|
||||||
|
distcheck', which can by used by developers to test that all other
|
||||||
|
targets like `make install' and `make uninstall' work correctly.
|
||||||
|
This target is generally not run by end users.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. Run `./configure --help'
|
||||||
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give `configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'. This
|
||||||
|
is known as a "VPATH" build.
|
||||||
|
|
||||||
|
With a non-GNU `make', it is safer to compile the package for one
|
||||||
|
architecture at a time in the source code directory. After you have
|
||||||
|
installed the package for one architecture, use `make distclean' before
|
||||||
|
reconfiguring for another architecture.
|
||||||
|
|
||||||
|
On MacOS X 10.5 and later systems, you can create libraries and
|
||||||
|
executables that work on multiple system types--known as "fat" or
|
||||||
|
"universal" binaries--by specifying multiple `-arch' options to the
|
||||||
|
compiler but only a single `-arch' option to the preprocessor. Like
|
||||||
|
this:
|
||||||
|
|
||||||
|
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||||
|
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||||
|
CPP="gcc -E" CXXCPP="g++ -E"
|
||||||
|
|
||||||
|
This is not guaranteed to produce working output in all cases, you
|
||||||
|
may have to build one architecture at a time and combine the results
|
||||||
|
using the `lipo' tool if you have problems.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' installs the package's commands under
|
||||||
|
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||||
|
can specify an installation prefix other than `/usr/local' by giving
|
||||||
|
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||||
|
absolute file name.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||||
|
PREFIX as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=DIR' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them. In general, the
|
||||||
|
default for these options is expressed in terms of `${prefix}', so that
|
||||||
|
specifying just `--prefix' will affect all of the other directory
|
||||||
|
specifications that were not explicitly provided.
|
||||||
|
|
||||||
|
The most portable way to affect installation locations is to pass the
|
||||||
|
correct locations to `configure'; however, many packages provide one or
|
||||||
|
both of the following shortcuts of passing variable assignments to the
|
||||||
|
`make install' command line to change installation locations without
|
||||||
|
having to reconfigure or recompile.
|
||||||
|
|
||||||
|
The first method involves providing an override variable for each
|
||||||
|
affected directory. For example, `make install
|
||||||
|
prefix=/alternate/directory' will choose an alternate location for all
|
||||||
|
directory configuration variables that were expressed in terms of
|
||||||
|
`${prefix}'. Any directories that were specified during `configure',
|
||||||
|
but not in terms of `${prefix}', must each be overridden at install
|
||||||
|
time for the entire installation to be relocated. The approach of
|
||||||
|
makefile variable overrides for each directory variable is required by
|
||||||
|
the GNU Coding Standards, and ideally causes no recompilation.
|
||||||
|
However, some platforms have known limitations with the semantics of
|
||||||
|
shared libraries that end up requiring recompilation when using this
|
||||||
|
method, particularly noticeable in packages that use GNU Libtool.
|
||||||
|
|
||||||
|
The second method involves providing the `DESTDIR' variable. For
|
||||||
|
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||||
|
`/alternate/directory' before all installation names. The approach of
|
||||||
|
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||||
|
does not work on platforms that have drive letters. On the other hand,
|
||||||
|
it does better at avoiding recompilation issues, and works well even
|
||||||
|
when some directory options were not specified in terms of `${prefix}'
|
||||||
|
at `configure' time.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Some packages offer the ability to configure how verbose the
|
||||||
|
execution of `make' will be. For these packages, running `./configure
|
||||||
|
--enable-silent-rules' sets the default to minimal output, which can be
|
||||||
|
overridden with `make V=1'; while running `./configure
|
||||||
|
--disable-silent-rules' sets the default to verbose, which can be
|
||||||
|
overridden with `make V=0'.
|
||||||
|
|
||||||
|
Particular systems
|
||||||
|
==================
|
||||||
|
|
||||||
|
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||||
|
CC is not installed, it is recommended to use the following options in
|
||||||
|
order to use an ANSI C compiler:
|
||||||
|
|
||||||
|
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||||
|
|
||||||
|
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||||
|
|
||||||
|
HP-UX `make' updates targets which have the same time stamps as
|
||||||
|
their prerequisites, which makes it generally unusable when shipped
|
||||||
|
generated files such as `configure' are involved. Use GNU `make'
|
||||||
|
instead.
|
||||||
|
|
||||||
|
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||||
|
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||||
|
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||||
|
to try
|
||||||
|
|
||||||
|
./configure CC="cc"
|
||||||
|
|
||||||
|
and if that doesn't work, try
|
||||||
|
|
||||||
|
./configure CC="cc -nodtk"
|
||||||
|
|
||||||
|
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||||
|
directory contains several dysfunctional programs; working variants of
|
||||||
|
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||||
|
in your `PATH', put it _after_ `/usr/bin'.
|
||||||
|
|
||||||
|
On Haiku, software installed for all users goes in `/boot/common',
|
||||||
|
not `/usr/local'. It is recommended to use the following options:
|
||||||
|
|
||||||
|
./configure --prefix=/boot/common
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' cannot figure out
|
||||||
|
automatically, but needs to determine by the type of machine the package
|
||||||
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
|
_same_ architectures, `configure' can figure that out, but if it prints
|
||||||
|
a message saying it cannot guess the machine type, give it the
|
||||||
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS
|
||||||
|
KERNEL-OS
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the option `--target=TYPE' to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with `--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to `configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||||
|
an Autoconf limitation. Until the limitation is lifted, you can use
|
||||||
|
this workaround:
|
||||||
|
|
||||||
|
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||||
|
|
||||||
|
`configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
`-h'
|
||||||
|
Print a summary of all of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--help=short'
|
||||||
|
`--help=recursive'
|
||||||
|
Print a summary of the options unique to this package's
|
||||||
|
`configure', and exit. The `short' variant lists options used
|
||||||
|
only in the top level, while the `recursive' variant lists options
|
||||||
|
also present in any nested packages.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
`-V'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
`--config-cache'
|
||||||
|
`-C'
|
||||||
|
Alias for `--cache-file=config.cache'.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`--prefix=DIR'
|
||||||
|
Use DIR as the installation prefix. *note Installation Names::
|
||||||
|
for more details, including other options available for fine-tuning
|
||||||
|
the installation locations.
|
||||||
|
|
||||||
|
`--no-create'
|
||||||
|
`-n'
|
||||||
|
Run the configure checks, but stop before creating any output
|
||||||
|
files.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options. Run
|
||||||
|
`configure --help' for more details.
|
||||||
52
libtirpc-1.3.1/Makefile.am
Normal file
52
libtirpc-1.3.1/Makefile.am
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
SUBDIRS = src man doc
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
noinst_HEADERS = tirpc/reentrant.h \
|
||||||
|
tirpc/getpeereid.h \
|
||||||
|
tirpc/libc_private.h \
|
||||||
|
tirpc/un-namespace.h
|
||||||
|
|
||||||
|
nobase_include_HEADERS = tirpc/netconfig.h \
|
||||||
|
tirpc/rpcsvc/crypt.x \
|
||||||
|
tirpc/rpcsvc/crypt.h \
|
||||||
|
tirpc/rpc/xdr.h \
|
||||||
|
tirpc/rpc/types.h \
|
||||||
|
tirpc/rpc/svc_soc.h \
|
||||||
|
tirpc/rpc/svc.h \
|
||||||
|
tirpc/rpc/svc_dg.h \
|
||||||
|
tirpc/rpc/svc_auth.h \
|
||||||
|
tirpc/rpc/svc_mt.h \
|
||||||
|
tirpc/rpc/rpc_msg.h \
|
||||||
|
tirpc/rpc/rpc.h \
|
||||||
|
tirpc/rpc/rpcent.h \
|
||||||
|
tirpc/rpc/rpc_com.h \
|
||||||
|
tirpc/rpc/rpcb_prot.x \
|
||||||
|
tirpc/rpc/rpcb_prot.h \
|
||||||
|
tirpc/rpc/rpcb_clnt.h \
|
||||||
|
tirpc/rpc/raw.h \
|
||||||
|
tirpc/rpc/pmap_rmt.h \
|
||||||
|
tirpc/rpc/pmap_prot.h \
|
||||||
|
tirpc/rpc/pmap_clnt.h \
|
||||||
|
tirpc/rpc/nettype.h \
|
||||||
|
tirpc/rpc/key_prot.h \
|
||||||
|
tirpc/rpc/des.h \
|
||||||
|
tirpc/rpc/des_crypt.h \
|
||||||
|
tirpc/rpc/clnt_stat.h \
|
||||||
|
tirpc/rpc/clnt_soc.h \
|
||||||
|
tirpc/rpc/clnt.h \
|
||||||
|
tirpc/rpc/auth_unix.h \
|
||||||
|
tirpc/rpc/auth_des.h \
|
||||||
|
tirpc/rpc/auth.h
|
||||||
|
|
||||||
|
if GSS
|
||||||
|
nobase_include_HEADERS += \
|
||||||
|
tirpc/rpc/rpcsec_gss.h \
|
||||||
|
tirpc/rpc/auth_gss.h \
|
||||||
|
tirpc/rpc/svc_auth_gss.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
pkgconfigdir=$(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libtirpc.pc
|
||||||
|
|
||||||
|
CLEANFILES = cscope.* *~
|
||||||
|
DISTCLEANFILES = Makefile.in libtirpc*.tar.gz
|
||||||
3
libtirpc-1.3.1/NEWS
Normal file
3
libtirpc-1.3.1/NEWS
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
New in 0.1:
|
||||||
|
* Portage from FreeBSD 5.2.1 (security part to be completed)
|
||||||
|
* Use autoconf/automake
|
||||||
44
libtirpc-1.3.1/README
Normal file
44
libtirpc-1.3.1/README
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
LIBTIRPC 0.1 FROM SUN'S TIRPCSRC 2.3 29 Aug 1994
|
||||||
|
|
||||||
|
This package contains SunLib's implementation of transport-independent
|
||||||
|
RPC (TI-RPC) documentation. This library forms a piece of the base of Open Network
|
||||||
|
Computing (ONC), and is derived directly from the Solaris 2.3 source.
|
||||||
|
|
||||||
|
TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V
|
||||||
|
Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface
|
||||||
|
(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported
|
||||||
|
by almost 70 vendors on all major operating systems. TS-RPC source code
|
||||||
|
(RPCSRC 4.0) remains available from several internet sites.
|
||||||
|
|
||||||
|
This release was a native source release, compatible for
|
||||||
|
building on Solaris 2.3. It had been ported from FreeBSD 5.2.1 to GNU/Linux
|
||||||
|
in 2004.
|
||||||
|
|
||||||
|
Applications linked with this release's librpc must link with the United
|
||||||
|
States domestic version of libcrypt in order to resolve the cbc_crypt() and
|
||||||
|
ecb_crypt() functions. These routines are used with Secure RPC however all
|
||||||
|
RPC programs that link with this release's librpc will need to link with the
|
||||||
|
domestic libcrypt.
|
||||||
|
|
||||||
|
WHAT'S NEW IN THIS RELEASE: TIRPCSRC 2.3 FROM SUN
|
||||||
|
|
||||||
|
The previous release was TIRPCSRC 2.0.
|
||||||
|
|
||||||
|
1. This release is based on Solaris 2.3. The previous release was
|
||||||
|
based on Solaris 2.0. This release contains a siginificant number of
|
||||||
|
bug fixes and other enhancements over TIRPCSRC 2.0.
|
||||||
|
|
||||||
|
2. The RPC library is thread safe for all client-side interfaces
|
||||||
|
(clnt_create, clnt_call, etc.). The server-side interfaces
|
||||||
|
(svc_create, svc_run, etc.) are not thread safe in this release. The
|
||||||
|
server-side interfaces will be made thread safe in the next release of
|
||||||
|
TIRPCSRC. Please see the manual pages for details about which
|
||||||
|
interfaces are thread safe.
|
||||||
|
|
||||||
|
3. As part of the work to make the RPC library thread-safe, rpcgen has
|
||||||
|
been enhanced to generate thread-safe RPC stubs (the -M option). Note
|
||||||
|
that this modifies the call-signature for the stub functions; the
|
||||||
|
procedure calling the RPC stub must now pass to the stub a pointer to
|
||||||
|
an allocated structure where results will be placed by the stub. See
|
||||||
|
the rpcgen manual page and the rpcgen Programming Guide for details.
|
||||||
|
|
||||||
6
libtirpc-1.3.1/THANKS
Normal file
6
libtirpc-1.3.1/THANKS
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Thanks to for
|
||||||
|
|
||||||
|
Aurelien Charbon <aurelien.charbon@bull.net> TI-RPC portage from NetBSD
|
||||||
|
|
||||||
|
BSD Communauty TI-RPC improvement from Sun implementation
|
||||||
|
|
||||||
3
libtirpc-1.3.1/TODO
Normal file
3
libtirpc-1.3.1/TODO
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
* Support of DES & other security part
|
||||||
|
* Provide tests
|
||||||
|
* rpcgen command missing
|
||||||
7
libtirpc-1.3.1/VERSION
Normal file
7
libtirpc-1.3.1/VERSION
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is used by configure to get version information
|
||||||
|
#
|
||||||
|
PKG_MAJOR=0
|
||||||
|
PKG_MINOR=1
|
||||||
|
PKG_REVISION=11
|
||||||
|
PKG_BUILD=0
|
||||||
|
|
||||||
42
libtirpc-1.3.1/autogen.sh
Normal file
42
libtirpc-1.3.1/autogen.sh
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
echo -n cleaning up .
|
||||||
|
|
||||||
|
# Clean up the generated crud
|
||||||
|
(
|
||||||
|
for FILE in compile config.guess config.sub depcomp install-sh ltmain.sh missing mkinstalldirs; do
|
||||||
|
if test -f $FILE; then
|
||||||
|
rm -f $FILE
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
)
|
||||||
|
|
||||||
|
for FILE in aclocal.m4 configure config.h.in; do
|
||||||
|
if test -f $FILE; then
|
||||||
|
rm -f $FILE
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
|
||||||
|
for DIR in autom4te.cache; do
|
||||||
|
if test -d $DIR; then
|
||||||
|
rm -rf $DIR
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
|
||||||
|
find . -type f -name 'Makefile.in' -print0 | xargs -r0 rm -f --
|
||||||
|
find . -type f -name 'Makefile' -print0 | xargs -r0 rm -f --
|
||||||
|
|
||||||
|
echo ' done'
|
||||||
|
|
||||||
|
if test x"${1}" = x"clean"; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
aclocal
|
||||||
|
libtoolize --force --copy
|
||||||
|
autoheader
|
||||||
|
automake --add-missing --copy --gnu # -Wall
|
||||||
|
autoconf # -Wall
|
||||||
12
libtirpc-1.3.1/bootstrap
Executable file
12
libtirpc-1.3.1/bootstrap
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
[ -e Makefile ] && make clean
|
||||||
|
rm -rf autom4te.cache configure Makefile stamp-h1
|
||||||
|
rm -rf src/Makefile src/.deps
|
||||||
|
rm -rf Makefile.in aclocal.m4 config.log config.h
|
||||||
|
rm -rf depcomp missing install-sh config.status
|
||||||
|
mkdir -p m4
|
||||||
|
aclocal -I m4
|
||||||
|
autoheader
|
||||||
|
libtoolize --automake --copy
|
||||||
|
automake --gnu --add-missing -c
|
||||||
|
autoconf
|
||||||
|
rm -rf autom4te.cache config.log libtool stamp-h1*
|
||||||
103
libtirpc-1.3.1/configure.ac
Normal file
103
libtirpc-1.3.1/configure.ac
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
AC_INIT(libtirpc, 1.3.1)
|
||||||
|
AM_INIT_AUTOMAKE([silent-rules])
|
||||||
|
AM_SILENT_RULES([yes])
|
||||||
|
AC_CONFIG_SRCDIR([src/auth_des.c])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# LT_VERSION_INFO="current:revision:age"
|
||||||
|
#
|
||||||
|
# From the libtool manual:
|
||||||
|
#
|
||||||
|
# 1. Start with version information of 0:0:0 for each libtool library.
|
||||||
|
# 2. Update the version information only immediately before a public
|
||||||
|
# release of your software. More frequent updates are unnecessary,
|
||||||
|
# and only guarantee that the current interface number gets larger faster.
|
||||||
|
# 3. If the library source code has changed at all since the last update,
|
||||||
|
# then increment revision (c:r:a becomes c:r+1:a).
|
||||||
|
# 4. If any interfaces have been added, removed, or changed since the last
|
||||||
|
# update, increment current, and set revision to 0.
|
||||||
|
# 5. If any interfaces have been added since the last public release,
|
||||||
|
# then increment age.
|
||||||
|
# 6. If any interfaces have been removed since the last public release,
|
||||||
|
# then set age to 0.
|
||||||
|
#
|
||||||
|
# _Never_ try to set the interface numbers so that they correspond to the
|
||||||
|
# release number of your package. This is an abuse that only fosters
|
||||||
|
# misunderstanding of the purpose of library versions.
|
||||||
|
#
|
||||||
|
# In addition to these rules, symbol versioning is now in effect. soname
|
||||||
|
# changes should be avoided.
|
||||||
|
#
|
||||||
|
LT_VERSION_INFO="3:0:0"
|
||||||
|
AC_SUBST([LT_VERSION_INFO])
|
||||||
|
|
||||||
|
AC_CHECK_HEADER([gssapi/gssapi.h], [HAVE_GSSAPI_H=yes], [HAVE_GSSAPI_H=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(gssapi,
|
||||||
|
[AC_HELP_STRING([--disable-gssapi], [Disable GSSAPI support @<:@default=no@:>@])],
|
||||||
|
[],[enable_gssapi=yes])
|
||||||
|
AM_CONDITIONAL(GSS, test "x$enable_gssapi" = xyes)
|
||||||
|
|
||||||
|
if test "x$enable_gssapi" = xyes; then
|
||||||
|
if test "x$HAVE_GSSAPI_H" = xno; then
|
||||||
|
AC_MSG_ERROR([gssapi.h not found. Use --disable-gssapi, or install GSS-API.])
|
||||||
|
fi
|
||||||
|
AC_CHECK_TOOL([KRB5_CONFIG], [krb5-config], [no])
|
||||||
|
if test "x$KRB5_CONFIG" = xno; then
|
||||||
|
AC_MSG_ERROR([krb5-config tool not found. Use --disable-gssapi, or install Kerberos.])
|
||||||
|
fi
|
||||||
|
GSSAPI_CFLAGS=`${KRB5_CONFIG} --cflags gssapi`
|
||||||
|
GSSAPI_LIBS=`${KRB5_CONFIG} --libs gssapi`
|
||||||
|
AC_SUBST([GSSAPI_CFLAGS])
|
||||||
|
AC_SUBST([GSSAPI_LIBS])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(authdes,
|
||||||
|
[AC_HELP_STRING([--enable-authdes], [Enable AUTH_DES support @<:@default=no@:>@])],
|
||||||
|
[],[enable_authdes=no])
|
||||||
|
AM_CONDITIONAL(AUTHDES, test "x$enable_authdes" = xyes)
|
||||||
|
if test "x$enable_authdes" != xno; then
|
||||||
|
AC_DEFINE(AUTHDES_SUPPORT, 1, [Define if AUTH_DES is support])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ipv6,
|
||||||
|
[AC_HELP_STRING([--disable-ipv6], [Disable IPv6 support @<:@default=no@:>@])],
|
||||||
|
[],[enable_ipv6=yes])
|
||||||
|
AM_CONDITIONAL(INET6, test "x$disable_ipv6" != xno)
|
||||||
|
if test "x$enable_ipv6" != xno; then
|
||||||
|
AC_DEFINE(INET6, 1, [Define to 1 if IPv6 is available])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(symvers,
|
||||||
|
[AC_HELP_STRING([--disable-symvers], [Disable symbol versioning @<:@default=no@:>@])],
|
||||||
|
[],[enable_symvers=yes])
|
||||||
|
AM_CONDITIONAL(SYMVERS, test "x$enable_symvers" = xyes)
|
||||||
|
|
||||||
|
AC_CANONICAL_BUILD
|
||||||
|
# Check for which host we are on and setup a few things
|
||||||
|
# specifically based on the host
|
||||||
|
case $build_os in
|
||||||
|
linux*)
|
||||||
|
# Do something specific for linux
|
||||||
|
LDFLAG_NOUNDEFINED="-Wl,--no-undefined"
|
||||||
|
AC_SUBST(LDFLAG_NOUNDEFINED)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
#Default Case
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_PREFIX_DEFAULT(/usr)
|
||||||
|
AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h locale.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h features.h gssapi/gssapi_ext.h])
|
||||||
|
AC_CHECK_LIB([pthread], [pthread_create])
|
||||||
|
AC_CHECK_FUNCS([getrpcbyname getrpcbynumber setrpcent endrpcent getrpcent])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
|
||||||
|
AC_OUTPUT(libtirpc.pc)
|
||||||
|
|
||||||
|
|
||||||
4
libtirpc-1.3.1/doc/Makefile.am
Normal file
4
libtirpc-1.3.1/doc/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
dist_sysconf_DATA = netconfig bindresvport.blacklist
|
||||||
|
|
||||||
|
CLEANFILES = cscope.* *~
|
||||||
|
DISTCLEANFILES = Makefile.in
|
||||||
14
libtirpc-1.3.1/doc/bindresvport.blacklist
Normal file
14
libtirpc-1.3.1/doc/bindresvport.blacklist
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#
|
||||||
|
# This file contains a list of port numbers between 600 and 1024,
|
||||||
|
# which should not be used by bindresvport. bindresvport is mostly
|
||||||
|
# called by RPC services. This mostly solves the problem, that a
|
||||||
|
# RPC service uses a well known port of another service.
|
||||||
|
#
|
||||||
|
623 # ASF, used by IPMI on some cards
|
||||||
|
631 # cups
|
||||||
|
636 # ldaps
|
||||||
|
664 # Secure ASF, used by IPMI on some cards
|
||||||
|
774 # rpasswd
|
||||||
|
921 # lwresd
|
||||||
|
993 # imaps
|
||||||
|
995 # pops
|
||||||
19
libtirpc-1.3.1/doc/netconfig
Normal file
19
libtirpc-1.3.1/doc/netconfig
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
# The network configuration file. This file is currently only used in
|
||||||
|
# conjunction with the TI-RPC code in the libtirpc library.
|
||||||
|
#
|
||||||
|
# Entries consist of:
|
||||||
|
#
|
||||||
|
# <network_id> <semantics> <flags> <protofamily> <protoname> \
|
||||||
|
# <device> <nametoaddr_libs>
|
||||||
|
#
|
||||||
|
# The <device> and <nametoaddr_libs> fields are always empty in this
|
||||||
|
# implementation.
|
||||||
|
#
|
||||||
|
udp tpi_clts v inet udp - -
|
||||||
|
tcp tpi_cots_ord v inet tcp - -
|
||||||
|
udp6 tpi_clts v inet6 udp - -
|
||||||
|
tcp6 tpi_cots_ord v inet6 tcp - -
|
||||||
|
rawip tpi_raw - inet - - -
|
||||||
|
local tpi_cots_ord - loopback - - -
|
||||||
|
unix tpi_cots_ord - loopback - - -
|
||||||
12
libtirpc-1.3.1/libtirpc.pc.in
Normal file
12
libtirpc-1.3.1/libtirpc.pc.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libtirpc
|
||||||
|
Description: Transport Independent RPC Library
|
||||||
|
Requires:
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Libs: -L${libdir} -ltirpc
|
||||||
|
Libs.private: -lpthread
|
||||||
|
Cflags: -I${includedir}/tirpc
|
||||||
30
libtirpc-1.3.1/man/Makefile.am
Normal file
30
libtirpc-1.3.1/man/Makefile.am
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
LOOKUP_MANS = getrpcent.3t getrpcport.3t
|
||||||
|
NETCONFIG_MANS = getnetconfig.3t getnetpath.3t
|
||||||
|
BIND_MANS = bindresvport.3t
|
||||||
|
COMPAT_MANS = des_crypt.3t rpc_soc.3t rpc_secure.3t rtime.3t
|
||||||
|
CLIENT_MANS = rpc_clnt_auth.3t rpc_clnt_calls.3t rpc_clnt_create.3t \
|
||||||
|
rpcbind.3t
|
||||||
|
SERVER_MANS = rpc_svc_calls.3t rpc_svc_create.3t rpc_svc_err.3t \
|
||||||
|
rpc_svc_reg.3t
|
||||||
|
GENERIC_MANS = rpc.3t rpc_xdr.3t
|
||||||
|
RPCSEC_MANS = rpcsec_gss.3t rpc_gss_get_error.3t \
|
||||||
|
rpc_gss_get_mechanisms.3t rpc_gss_get_mech_info.3t \
|
||||||
|
rpc_gss_get_versions.3t rpc_gss_is_installed.3t \
|
||||||
|
rpc_gss_mech_to_oid.3t rpc_gss_qop_to_num.3t \
|
||||||
|
rpc_gss_max_data_length.3t rpc_gss_seccreate.3t \
|
||||||
|
rpc_gss_set_defaults.3t rpc_gss_getcred.3t \
|
||||||
|
rpc_gss_get_principal_name.3t rpc_gss_set_callback.3t \
|
||||||
|
rpc_gss_set_svc_name.3t rpc_gss_svc_max_data_length.3t
|
||||||
|
|
||||||
|
dist_man5_MANS = netconfig.5
|
||||||
|
dist_man3_MANS = $(LOOKUP_MANS) $(NETCONFIG_MANS) \
|
||||||
|
$(BIND_MANS) $(GENERIC_MANS) $(COMPAT_MANS) \
|
||||||
|
$(CLIENT_MANS) $(SERVER_MANS)
|
||||||
|
if GSS
|
||||||
|
dist_man3_MANS += $(RPCSEC_MANS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
EXTRA_DIST = publickey.3t publickey.5 rpc.5
|
||||||
|
|
||||||
|
CLEANFILES = cscope.* *~
|
||||||
|
DISTCLEANFILES = Makefile.in
|
||||||
102
libtirpc-1.3.1/man/bindresvport.3t
Normal file
102
libtirpc-1.3.1/man/bindresvport.3t
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
|
||||||
|
.\"
|
||||||
|
.Dd November 22, 1987
|
||||||
|
.Dt BINDRESVPORT 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm bindresvport ,
|
||||||
|
.Nm bindresvport_sa
|
||||||
|
.Nd bind a socket to a privileged IP port
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In sys/types.h
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft int
|
||||||
|
.Fn bindresvport "int sd" "struct sockaddr_in *sin"
|
||||||
|
.Ft int
|
||||||
|
.Fn bindresvport_sa "int sd" "struct sockaddr *sa"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn bindresvport
|
||||||
|
and
|
||||||
|
.Fn bindresvport_sa
|
||||||
|
functions
|
||||||
|
are used to bind a socket descriptor to a privileged
|
||||||
|
.Tn IP
|
||||||
|
port, that is, a
|
||||||
|
port number in the range 0-1023.
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Fa sin
|
||||||
|
is a pointer to a
|
||||||
|
.Ft "struct sockaddr_in"
|
||||||
|
then the appropriate fields in the structure should be defined.
|
||||||
|
Note that
|
||||||
|
.Fa sin->sin_family
|
||||||
|
must be initialized to the address family of the socket, passed by
|
||||||
|
.Fa sd .
|
||||||
|
If
|
||||||
|
.Fa sin->sin_port
|
||||||
|
is
|
||||||
|
.Sq 0
|
||||||
|
then an anonymous port (in the range 600-1023) will be
|
||||||
|
chosen, and if
|
||||||
|
.Xr bind 2
|
||||||
|
is successful, the
|
||||||
|
.Fa sin->sin_port
|
||||||
|
will be updated to contain the allocated port.
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Fa sin
|
||||||
|
is the
|
||||||
|
.Dv NULL
|
||||||
|
pointer,
|
||||||
|
an anonymous port will be allocated (as above).
|
||||||
|
However, there is no way for
|
||||||
|
.Fn bindresvport
|
||||||
|
to return the allocated port in this case.
|
||||||
|
.Pp
|
||||||
|
Only root can bind to a privileged port; this call will fail for any
|
||||||
|
other users.
|
||||||
|
.Pp
|
||||||
|
Function prototype of
|
||||||
|
.Fn bindresvport
|
||||||
|
is biased to
|
||||||
|
.Dv AF_INET
|
||||||
|
socket.
|
||||||
|
The
|
||||||
|
.Fn bindresvport_sa
|
||||||
|
function
|
||||||
|
acts exactly the same, with more neutral function prototype.
|
||||||
|
Note that both functions behave exactly the same, and
|
||||||
|
both support
|
||||||
|
.Dv AF_INET6
|
||||||
|
sockets as well as
|
||||||
|
.Dv AF_INET
|
||||||
|
sockets.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
.Rv -std bindresvport
|
||||||
|
.Sh ERRORS
|
||||||
|
.Bl -tag -width Er
|
||||||
|
.It Bq Er EPFNOSUPPORT
|
||||||
|
If second argument was supplied,
|
||||||
|
and address family did not match between arguments.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn bindresvport
|
||||||
|
function
|
||||||
|
may also fail and set
|
||||||
|
.Va errno
|
||||||
|
for any of the errors specified for the calls
|
||||||
|
.Xr bind 2 ,
|
||||||
|
.Xr getsockopt 2 ,
|
||||||
|
or
|
||||||
|
.Xr setsockopt 2 .
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn bindresvport
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr bind 2 ,
|
||||||
|
.Xr getsockopt 2 ,
|
||||||
|
.Xr setsockopt 2
|
||||||
134
libtirpc-1.3.1/man/des_crypt.3t
Normal file
134
libtirpc-1.3.1/man/des_crypt.3t
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI;
|
||||||
|
.\"
|
||||||
|
.Dd October 6, 1987
|
||||||
|
.Dt DES_CRYPT 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm des_crypt , ecb_crypt , cbc_crypt , des_setparity
|
||||||
|
.Nd "fast DES encryption"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/des_crypt.h
|
||||||
|
.Ft int
|
||||||
|
.Fn ecb_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode"
|
||||||
|
.Ft int
|
||||||
|
.Fn cbc_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode" "char *ivec"
|
||||||
|
.Ft void
|
||||||
|
.Fn des_setparity "char *key"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn ecb_crypt
|
||||||
|
and
|
||||||
|
.Fn cbc_crypt
|
||||||
|
functions
|
||||||
|
implement the
|
||||||
|
.Tn NBS
|
||||||
|
.Tn DES
|
||||||
|
(Data Encryption Standard).
|
||||||
|
These routines are faster and more general purpose than
|
||||||
|
.Xr crypt 3 .
|
||||||
|
They also are able to utilize
|
||||||
|
.Tn DES
|
||||||
|
hardware if it is available.
|
||||||
|
The
|
||||||
|
.Fn ecb_crypt
|
||||||
|
function
|
||||||
|
encrypts in
|
||||||
|
.Tn ECB
|
||||||
|
(Electronic Code Book)
|
||||||
|
mode, which encrypts blocks of data independently.
|
||||||
|
The
|
||||||
|
.Fn cbc_crypt
|
||||||
|
function
|
||||||
|
encrypts in
|
||||||
|
.Tn CBC
|
||||||
|
(Cipher Block Chaining)
|
||||||
|
mode, which chains together
|
||||||
|
successive blocks.
|
||||||
|
.Tn CBC
|
||||||
|
mode protects against insertions, deletions and
|
||||||
|
substitutions of blocks.
|
||||||
|
Also, regularities in the clear text will
|
||||||
|
not appear in the cipher text.
|
||||||
|
.Pp
|
||||||
|
Here is how to use these routines.
|
||||||
|
The first argument,
|
||||||
|
.Fa key ,
|
||||||
|
is the 8-byte encryption key with parity.
|
||||||
|
To set the key's parity, which for
|
||||||
|
.Tn DES
|
||||||
|
is in the low bit of each byte, use
|
||||||
|
.Fn des_setparity .
|
||||||
|
The second argument,
|
||||||
|
.Fa data ,
|
||||||
|
contains the data to be encrypted or decrypted.
|
||||||
|
The
|
||||||
|
third argument,
|
||||||
|
.Fa datalen ,
|
||||||
|
is the length in bytes of
|
||||||
|
.Fa data ,
|
||||||
|
which must be a multiple of 8.
|
||||||
|
The fourth argument,
|
||||||
|
.Fa mode ,
|
||||||
|
is formed by
|
||||||
|
.Em OR Ns 'ing
|
||||||
|
together some things.
|
||||||
|
For the encryption direction
|
||||||
|
.Em OR
|
||||||
|
in either
|
||||||
|
.Dv DES_ENCRYPT
|
||||||
|
or
|
||||||
|
.Dv DES_DECRYPT .
|
||||||
|
For software versus hardware
|
||||||
|
encryption,
|
||||||
|
.Em OR
|
||||||
|
in either
|
||||||
|
.Dv DES_HW
|
||||||
|
or
|
||||||
|
.Dv DES_SW .
|
||||||
|
If
|
||||||
|
.Dv DES_HW
|
||||||
|
is specified, and there is no hardware, then the encryption is performed
|
||||||
|
in software and the routine returns
|
||||||
|
.Er DESERR_NOHWDEVICE .
|
||||||
|
For
|
||||||
|
.Fn cbc_crypt ,
|
||||||
|
the
|
||||||
|
.Fa ivec
|
||||||
|
argument
|
||||||
|
is the 8-byte initialization
|
||||||
|
vector for the chaining.
|
||||||
|
It is updated to the next initialization
|
||||||
|
vector upon return.
|
||||||
|
.Sh ERRORS
|
||||||
|
.Bl -tag -width [DESERR_NOHWDEVICE] -compact
|
||||||
|
.It Bq Er DESERR_NONE
|
||||||
|
No error.
|
||||||
|
.It Bq Er DESERR_NOHWDEVICE
|
||||||
|
Encryption succeeded, but done in software instead of the requested hardware.
|
||||||
|
.It Bq Er DESERR_HWERR
|
||||||
|
An error occurred in the hardware or driver.
|
||||||
|
.It Bq Er DESERR_BADPARAM
|
||||||
|
Bad argument to routine.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Given a result status
|
||||||
|
.Va stat ,
|
||||||
|
the macro
|
||||||
|
.Fn DES_FAILED stat
|
||||||
|
is false only for the first two statuses.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn ecb_crypt ,
|
||||||
|
.Fn cbc_crypt ,
|
||||||
|
and
|
||||||
|
.Fn des_setparity
|
||||||
|
functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.\" .Xr des 1 ,
|
||||||
|
.Xr crypt 3
|
||||||
|
.Sh RESTRICTIONS
|
||||||
|
These routines are not available in RPCSRC 4.0.
|
||||||
|
This information is provided to describe the
|
||||||
|
.Tn DES
|
||||||
|
interface expected by
|
||||||
|
Secure RPC.
|
||||||
220
libtirpc-1.3.1/man/getnetconfig.3t
Normal file
220
libtirpc-1.3.1/man/getnetconfig.3t
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
.\" @(#)getnetconfig.3n 1.28 93/06/02 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.Dd April 22, 2000
|
||||||
|
.Dt GETNETCONFIG 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm getnetconfig ,
|
||||||
|
.Nm setnetconfig ,
|
||||||
|
.Nm endnetconfig ,
|
||||||
|
.Nm getnetconfigent ,
|
||||||
|
.Nm freenetconfigent ,
|
||||||
|
.Nm nc_perror ,
|
||||||
|
.Nm nc_sperror
|
||||||
|
.Nd get network configuration database entry
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In netconfig.h
|
||||||
|
.Ft "struct netconfig *"
|
||||||
|
.Fn getnetconfig "void *handlep"
|
||||||
|
.Ft "void *"
|
||||||
|
.Fn setnetconfig "void"
|
||||||
|
.Ft int
|
||||||
|
.Fn endnetconfig "void *handlep"
|
||||||
|
.Ft "struct netconfig *"
|
||||||
|
.Fn getnetconfigent "const char *netid"
|
||||||
|
.Ft void
|
||||||
|
.Fn freenetconfigent "struct netconfig *netconfigp"
|
||||||
|
.Ft void
|
||||||
|
.Fn nc_perror "const char *msg"
|
||||||
|
.Ft "char *"
|
||||||
|
.Fn nc_sperror "void"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The library routines described on this page
|
||||||
|
provide the application access to
|
||||||
|
the system network configuration database,
|
||||||
|
.Pa /etc/netconfig .
|
||||||
|
The
|
||||||
|
.Fn getnetconfig
|
||||||
|
function
|
||||||
|
returns a pointer to the
|
||||||
|
current entry in the
|
||||||
|
netconfig
|
||||||
|
database, formatted as a
|
||||||
|
.Ft "struct netconfig" .
|
||||||
|
Successive calls will return successive netconfig
|
||||||
|
entries in the netconfig database.
|
||||||
|
The
|
||||||
|
.Fn getnetconfig
|
||||||
|
function
|
||||||
|
can be used to search the entire netconfig
|
||||||
|
file.
|
||||||
|
The
|
||||||
|
.Fn getnetconfig
|
||||||
|
function
|
||||||
|
returns
|
||||||
|
.Dv NULL
|
||||||
|
at the end of the file.
|
||||||
|
The
|
||||||
|
.Fa handlep
|
||||||
|
argument
|
||||||
|
is the handle obtained through
|
||||||
|
.Fn setnetconfig .
|
||||||
|
.Pp
|
||||||
|
A call to
|
||||||
|
.Fn setnetconfig
|
||||||
|
has the effect of
|
||||||
|
.Dq binding
|
||||||
|
to or
|
||||||
|
.Dq rewinding
|
||||||
|
the netconfig database.
|
||||||
|
The
|
||||||
|
.Fn setnetconfig
|
||||||
|
function
|
||||||
|
must be called before the first call to
|
||||||
|
.Fn getnetconfig
|
||||||
|
and may be called at any other time.
|
||||||
|
The
|
||||||
|
.Fn setnetconfig
|
||||||
|
function
|
||||||
|
need not be called before a call to
|
||||||
|
.Fn getnetconfigent .
|
||||||
|
The
|
||||||
|
.Fn setnetconfig
|
||||||
|
function
|
||||||
|
returns a unique handle to be used by
|
||||||
|
.Fn getnetconfig .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn endnetconfig
|
||||||
|
function
|
||||||
|
should be called when processing is complete to release resources for reuse.
|
||||||
|
The
|
||||||
|
.Fa handlep
|
||||||
|
argument
|
||||||
|
is the handle obtained through
|
||||||
|
.Fn setnetconfig .
|
||||||
|
Programmers should be aware, however, that the last call to
|
||||||
|
.Fn endnetconfig
|
||||||
|
frees all memory allocated by
|
||||||
|
.Fn getnetconfig
|
||||||
|
for the
|
||||||
|
.Ft "struct netconfig"
|
||||||
|
data structure.
|
||||||
|
The
|
||||||
|
.Fn endnetconfig
|
||||||
|
function
|
||||||
|
may not be called before
|
||||||
|
.Fn setnetconfig .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getnetconfigent
|
||||||
|
function
|
||||||
|
returns a pointer
|
||||||
|
to the netconfig structure corresponding
|
||||||
|
to
|
||||||
|
.Fa netid .
|
||||||
|
It returns
|
||||||
|
.Dv NULL
|
||||||
|
if
|
||||||
|
.Fa netid
|
||||||
|
is invalid
|
||||||
|
(that is, does not name an entry in the netconfig database).
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn freenetconfigent
|
||||||
|
function
|
||||||
|
frees the netconfig structure pointed to by
|
||||||
|
.Fa netconfigp
|
||||||
|
(previously returned by
|
||||||
|
.Fn getnetconfigent ) .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn nc_perror
|
||||||
|
function
|
||||||
|
prints a message to the standard error indicating why any of the
|
||||||
|
above routines failed.
|
||||||
|
The message is prepended with the string
|
||||||
|
.Fa msg
|
||||||
|
and a colon.
|
||||||
|
A newline character is appended at the end of the message.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn nc_sperror
|
||||||
|
function
|
||||||
|
is similar to
|
||||||
|
.Fn nc_perror
|
||||||
|
but instead of sending the message
|
||||||
|
to the standard error, will return a pointer to a string that
|
||||||
|
contains the error message.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn nc_perror
|
||||||
|
and
|
||||||
|
.Fn nc_sperror
|
||||||
|
functions
|
||||||
|
can also be used with the
|
||||||
|
.Ev NETPATH
|
||||||
|
access routines defined in
|
||||||
|
.Xr getnetpath 3 .
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The
|
||||||
|
.Fn setnetconfig
|
||||||
|
function
|
||||||
|
returns a unique handle to be used by
|
||||||
|
.Fn getnetconfig .
|
||||||
|
In the case of an error,
|
||||||
|
.Fn setnetconfig
|
||||||
|
returns
|
||||||
|
.Dv NULL
|
||||||
|
and
|
||||||
|
.Fn nc_perror
|
||||||
|
or
|
||||||
|
.Fn nc_sperror
|
||||||
|
can be used to print the reason for failure.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getnetconfig
|
||||||
|
function
|
||||||
|
returns a pointer to the current entry in the netconfig
|
||||||
|
database, formatted as a
|
||||||
|
.Ft "struct netconfig" .
|
||||||
|
The
|
||||||
|
.Fn getnetconfig
|
||||||
|
function
|
||||||
|
returns
|
||||||
|
.Dv NULL
|
||||||
|
at the end of the file, or upon failure.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn endnetconfig
|
||||||
|
function
|
||||||
|
returns 0 on success and \-1 on failure
|
||||||
|
(for example, if
|
||||||
|
.Fn setnetconfig
|
||||||
|
was not called previously).
|
||||||
|
.Pp
|
||||||
|
On success,
|
||||||
|
.Fn getnetconfigent
|
||||||
|
returns a pointer to the
|
||||||
|
.Ft "struct netconfig"
|
||||||
|
structure corresponding to
|
||||||
|
.Fa netid ;
|
||||||
|
otherwise it returns
|
||||||
|
.Dv NULL .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn nc_sperror
|
||||||
|
function
|
||||||
|
returns a pointer to a buffer which contains the error message string.
|
||||||
|
This buffer is overwritten on each call.
|
||||||
|
In multithreaded applications, this buffer is
|
||||||
|
implemented as thread-specific data.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/netconfig -compact
|
||||||
|
.It Pa /etc/netconfig
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr getnetpath 3 ,
|
||||||
|
.Xr netconfig 5
|
||||||
168
libtirpc-1.3.1/man/getnetpath.3t
Normal file
168
libtirpc-1.3.1/man/getnetpath.3t
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
.\" @(#)getnetpath.3n 1.26 93/05/07 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.Dd April 22, 2000
|
||||||
|
.Dt GETNETPATH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm getnetpath ,
|
||||||
|
.Nm setnetpath ,
|
||||||
|
.Nm endnetpath
|
||||||
|
.Nd get
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
entry corresponding to
|
||||||
|
.Ev NETPATH
|
||||||
|
component
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In netconfig.h
|
||||||
|
.Ft "struct netconfig *"
|
||||||
|
.Fn getnetpath "void *handlep"
|
||||||
|
.Ft "void *"
|
||||||
|
.Fn setnetpath "void"
|
||||||
|
.Ft int
|
||||||
|
.Fn endnetpath "void *handlep"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The routines described in this page provide the application access to the system
|
||||||
|
network configuration database,
|
||||||
|
.Pa /etc/netconfig ,
|
||||||
|
as it is
|
||||||
|
.Dq filtered
|
||||||
|
by the
|
||||||
|
.Ev NETPATH
|
||||||
|
environment variable (see
|
||||||
|
.Xr environ 7 ) .
|
||||||
|
See
|
||||||
|
.Xr getnetconfig 3
|
||||||
|
for other routines that also access the
|
||||||
|
network configuration database directly.
|
||||||
|
The
|
||||||
|
.Ev NETPATH
|
||||||
|
variable is a list of colon-separated network identifiers.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getnetpath
|
||||||
|
function
|
||||||
|
returns a pointer to the
|
||||||
|
netconfig database entry corresponding to the first valid
|
||||||
|
.Ev NETPATH
|
||||||
|
component.
|
||||||
|
The netconfig entry is formatted as a
|
||||||
|
.Ft "struct netconfig" .
|
||||||
|
On each subsequent call,
|
||||||
|
.Fn getnetpath
|
||||||
|
returns a pointer to the netconfig entry that corresponds to the next
|
||||||
|
valid
|
||||||
|
.Ev NETPATH
|
||||||
|
component.
|
||||||
|
The
|
||||||
|
.Fn getnetpath
|
||||||
|
function
|
||||||
|
can thus be used to search the netconfig database for all networks
|
||||||
|
included in the
|
||||||
|
.Ev NETPATH
|
||||||
|
variable.
|
||||||
|
When
|
||||||
|
.Ev NETPATH
|
||||||
|
has been exhausted,
|
||||||
|
.Fn getnetpath
|
||||||
|
returns
|
||||||
|
.Dv NULL .
|
||||||
|
.Pp
|
||||||
|
A call to
|
||||||
|
.Fn setnetpath
|
||||||
|
.Dq binds
|
||||||
|
to or
|
||||||
|
.Dq rewinds
|
||||||
|
.Ev NETPATH .
|
||||||
|
The
|
||||||
|
.Fn setnetpath
|
||||||
|
function
|
||||||
|
must be called before the first call to
|
||||||
|
.Fn getnetpath
|
||||||
|
and may be called at any other time.
|
||||||
|
It returns a handle that is used by
|
||||||
|
.Fn getnetpath .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getnetpath
|
||||||
|
function
|
||||||
|
silently ignores invalid
|
||||||
|
.Ev NETPATH
|
||||||
|
components.
|
||||||
|
A
|
||||||
|
.Ev NETPATH
|
||||||
|
component is invalid if there is no corresponding
|
||||||
|
entry in the netconfig database.
|
||||||
|
.Pp
|
||||||
|
If the
|
||||||
|
.Ev NETPATH
|
||||||
|
variable is unset,
|
||||||
|
.Fn getnetpath
|
||||||
|
behaves as if
|
||||||
|
.Ev NETPATH
|
||||||
|
were set to the sequence of
|
||||||
|
.Dq default
|
||||||
|
or
|
||||||
|
.Dq visible
|
||||||
|
networks in the netconfig database, in the
|
||||||
|
order in which they are listed.
|
||||||
|
.\"This proviso holds also for this
|
||||||
|
.\"whole manpage.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn endnetpath
|
||||||
|
function
|
||||||
|
may be called to
|
||||||
|
.Dq unbind
|
||||||
|
from
|
||||||
|
.Ev NETPATH
|
||||||
|
when processing is complete, releasing resources for reuse.
|
||||||
|
Programmers should be aware, however, that
|
||||||
|
.Fn endnetpath
|
||||||
|
frees all memory allocated by
|
||||||
|
.Fn getnetpath
|
||||||
|
for the struct netconfig data structure.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The
|
||||||
|
.Fn setnetpath
|
||||||
|
function
|
||||||
|
returns a handle that is used by
|
||||||
|
.Fn getnetpath .
|
||||||
|
In case of an error,
|
||||||
|
.Fn setnetpath
|
||||||
|
returns
|
||||||
|
.Dv NULL .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn endnetpath
|
||||||
|
function
|
||||||
|
returns 0 on success and \-1 on failure
|
||||||
|
(for example, if
|
||||||
|
.Fn setnetpath
|
||||||
|
was not called previously).
|
||||||
|
The
|
||||||
|
.Fn nc_perror
|
||||||
|
or
|
||||||
|
.Fn nc_sperror
|
||||||
|
function
|
||||||
|
can be used to print out the reason for failure.
|
||||||
|
See
|
||||||
|
.Xr getnetconfig 3 .
|
||||||
|
.Pp
|
||||||
|
When first called,
|
||||||
|
.Fn getnetpath
|
||||||
|
returns a pointer to the netconfig database entry corresponding to the first
|
||||||
|
valid
|
||||||
|
.Ev NETPATH
|
||||||
|
component.
|
||||||
|
When
|
||||||
|
.Ev NETPATH
|
||||||
|
has been exhausted,
|
||||||
|
.Fn getnetpath
|
||||||
|
returns
|
||||||
|
.Dv NULL .
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr getnetconfig 3 ,
|
||||||
|
.Xr netconfig 5 ,
|
||||||
|
.Xr environ 7
|
||||||
105
libtirpc-1.3.1/man/getrpcent.3t
Normal file
105
libtirpc-1.3.1/man/getrpcent.3t
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
|
||||||
|
.\"
|
||||||
|
.Dd December 14, 1987
|
||||||
|
.Dt GETRPCENT 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm getrpcent ,
|
||||||
|
.Nm getrpcbyname ,
|
||||||
|
.Nm getrpcbynumber ,
|
||||||
|
.Nm endrpcent ,
|
||||||
|
.Nm setrpcent
|
||||||
|
.Nd get RPC entry
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft struct rpcent *
|
||||||
|
.Fn getrpcent void
|
||||||
|
.Ft struct rpcent *
|
||||||
|
.Fn getrpcbyname "char *name"
|
||||||
|
.Ft struct rpcent *
|
||||||
|
.Fn getrpcbynumber "int number"
|
||||||
|
.Ft void
|
||||||
|
.Fn setrpcent "int stayopen"
|
||||||
|
.Ft void
|
||||||
|
.Fn endrpcent void
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn getrpcent ,
|
||||||
|
.Fn getrpcbyname ,
|
||||||
|
and
|
||||||
|
.Fn getrpcbynumber
|
||||||
|
functions
|
||||||
|
each return a pointer to an object with the
|
||||||
|
following structure
|
||||||
|
containing the broken-out
|
||||||
|
fields of a line in the rpc program number data base,
|
||||||
|
.Pa /etc/rpc :
|
||||||
|
.Bd -literal
|
||||||
|
struct rpcent {
|
||||||
|
char *r_name; /* name of server for this rpc program */
|
||||||
|
char **r_aliases; /* alias list */
|
||||||
|
long r_number; /* rpc program number */
|
||||||
|
};
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The members of this structure are:
|
||||||
|
.Bl -tag -width r_aliases -offset indent
|
||||||
|
.It Va r_name
|
||||||
|
The name of the server for this rpc program.
|
||||||
|
.It Va r_aliases
|
||||||
|
A zero terminated list of alternate names for the rpc program.
|
||||||
|
.It Va r_number
|
||||||
|
The rpc program number for this service.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getrpcent
|
||||||
|
function
|
||||||
|
reads the next line of the file, opening the file if necessary.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn setrpcent
|
||||||
|
function
|
||||||
|
opens and rewinds the file. If the
|
||||||
|
.Fa stayopen
|
||||||
|
flag is non-zero,
|
||||||
|
the net data base will not be closed after each call to
|
||||||
|
.Fn getrpcent
|
||||||
|
(either directly, or indirectly through one of
|
||||||
|
the other
|
||||||
|
.Dq getrpc
|
||||||
|
calls).
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn endrpcent
|
||||||
|
function
|
||||||
|
closes the file.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getrpcbyname
|
||||||
|
and
|
||||||
|
.Fn getrpcbynumber
|
||||||
|
functions
|
||||||
|
sequentially search from the beginning
|
||||||
|
of the file until a matching rpc program name or
|
||||||
|
program number is found, or until end-of-file is encountered.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/rpc -compact
|
||||||
|
.It Pa /etc/rpc
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 5 ,
|
||||||
|
.Xr rpcinfo 8
|
||||||
|
.Sh DIAGNOSTICS
|
||||||
|
A
|
||||||
|
.Dv NULL
|
||||||
|
pointer is returned on
|
||||||
|
.Dv EOF
|
||||||
|
or error.
|
||||||
|
.Sh BUGS
|
||||||
|
All information
|
||||||
|
is contained in a static area
|
||||||
|
so it must be copied if it is
|
||||||
|
to be saved.
|
||||||
36
libtirpc-1.3.1/man/getrpcport.3t
Normal file
36
libtirpc-1.3.1/man/getrpcport.3t
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
|
||||||
|
.\"
|
||||||
|
.Dd October 6, 1987
|
||||||
|
.Dt GETRPCPORT 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm getrpcport
|
||||||
|
.Nd get RPC port number
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Ft int
|
||||||
|
.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn getrpcport
|
||||||
|
function
|
||||||
|
returns the port number for version
|
||||||
|
.Fa versnum
|
||||||
|
of the RPC program
|
||||||
|
.Fa prognum
|
||||||
|
running on
|
||||||
|
.Fa host
|
||||||
|
and using protocol
|
||||||
|
.Fa proto .
|
||||||
|
It returns 0 if it cannot contact the portmapper, or if
|
||||||
|
.Fa prognum
|
||||||
|
is not registered. If
|
||||||
|
.Fa prognum
|
||||||
|
is registered but not with version
|
||||||
|
.Fa versnum ,
|
||||||
|
it will still return a port number (for some version of the program)
|
||||||
|
indicating that the program is indeed registered.
|
||||||
|
The version mismatch will be detected upon the first call to the service.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn getrpcport
|
||||||
|
function is part of libtirpc.
|
||||||
123
libtirpc-1.3.1/man/netconfig.5
Normal file
123
libtirpc-1.3.1/man/netconfig.5
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
.Dd November 17, 2000
|
||||||
|
.Dt NETCONFIG 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm netconfig
|
||||||
|
.Nd network configuration data base
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file defines a list of
|
||||||
|
.Dq transport names ,
|
||||||
|
describing their semantics and protocol.
|
||||||
|
In
|
||||||
|
.Fx ,
|
||||||
|
this file is only used by the RPC library code.
|
||||||
|
.Pp
|
||||||
|
Entries have the following format:
|
||||||
|
.Pp
|
||||||
|
.Ar network_id semantics flags family protoname device libraries
|
||||||
|
.Pp
|
||||||
|
Entries consist of the following fields:
|
||||||
|
.Bl -tag -width network_id
|
||||||
|
.It Ar network_id
|
||||||
|
The name of the transport described.
|
||||||
|
.It Ar semantics
|
||||||
|
Describes the semantics of the transport.
|
||||||
|
This can be one of:
|
||||||
|
.Bl -tag -width tpi_cots_ord -offset indent
|
||||||
|
.It Sy tpi_clts
|
||||||
|
Connectionless transport.
|
||||||
|
.It Sy tpi_cots
|
||||||
|
Connection-oriented transport
|
||||||
|
.It Sy tpi_cots_ord
|
||||||
|
Connection-oriented, ordered transport.
|
||||||
|
.It Sy tpi_raw
|
||||||
|
A raw connection.
|
||||||
|
.El
|
||||||
|
.It Ar flags
|
||||||
|
This field is either blank (specified by
|
||||||
|
.Dq Li - ) ,
|
||||||
|
or contains a
|
||||||
|
.Dq Li v ,
|
||||||
|
meaning visible to the
|
||||||
|
.Xr getnetconfig 3
|
||||||
|
function.
|
||||||
|
.It Ar family
|
||||||
|
The protocol family of the transport.
|
||||||
|
This is currently one of:
|
||||||
|
.Bl -tag -width loopback -offset indent
|
||||||
|
.It Sy inet6
|
||||||
|
The IPv6
|
||||||
|
.Pq Dv PF_INET6
|
||||||
|
family of protocols.
|
||||||
|
.It Sy inet
|
||||||
|
The IPv4
|
||||||
|
.Pq Dv PF_INET
|
||||||
|
family of protocols.
|
||||||
|
.It Sy loopback
|
||||||
|
The
|
||||||
|
.Dv PF_LOCAL
|
||||||
|
protocol family.
|
||||||
|
.El
|
||||||
|
.It Ar protoname
|
||||||
|
The name of the protocol used for this transport.
|
||||||
|
Can currently be either
|
||||||
|
.Sy udp ,
|
||||||
|
.Sy tcp
|
||||||
|
or empty.
|
||||||
|
.It Ar device
|
||||||
|
This field is always empty in
|
||||||
|
.Fx .
|
||||||
|
.It Ar libraries
|
||||||
|
This field is always empty in
|
||||||
|
.Fx .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The order of entries in this file will determine which transport will
|
||||||
|
be preferred by the RPC library code, given a match on a specified
|
||||||
|
network type.
|
||||||
|
For example, if a sample network config file would look like this:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
udp6 tpi_clts v inet6 udp - -
|
||||||
|
tcp6 tpi_cots_ord v inet6 tcp - -
|
||||||
|
udp tpi_clts v inet udp - -
|
||||||
|
tcp tpi_cots_ord v inet tcp - -
|
||||||
|
rawip tpi_raw - inet - - -
|
||||||
|
local tpi_cots_ord - loopback - - -
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
then using the network type
|
||||||
|
.Sy udp
|
||||||
|
in calls to the RPC library function (see
|
||||||
|
.Xr rpc 3 )
|
||||||
|
will make the code first try
|
||||||
|
.Sy udp6 ,
|
||||||
|
and then
|
||||||
|
.Sy udp .
|
||||||
|
.Pp
|
||||||
|
.Xr getnetconfig 3
|
||||||
|
and associated functions will parse this file and return structures of
|
||||||
|
the following format:
|
||||||
|
.Bd -literal
|
||||||
|
struct netconfig {
|
||||||
|
char *nc_netid; /* Network ID */
|
||||||
|
unsigned long nc_semantics; /* Semantics (see below) */
|
||||||
|
unsigned long nc_flag; /* Flags (see below) */
|
||||||
|
char *nc_protofmly; /* Protocol family */
|
||||||
|
char *nc_proto; /* Protocol name */
|
||||||
|
char *nc_device; /* Network device pathname (unused) */
|
||||||
|
unsigned long nc_nlookups; /* Number of lookup libs (unused) */
|
||||||
|
char **nc_lookups; /* Names of the libraries (unused) */
|
||||||
|
unsigned long nc_unused[9]; /* reserved */
|
||||||
|
};
|
||||||
|
.Ed
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/netconfig -compact
|
||||||
|
.It Pa /etc/netconfig
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr getnetconfig 3 ,
|
||||||
|
.Xr getnetpath 3
|
||||||
52
libtirpc-1.3.1/man/publickey.3t
Normal file
52
libtirpc-1.3.1/man/publickey.3t
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC
|
||||||
|
.\"
|
||||||
|
.Dd October 6, 1987
|
||||||
|
.Dt PUBLICKEY 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm publickey , getpublickey , getsecretkey
|
||||||
|
.Nd "get public or secret key"
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb librpcsvc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.In rpc/key_prot.h
|
||||||
|
.Ft int
|
||||||
|
.Fo getpublickey
|
||||||
|
.Fa "char netname[MAXNETNAMELEN+1]"
|
||||||
|
.Fa "char publickey[HEXKEYBYTES+1]"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fo getsecretkey
|
||||||
|
.Fa "char netname[MAXNETNAMELEN+1]"
|
||||||
|
.Fa "char secretkey[HEXKEYBYTES+1]"
|
||||||
|
.Fa "char *passwd"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are used to get public and secret keys from the
|
||||||
|
.Tn YP
|
||||||
|
database.
|
||||||
|
The
|
||||||
|
.Fn getsecretkey
|
||||||
|
function
|
||||||
|
has an extra argument,
|
||||||
|
.Fa passwd ,
|
||||||
|
which is used to decrypt the encrypted secret key stored in the database.
|
||||||
|
Both routines return 1 if they are successful in finding the key, 0 otherwise.
|
||||||
|
The keys are returned as
|
||||||
|
.Dv NULL Ns \-terminated ,
|
||||||
|
hexadecimal strings.
|
||||||
|
If the password supplied to
|
||||||
|
.Fn getsecretkey
|
||||||
|
fails to decrypt the secret key, the routine will return 1 but the
|
||||||
|
.Fa secretkey
|
||||||
|
argument will be a
|
||||||
|
.Dv NULL
|
||||||
|
string
|
||||||
|
.Pq Dq .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr publickey 5
|
||||||
|
.Pp
|
||||||
|
.%T "RPC Programmer's Manual"
|
||||||
|
in
|
||||||
|
.Pa /usr/share/doc/psd/23.rpc .
|
||||||
41
libtirpc-1.3.1/man/publickey.5
Normal file
41
libtirpc-1.3.1/man/publickey.5
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI;
|
||||||
|
.Dd October 19, 1987
|
||||||
|
.Dt PUBLICKEY 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm publickey
|
||||||
|
.Nd "public key database"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Pa /etc/publickey
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Pa /etc/publickey
|
||||||
|
is the public key database used for secure
|
||||||
|
RPC (Remote Procedure Calls).
|
||||||
|
Each entry in
|
||||||
|
the database consists of a network user
|
||||||
|
name (which may either refer to
|
||||||
|
a user or a hostname), followed by the user's
|
||||||
|
public key (in hex
|
||||||
|
notation), a colon, and then the user's
|
||||||
|
secret key encrypted with
|
||||||
|
its login password (also in hex notation).
|
||||||
|
.Pp
|
||||||
|
This file is altered either by the user through the
|
||||||
|
.Xr chkey 1
|
||||||
|
command or by the system administrator through the
|
||||||
|
.Xr newkey 8
|
||||||
|
command.
|
||||||
|
The file
|
||||||
|
.Pa /etc/publickey
|
||||||
|
should only contain data on the
|
||||||
|
.Tn NIS
|
||||||
|
master machine, where it
|
||||||
|
is converted into the
|
||||||
|
.Tn NIS
|
||||||
|
database
|
||||||
|
.Pa publickey.byname .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr chkey 1 ,
|
||||||
|
.Xr publickey 3 ,
|
||||||
|
.Xr newkey 8 ,
|
||||||
|
.Xr ypupdated 8
|
||||||
515
libtirpc-1.3.1/man/rpc.3t
Normal file
515
libtirpc-1.3.1/man/rpc.3t
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
.\" @(#)rpc.3n 1.31 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.Dd May 7, 1993
|
||||||
|
.Dt RPC 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc
|
||||||
|
.Nd library routines for remote procedure calls
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.In netconfig.h
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These
|
||||||
|
routines allow C language programs to make procedure
|
||||||
|
calls on other machines across a network.
|
||||||
|
First, the client sends a request to the server.
|
||||||
|
On receipt of the request, the server calls a dispatch routine
|
||||||
|
to perform the requested service, and then sends back a reply.
|
||||||
|
.Pp
|
||||||
|
All
|
||||||
|
RPC routines require the header
|
||||||
|
.In rpc/rpc.h .
|
||||||
|
Routines that take a
|
||||||
|
.Vt "struct netconfig"
|
||||||
|
also require that
|
||||||
|
.In netconfig.h
|
||||||
|
be included.
|
||||||
|
.Sh Nettype
|
||||||
|
Some of the high-level
|
||||||
|
RPC interface routines take a
|
||||||
|
.Fa nettype
|
||||||
|
string as one of the arguments
|
||||||
|
(for example,
|
||||||
|
.Fn clnt_create ,
|
||||||
|
.Fn svc_create ,
|
||||||
|
.Fn rpc_reg ,
|
||||||
|
.Fn rpc_call ) .
|
||||||
|
This string defines a class of transports which can be used
|
||||||
|
for a particular application.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fa nettype
|
||||||
|
argument
|
||||||
|
can be one of the following:
|
||||||
|
.Bl -tag -width datagram_v
|
||||||
|
.It netpath
|
||||||
|
Choose from the transports which have been
|
||||||
|
indicated by their token names in the
|
||||||
|
.Ev NETPATH
|
||||||
|
environment variable.
|
||||||
|
.Ev NETPATH
|
||||||
|
is unset or
|
||||||
|
.Dv NULL ,
|
||||||
|
it defaults to
|
||||||
|
.Qq visible .
|
||||||
|
.Qq netpath
|
||||||
|
is the default
|
||||||
|
.Fa nettype .
|
||||||
|
.It visible
|
||||||
|
Choose the transports which have the visible flag (v)
|
||||||
|
set in the
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
file.
|
||||||
|
.It circuit_v
|
||||||
|
This is same as
|
||||||
|
.Qq visible
|
||||||
|
except that it chooses only the connection oriented transports
|
||||||
|
(semantics
|
||||||
|
.Qq tpi_cots
|
||||||
|
or
|
||||||
|
.Qq tpi_cots_ord )
|
||||||
|
from the entries in the
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
file.
|
||||||
|
.It datagram_v
|
||||||
|
This is same as
|
||||||
|
.Qq visible
|
||||||
|
except that it chooses only the connectionless datagram transports
|
||||||
|
(semantics
|
||||||
|
.Qq tpi_clts )
|
||||||
|
from the entries in the
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
file.
|
||||||
|
.It circuit_n
|
||||||
|
This is same as
|
||||||
|
.Qq netpath
|
||||||
|
except that it chooses only the connection oriented datagram transports
|
||||||
|
(semantics
|
||||||
|
.Qq tpi_cots
|
||||||
|
or
|
||||||
|
.Qq tpi_cots_ord ) .
|
||||||
|
.It datagram_n
|
||||||
|
This is same as
|
||||||
|
.Qq netpath
|
||||||
|
except that it chooses only the connectionless datagram transports
|
||||||
|
(semantics
|
||||||
|
.Qq tpi_clts ) .
|
||||||
|
.It udp
|
||||||
|
This refers to Internet UDP, both version 4 and 6.
|
||||||
|
.It tcp
|
||||||
|
This refers to Internet TCP, both version 4 and 6.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Fa nettype
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
it defaults to
|
||||||
|
.Qq netpath .
|
||||||
|
The transports are tried in left to right order in the
|
||||||
|
.Ev NETPATH
|
||||||
|
variable or in top to down order in the
|
||||||
|
.Pa /etc/netconfig
|
||||||
|
file.
|
||||||
|
.Sh Derived Types
|
||||||
|
The derived types used in the RPC interfaces are defined as follows:
|
||||||
|
.Bd -literal
|
||||||
|
typedef u_int32_t rpcprog_t;
|
||||||
|
typedef u_int32_t rpcvers_t;
|
||||||
|
typedef u_int32_t rpcproc_t;
|
||||||
|
typedef u_int32_t rpcprot_t;
|
||||||
|
typedef u_int32_t rpcport_t;
|
||||||
|
typedef int32_t rpc_inline_t;
|
||||||
|
.Ed
|
||||||
|
.Sh "Data Structures"
|
||||||
|
Some of the data structures used by the
|
||||||
|
RPC package are shown below.
|
||||||
|
.Sh "The AUTH Structure"
|
||||||
|
.Bd -literal
|
||||||
|
/*
|
||||||
|
* Authentication info. Opaque to client.
|
||||||
|
*/
|
||||||
|
struct opaque_auth {
|
||||||
|
enum_t oa_flavor; /* flavor of auth */
|
||||||
|
caddr_t oa_base; /* address of more auth stuff */
|
||||||
|
u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auth handle, interface to client side authenticators.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
struct opaque_auth ah_cred;
|
||||||
|
struct opaque_auth ah_verf;
|
||||||
|
struct auth_ops {
|
||||||
|
void (*ah_nextverf)(\|);
|
||||||
|
int (*ah_marshal)(\|); /* nextverf & serialize */
|
||||||
|
int (*ah_validate)(\|); /* validate verifier */
|
||||||
|
int (*ah_refresh)(\|); /* refresh credentials */
|
||||||
|
void (*ah_destroy)(\|); /* destroy this structure */
|
||||||
|
} *ah_ops;
|
||||||
|
caddr_t ah_private;
|
||||||
|
} AUTH;
|
||||||
|
.Ed
|
||||||
|
.Sh "The CLIENT Structure"
|
||||||
|
.Bd -literal
|
||||||
|
/*
|
||||||
|
* Client rpc handle.
|
||||||
|
* Created by individual implementations.
|
||||||
|
* Client is responsible for initializing auth.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
AUTH *cl_auth; /* authenticator */
|
||||||
|
struct clnt_ops {
|
||||||
|
enum clnt_stat (*cl_call)(); /* call remote procedure */
|
||||||
|
void (*cl_abort)(); /* abort a call */
|
||||||
|
void (*cl_geterr)(); /* get specific error code */
|
||||||
|
bool_t (*cl_freeres)(); /* frees results */
|
||||||
|
void (*cl_destroy)(); /* destroy this structure */
|
||||||
|
bool_t (*cl_control)(); /* the ioctl() of rpc */
|
||||||
|
} *cl_ops;
|
||||||
|
caddr_t cl_private; /* private stuff */
|
||||||
|
char *cl_netid; /* network identifier */
|
||||||
|
char *cl_tp; /* device name */
|
||||||
|
} CLIENT;
|
||||||
|
.Ed
|
||||||
|
.Sh "The SVCXPRT structure"
|
||||||
|
.Bd -literal
|
||||||
|
enum xprt_stat {
|
||||||
|
XPRT_DIED,
|
||||||
|
XPRT_MOREREQS,
|
||||||
|
XPRT_IDLE
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Server side transport handle
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int xp_fd; /* file descriptor for the server handle */
|
||||||
|
u_short xp_port; /* obsolete */
|
||||||
|
const struct xp_ops {
|
||||||
|
bool_t (*xp_recv)(); /* receive incoming requests */
|
||||||
|
enum xprt_stat (*xp_stat)(); /* get transport status */
|
||||||
|
bool_t (*xp_getargs)(); /* get arguments */
|
||||||
|
bool_t (*xp_reply)(); /* send reply */
|
||||||
|
bool_t (*xp_freeargs)(); /* free mem allocated for args */
|
||||||
|
void (*xp_destroy)(); /* destroy this struct */
|
||||||
|
} *xp_ops;
|
||||||
|
int xp_addrlen; /* length of remote addr. Obsolete */
|
||||||
|
struct sockaddr_in xp_raddr; /* Obsolete */
|
||||||
|
const struct xp_ops2 {
|
||||||
|
bool_t (*xp_control)(); /* catch-all function */
|
||||||
|
} *xp_ops2;
|
||||||
|
char *xp_tp; /* transport provider device name */
|
||||||
|
char *xp_netid; /* network identifier */
|
||||||
|
struct netbuf xp_ltaddr; /* local transport address */
|
||||||
|
struct netbuf xp_rtaddr; /* remote transport address */
|
||||||
|
struct opaque_auth xp_verf; /* raw response verifier */
|
||||||
|
caddr_t xp_p1; /* private: for use by svc ops */
|
||||||
|
caddr_t xp_p2; /* private: for use by svc ops */
|
||||||
|
caddr_t xp_p3; /* private: for use by svc lib */
|
||||||
|
int xp_type /* transport type */
|
||||||
|
} SVCXPRT;
|
||||||
|
.Ed
|
||||||
|
.Sh "The svc_reg structure"
|
||||||
|
.Bd -literal
|
||||||
|
struct svc_req {
|
||||||
|
rpcprog_t rq_prog; /* service program number */
|
||||||
|
rpcvers_t rq_vers; /* service protocol version */
|
||||||
|
rpcproc_t rq_proc; /* the desired procedure */
|
||||||
|
struct opaque_auth rq_cred; /* raw creds from the wire */
|
||||||
|
caddr_t rq_clntcred; /* read only cooked cred */
|
||||||
|
SVCXPRT *rq_xprt; /* associated transport */
|
||||||
|
};
|
||||||
|
.Ed
|
||||||
|
.Sh "The XDR structure"
|
||||||
|
.Bd -literal
|
||||||
|
/*
|
||||||
|
* XDR operations.
|
||||||
|
* XDR_ENCODE causes the type to be encoded into the stream.
|
||||||
|
* XDR_DECODE causes the type to be extracted from the stream.
|
||||||
|
* XDR_FREE can be used to release the space allocated by an XDR_DECODE
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
enum xdr_op {
|
||||||
|
XDR_ENCODE=0,
|
||||||
|
XDR_DECODE=1,
|
||||||
|
XDR_FREE=2
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* This is the number of bytes per unit of external data.
|
||||||
|
*/
|
||||||
|
#define BYTES_PER_XDR_UNIT (4)
|
||||||
|
#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) /
|
||||||
|
BYTES_PER_XDR_UNIT) \e * BYTES_PER_XDR_UNIT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A xdrproc_t exists for each data type which is to be encoded or
|
||||||
|
* decoded. The second argument to the xdrproc_t is a pointer to
|
||||||
|
* an opaque pointer. The opaque pointer generally points to a
|
||||||
|
* structure of the data type to be decoded. If this points to 0,
|
||||||
|
* then the type routines should allocate dynamic storage of the
|
||||||
|
* appropriate size and return it.
|
||||||
|
* bool_t (*xdrproc_t)(XDR *, caddr_t *);
|
||||||
|
*/
|
||||||
|
typedef bool_t (*xdrproc_t)();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The XDR handle.
|
||||||
|
* Contains operation which is being applied to the stream,
|
||||||
|
* an operations vector for the particular implementation
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
enum xdr_op x_op; /* operation; fast additional param */
|
||||||
|
struct xdr_ops {
|
||||||
|
bool_t (*x_getlong)(); /* get a long from underlying stream */
|
||||||
|
bool_t (*x_putlong)(); /* put a long to underlying stream */
|
||||||
|
bool_t (*x_getbytes)(); /* get bytes from underlying stream */
|
||||||
|
bool_t (*x_putbytes)(); /* put bytes to underlying stream */
|
||||||
|
u_int (*x_getpostn)(); /* returns bytes off from beginning */
|
||||||
|
bool_t (*x_setpostn)(); /* lets you reposition the stream */
|
||||||
|
long * (*x_inline)(); /* buf quick ptr to buffered data */
|
||||||
|
void (*x_destroy)(); /* free privates of this xdr_stream */
|
||||||
|
} *x_ops;
|
||||||
|
caddr_t x_public; /* users' data */
|
||||||
|
caddr_t x_private; /* pointer to private data */
|
||||||
|
caddr_t x_base; /* private used for position info */
|
||||||
|
u_int x_handy; /* extra private word */
|
||||||
|
} XDR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The netbuf structure. This structure is defined in <xti.h> on SysV
|
||||||
|
* systems, but NetBSD / FreeBSD do not use XTI.
|
||||||
|
*
|
||||||
|
* Usually, buf will point to a struct sockaddr, and len and maxlen
|
||||||
|
* will contain the length and maximum length of that socket address,
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
struct netbuf {
|
||||||
|
unsigned int maxlen;
|
||||||
|
unsigned int len;
|
||||||
|
void *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The format of the address and options arguments of the XTI t_bind call.
|
||||||
|
* Only provided for compatibility, it should not be used other than
|
||||||
|
* as an argument to svc_tli_create().
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct t_bind {
|
||||||
|
struct netbuf addr;
|
||||||
|
unsigned int qlen;
|
||||||
|
};
|
||||||
|
.Ed
|
||||||
|
.Sh "Index to Routines"
|
||||||
|
The following table lists RPC routines and the manual reference
|
||||||
|
pages on which they are described:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width "authunix_create_default()" -compact
|
||||||
|
.It Em "RPC Routine"
|
||||||
|
.Em "Manual Reference Page"
|
||||||
|
.Pp
|
||||||
|
.It Fn auth_destroy
|
||||||
|
.Xr rpc_clnt_auth 3
|
||||||
|
.It Fn authdes_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn authnone_create
|
||||||
|
.Xr rpc_clnt_auth 3
|
||||||
|
.It Fn authsys_create
|
||||||
|
.Xr rpc_clnt_auth 3
|
||||||
|
.It Fn authsys_create_default
|
||||||
|
.Xr rpc_clnt_auth 3
|
||||||
|
.It Fn authunix_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn authunix_create_default
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn callrpc
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn clnt_broadcast
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn clnt_call
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_control
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_create_timed
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_create_vers
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_create_vers_timed
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_destroy
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_dg_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_freeres
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_geterr
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_pcreateerror
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_perrno
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_perror
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_raw_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_spcreateerror
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_sperrno
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_sperror
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn clnt_tli_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_tp_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_tp_create_timed
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clnt_udpcreate
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn clnt_vc_create
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
|
.It Fn clntraw_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn clnttcp_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn clntudp_bufcreate
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn get_myaddress
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn pmap_getmaps
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn pmap_getport
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn pmap_rmtcall
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn pmap_set
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn pmap_unset
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn registerrpc
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn rpc_broadcast
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn rpc_broadcast_exp
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn rpc_call
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
.It Fn rpc_reg
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_destroy
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_dg_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_dg_enablecache
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_fd_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_fds
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svc_freeargs
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
|
.It Fn svc_getargs
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
|
.It Fn svc_getcaller
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svc_getreq
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svc_getreqset
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_getrpccaller
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_kerb_reg
|
||||||
|
.Xr kerberos_rpc 3
|
||||||
|
.It Fn svc_raw_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_reg
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_register
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svc_run
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
|
.It Fn svc_sendreply
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
|
.It Fn svc_tli_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_tp_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svc_unreg
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn svc_unregister
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svc_vc_create
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
.It Fn svcerr_auth
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_decode
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_noproc
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_noprog
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_progvers
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_systemerr
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcerr_weakauth
|
||||||
|
.Xr rpc_svc_err 3
|
||||||
|
.It Fn svcfd_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svcraw_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svctcp_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svcudp_bufcreate
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn svcudp_create
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn xdr_accepted_reply
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_authsys_parms
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_authunix_parms
|
||||||
|
.Xr rpc_soc 3
|
||||||
|
.It Fn xdr_callhdr
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_callmsg
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_opaque_auth
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_rejected_reply
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xdr_replymsg
|
||||||
|
.Xr rpc_xdr 3
|
||||||
|
.It Fn xprt_register
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.It Fn xprt_unregister
|
||||||
|
.Xr rpc_svc_calls 3
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/netconfig
|
||||||
|
.It Pa /etc/netconfig
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr getnetconfig 3 ,
|
||||||
|
.Xr getnetpath 3 ,
|
||||||
|
.Xr rpcbind 3 ,
|
||||||
|
.Xr rpc_clnt_auth 3 ,
|
||||||
|
.Xr rpc_clnt_calls 3 ,
|
||||||
|
.Xr rpc_clnt_create 3 ,
|
||||||
|
.Xr rpc_svc_calls 3 ,
|
||||||
|
.Xr rpc_svc_create 3 ,
|
||||||
|
.Xr rpc_svc_err 3 ,
|
||||||
|
.Xr rpc_svc_reg 3 ,
|
||||||
|
.Xr rpc_xdr 3 ,
|
||||||
|
.Xr xdr 3 ,
|
||||||
|
.Xr netconfig 5
|
||||||
57
libtirpc-1.3.1/man/rpc.5
Normal file
57
libtirpc-1.3.1/man/rpc.5
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
.\" @(#)rpc.4 1.17 93/08/30 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.Dd December 10, 1991
|
||||||
|
.Dt RPC 5
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc
|
||||||
|
.Nd rpc program number data base
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Pa /etc/rpc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file contains user readable names that
|
||||||
|
can be used in place of RPC program numbers.
|
||||||
|
For each RPC program a single line should be present
|
||||||
|
with the following information:
|
||||||
|
.Pp
|
||||||
|
.Bl -enum -compact
|
||||||
|
.It
|
||||||
|
name of the RPC program
|
||||||
|
.It
|
||||||
|
RPC program number
|
||||||
|
.It
|
||||||
|
aliases
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Items are separated by any number of blanks and/or
|
||||||
|
tab characters.
|
||||||
|
A hash
|
||||||
|
.Pq Dq Li #
|
||||||
|
indicates the beginning of a comment; characters up to the end of
|
||||||
|
the line are not interpreted by routines which search the file.
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Below is an example of an RPC database:
|
||||||
|
.Bd -literal
|
||||||
|
#
|
||||||
|
# rpc
|
||||||
|
#
|
||||||
|
rpcbind 100000 portmap sunrpc portmapper
|
||||||
|
rusersd 100002 rusers
|
||||||
|
nfs 100003 nfsprog
|
||||||
|
mountd 100005 mount showmount
|
||||||
|
walld 100008 rwall shutdown
|
||||||
|
sprayd 100012 spray
|
||||||
|
llockmgr 100020
|
||||||
|
nlockmgr 100021
|
||||||
|
status 100024
|
||||||
|
bootparam 100026
|
||||||
|
keyserv 100029 keyserver
|
||||||
|
.Ed
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width /etc/nsswitch.conf -compact
|
||||||
|
.It Pa /etc/nsswitch.conf
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr getrpcent 3
|
||||||
96
libtirpc-1.3.1/man/rpc_clnt_auth.3t
Normal file
96
libtirpc-1.3.1/man/rpc_clnt_auth.3t
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
.\" @(#)rpc_clnt_auth.3n 1.21 93/05/07 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_clnt_auth 1.4 89/07/20 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $NetBSD: rpc_clnt_auth.3,v 1.1 2000/06/03 09:29:50 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_clnt_auth.3,v 1.5 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.Dd May 7, 1993
|
||||||
|
.Dt RPC_CLNT_AUTH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm auth_destroy ,
|
||||||
|
.Nm authnone_create ,
|
||||||
|
.Nm authsys_create ,
|
||||||
|
.Nm authsys_create_default
|
||||||
|
.Nd library routines for client side remote procedure call authentication
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft "void"
|
||||||
|
.Fn auth_destroy "AUTH *auth"
|
||||||
|
.Ft "AUTH *"
|
||||||
|
.Fn authnone_create "void"
|
||||||
|
.Ft "AUTH *"
|
||||||
|
.Fn authsys_create "const char *host" "const uid_t uid" "const gid_t gid" "const int len" "const gid_t *aup_gids"
|
||||||
|
.Ft "AUTH *"
|
||||||
|
.Fn authsys_create_default "void"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are part of the
|
||||||
|
RPC library that allows C language programs to make procedure
|
||||||
|
calls on other machines across the network,
|
||||||
|
with desired authentication.
|
||||||
|
.Pp
|
||||||
|
These routines are normally called after creating the
|
||||||
|
.Vt CLIENT
|
||||||
|
handle.
|
||||||
|
The
|
||||||
|
.Va cl_auth
|
||||||
|
field of the
|
||||||
|
.Vt CLIENT
|
||||||
|
structure should be initialized by the
|
||||||
|
.Vt AUTH
|
||||||
|
structure returned by some of the following routines.
|
||||||
|
The client's authentication information
|
||||||
|
is passed to the server when the
|
||||||
|
RPC
|
||||||
|
call is made.
|
||||||
|
.Pp
|
||||||
|
Only the
|
||||||
|
.Dv NULL
|
||||||
|
and the
|
||||||
|
.Dv SYS
|
||||||
|
style of authentication is discussed here.
|
||||||
|
.Sh Routines
|
||||||
|
.Bl -tag -width authsys_create_default()
|
||||||
|
.It Fn auth_destroy
|
||||||
|
A function macro that destroys the authentication
|
||||||
|
information associated with
|
||||||
|
.Fa auth .
|
||||||
|
Destruction usually involves deallocation
|
||||||
|
of private data structures.
|
||||||
|
The use of
|
||||||
|
.Fa auth
|
||||||
|
is undefined after calling
|
||||||
|
.Fn auth_destroy .
|
||||||
|
.It Fn authnone_create
|
||||||
|
Create and return an RPC
|
||||||
|
authentication handle that passes nonusable
|
||||||
|
authentication information with each remote procedure call.
|
||||||
|
This is the default authentication used by RPC.
|
||||||
|
.It Fn authsys_create
|
||||||
|
Create and return an RPC authentication handle that contains
|
||||||
|
.Dv AUTH_SYS
|
||||||
|
authentication information.
|
||||||
|
The
|
||||||
|
.Fa host
|
||||||
|
argument
|
||||||
|
is the name of the machine on which the information was
|
||||||
|
created;
|
||||||
|
.Fa uid
|
||||||
|
is the user's user ID;
|
||||||
|
.Fa gid
|
||||||
|
is the user's current group ID;
|
||||||
|
.Fa len
|
||||||
|
and
|
||||||
|
.Fa aup_gids
|
||||||
|
refer to a counted array of groups to which the user belongs.
|
||||||
|
.It Fn authsys_create_default
|
||||||
|
Call
|
||||||
|
.Fn authsys_create
|
||||||
|
with the appropriate arguments.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_clnt_calls 3 ,
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
316
libtirpc-1.3.1/man/rpc_clnt_calls.3t
Normal file
316
libtirpc-1.3.1/man/rpc_clnt_calls.3t
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
.\" @(#)rpc_clnt_calls.3n 1.30 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_clnt_calls 1.4 89/07/20 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_clnt_calls.3,v 1.7 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.Dd May 7, 1993
|
||||||
|
.Dt RPC_CLNT_CALLS 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_clnt_calls ,
|
||||||
|
.Nm clnt_call ,
|
||||||
|
.Nm clnt_freeres ,
|
||||||
|
.Nm clnt_geterr ,
|
||||||
|
.Nm clnt_perrno ,
|
||||||
|
.Nm clnt_perror ,
|
||||||
|
.Nm clnt_sperrno ,
|
||||||
|
.Nm clnt_sperror ,
|
||||||
|
.Nm rpc_broadcast ,
|
||||||
|
.Nm rpc_broadcast_exp ,
|
||||||
|
.Nm rpc_call
|
||||||
|
.Nd library routines for client side calls
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft "enum clnt_stat"
|
||||||
|
.Fn clnt_call "CLIENT *clnt" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" "const struct timeval tout"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn clnt_freeres "CLIENT *clnt" "const xdrproc_t outproc" "caddr_t out"
|
||||||
|
.Ft void
|
||||||
|
.Fn clnt_geterr "const CLIENT * clnt" "struct rpc_err * errp"
|
||||||
|
.Ft void
|
||||||
|
.Fn clnt_perrno "const enum clnt_stat stat"
|
||||||
|
.Ft void
|
||||||
|
.Fn clnt_perror "CLIENT *clnt" "const char *s"
|
||||||
|
.Ft "char *"
|
||||||
|
.Fn clnt_sperrno "const enum clnt_stat stat"
|
||||||
|
.Ft "char *"
|
||||||
|
.Fn clnt_sperror "CLIENT *clnt" "const char * s"
|
||||||
|
.Ft "enum clnt_stat"
|
||||||
|
.Fo rpc_broadcast
|
||||||
|
.Fa "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||||
|
.Fa "const rpcproc_t procnum" "const xdrproc_t inproc"
|
||||||
|
.Fa "const caddr_t in" "const xdrproc_t outproc" "caddr_t out"
|
||||||
|
.Fa "const resultproc_t eachresult" "const char *nettype"
|
||||||
|
.Fc
|
||||||
|
.Ft "enum clnt_stat"
|
||||||
|
.Fo rpc_broadcast_exp
|
||||||
|
.Fa "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||||
|
.Fa "const rpcproc_t procnum" "const xdrproc_t xargs"
|
||||||
|
.Fa "caddr_t argsp" "const xdrproc_t xresults"
|
||||||
|
.Fa "caddr_t resultsp" "const resultproc_t eachresult"
|
||||||
|
.Fa "const int inittime" "const int waittime"
|
||||||
|
.Fa "const char * nettype"
|
||||||
|
.Fc
|
||||||
|
.Ft "enum clnt_stat"
|
||||||
|
.Fo rpc_call
|
||||||
|
.Fa "const char *host" "const rpcprog_t prognum"
|
||||||
|
.Fa "const rpcvers_t versnum" "const rpcproc_t procnum"
|
||||||
|
.Fa "const xdrproc_t inproc" "const char *in"
|
||||||
|
.Fa "const xdrproc_t outproc" "char *out" "const char *nettype"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
RPC library routines allow C language programs to make procedure
|
||||||
|
calls on other machines across the network.
|
||||||
|
First, the client calls a procedure to send a request to the server.
|
||||||
|
Upon receipt of the request, the server calls a dispatch routine
|
||||||
|
to perform the requested service, and then sends back a reply.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn clnt_call ,
|
||||||
|
.Fn rpc_call ,
|
||||||
|
and
|
||||||
|
.Fn rpc_broadcast
|
||||||
|
routines handle the client side of the procedure call.
|
||||||
|
The remaining routines deal with error handling in the case of errors.
|
||||||
|
.Pp
|
||||||
|
Some of the routines take a
|
||||||
|
.Vt CLIENT
|
||||||
|
handle as one of the arguments.
|
||||||
|
A
|
||||||
|
.Vt CLIENT
|
||||||
|
handle can be created by an RPC creation routine such as
|
||||||
|
.Fn clnt_create
|
||||||
|
(see
|
||||||
|
.Xr rpc_clnt_create 3 ) .
|
||||||
|
.Pp
|
||||||
|
These routines are safe for use in multithreaded applications.
|
||||||
|
.Vt CLIENT
|
||||||
|
handles can be shared between threads, however in this implementation
|
||||||
|
requests by different threads are serialized (that is, the first request will
|
||||||
|
receive its results before the second request is sent).
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt CLIENT
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn clnt_call
|
||||||
|
A function macro that calls the remote procedure
|
||||||
|
.Fa procnum
|
||||||
|
associated with the client handle,
|
||||||
|
.Fa clnt ,
|
||||||
|
which is obtained with an RPC
|
||||||
|
client creation routine such as
|
||||||
|
.Fn clnt_create
|
||||||
|
(see
|
||||||
|
.Xr rpc_clnt_create 3 ) .
|
||||||
|
The
|
||||||
|
.Fa inproc
|
||||||
|
argument
|
||||||
|
is the XDR function used to encode the procedure's arguments, and
|
||||||
|
.Fa outproc
|
||||||
|
is the XDR function used to decode the procedure's results;
|
||||||
|
.Fa in
|
||||||
|
is the address of the procedure's argument(s), and
|
||||||
|
.Fa out
|
||||||
|
is the address of where to place the result(s).
|
||||||
|
The
|
||||||
|
.Fa tout
|
||||||
|
argument
|
||||||
|
is the time allowed for results to be returned, which is overridden by
|
||||||
|
a time-out set explicitly through
|
||||||
|
.Fn clnt_control ,
|
||||||
|
see
|
||||||
|
.Xr rpc_clnt_create 3 .
|
||||||
|
If the remote call succeeds, the status returned is
|
||||||
|
.Dv RPC_SUCCESS ,
|
||||||
|
otherwise an appropriate status is returned.
|
||||||
|
.It Fn clnt_freeres
|
||||||
|
A function macro that frees any data allocated by the
|
||||||
|
RPC/XDR system when it decoded the results of an RPC call.
|
||||||
|
The
|
||||||
|
.Fa out
|
||||||
|
argument
|
||||||
|
is the address of the results, and
|
||||||
|
.Fa outproc
|
||||||
|
is the XDR routine describing the results.
|
||||||
|
This routine returns 1 if the results were successfully freed,
|
||||||
|
and 0 otherwise.
|
||||||
|
.It Fn clnt_geterr
|
||||||
|
A function macro that copies the error structure out of the client
|
||||||
|
handle to the structure at address
|
||||||
|
.Fa errp .
|
||||||
|
.It Fn clnt_perrno
|
||||||
|
Print a message to standard error corresponding
|
||||||
|
to the condition indicated by
|
||||||
|
.Fa stat .
|
||||||
|
A newline is appended.
|
||||||
|
Normally used after a procedure call fails for a routine
|
||||||
|
for which a client handle is not needed, for instance
|
||||||
|
.Fn rpc_call .
|
||||||
|
.It Fn clnt_perror
|
||||||
|
Print a message to the standard error indicating why an
|
||||||
|
RPC call failed;
|
||||||
|
.Fa clnt
|
||||||
|
is the handle used to do the call.
|
||||||
|
The message is prepended with string
|
||||||
|
.Fa s
|
||||||
|
and a colon.
|
||||||
|
A newline is appended.
|
||||||
|
Normally used after a remote procedure call fails
|
||||||
|
for a routine which requires a client handle,
|
||||||
|
for instance
|
||||||
|
.Fn clnt_call .
|
||||||
|
.It Fn clnt_sperrno
|
||||||
|
Take the same arguments as
|
||||||
|
.Fn clnt_perrno ,
|
||||||
|
but instead of sending a message to the standard error
|
||||||
|
indicating why an RPC
|
||||||
|
call failed, return a pointer to a string which contains the message.
|
||||||
|
The
|
||||||
|
.Fn clnt_sperrno
|
||||||
|
function
|
||||||
|
is normally used instead of
|
||||||
|
.Fn clnt_perrno
|
||||||
|
when the program does not have a standard error (as a program
|
||||||
|
running as a server quite likely does not), or if the programmer
|
||||||
|
does not want the message to be output with
|
||||||
|
.Fn printf
|
||||||
|
(see
|
||||||
|
.Xr printf 3 ) ,
|
||||||
|
or if a message format different than that supported by
|
||||||
|
.Fn clnt_perrno
|
||||||
|
is to be used.
|
||||||
|
Note:
|
||||||
|
unlike
|
||||||
|
.Fn clnt_sperror
|
||||||
|
and
|
||||||
|
.Fn clnt_spcreateerror
|
||||||
|
(see
|
||||||
|
.Xr rpc_clnt_create 3 ) ,
|
||||||
|
.Fn clnt_sperrno
|
||||||
|
does not return pointer to static data so the
|
||||||
|
result will not get overwritten on each call.
|
||||||
|
.It Fn clnt_sperror
|
||||||
|
Like
|
||||||
|
.Fn clnt_perror ,
|
||||||
|
except that (like
|
||||||
|
.Fn clnt_sperrno )
|
||||||
|
it returns a string instead of printing to standard error.
|
||||||
|
However,
|
||||||
|
.Fn clnt_sperror
|
||||||
|
does not append a newline at the end of the message.
|
||||||
|
Warning:
|
||||||
|
returns pointer to a buffer that is overwritten
|
||||||
|
on each call.
|
||||||
|
.It Fn rpc_broadcast
|
||||||
|
Like
|
||||||
|
.Fn rpc_call ,
|
||||||
|
except the call message is broadcast to
|
||||||
|
all the connectionless transports specified by
|
||||||
|
.Fa nettype .
|
||||||
|
If
|
||||||
|
.Fa nettype
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
it defaults to
|
||||||
|
.Qq netpath .
|
||||||
|
Each time it receives a response,
|
||||||
|
this routine calls
|
||||||
|
.Fn eachresult ,
|
||||||
|
whose form is:
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn eachresult "caddr_t out" "const struct netbuf * addr" "const struct netconfig * netconf"
|
||||||
|
where
|
||||||
|
.Fa out
|
||||||
|
is the same as
|
||||||
|
.Fa out
|
||||||
|
passed to
|
||||||
|
.Fn rpc_broadcast ,
|
||||||
|
except that the remote procedure's output is decoded there;
|
||||||
|
.Fa addr
|
||||||
|
points to the address of the machine that sent the results, and
|
||||||
|
.Fa netconf
|
||||||
|
is the netconfig structure of the transport on which the remote
|
||||||
|
server responded.
|
||||||
|
If
|
||||||
|
.Fn eachresult
|
||||||
|
returns 0,
|
||||||
|
.Fn rpc_broadcast
|
||||||
|
waits for more replies;
|
||||||
|
otherwise it returns with appropriate status.
|
||||||
|
Warning:
|
||||||
|
broadcast file descriptors are limited in size to the
|
||||||
|
maximum transfer size of that transport.
|
||||||
|
For Ethernet, this value is 1500 bytes.
|
||||||
|
The
|
||||||
|
.Fn rpc_broadcast
|
||||||
|
function
|
||||||
|
uses
|
||||||
|
.Dv AUTH_SYS
|
||||||
|
credentials by default (see
|
||||||
|
.Xr rpc_clnt_auth 3 ) .
|
||||||
|
.It Fn rpc_broadcast_exp
|
||||||
|
Like
|
||||||
|
.Fn rpc_broadcast ,
|
||||||
|
except that the initial timeout,
|
||||||
|
.Fa inittime
|
||||||
|
and the maximum timeout,
|
||||||
|
.Fa waittime
|
||||||
|
are specified in milliseconds.
|
||||||
|
The
|
||||||
|
.Fa inittime
|
||||||
|
argument
|
||||||
|
is the initial time that
|
||||||
|
.Fn rpc_broadcast_exp
|
||||||
|
waits before resending the request.
|
||||||
|
After the first resend, the re-transmission interval
|
||||||
|
increases exponentially until it exceeds
|
||||||
|
.Fa waittime .
|
||||||
|
.It Fn rpc_call
|
||||||
|
Call the remote procedure associated with
|
||||||
|
.Fa prognum ,
|
||||||
|
.Fa versnum ,
|
||||||
|
and
|
||||||
|
.Fa procnum
|
||||||
|
on the machine,
|
||||||
|
.Fa host .
|
||||||
|
The
|
||||||
|
.Fa inproc
|
||||||
|
argument
|
||||||
|
is used to encode the procedure's arguments, and
|
||||||
|
.Fa outproc
|
||||||
|
is used to decode the procedure's results;
|
||||||
|
.Fa in
|
||||||
|
is the address of the procedure's argument(s), and
|
||||||
|
.Fa out
|
||||||
|
is the address of where to place the result(s).
|
||||||
|
The
|
||||||
|
.Fa nettype
|
||||||
|
argument
|
||||||
|
can be any of the values listed on
|
||||||
|
.Xr rpc 3 .
|
||||||
|
This routine returns
|
||||||
|
.Dv RPC_SUCCESS
|
||||||
|
if it succeeds,
|
||||||
|
or an appropriate status is returned.
|
||||||
|
Use the
|
||||||
|
.Fn clnt_perrno
|
||||||
|
routine to translate failure status into error messages.
|
||||||
|
Warning:
|
||||||
|
.Fn rpc_call
|
||||||
|
uses the first available transport belonging
|
||||||
|
to the class
|
||||||
|
.Fa nettype ,
|
||||||
|
on which it can create a connection.
|
||||||
|
You do not have control of timeouts or authentication
|
||||||
|
using this routine.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr printf 3 ,
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_clnt_auth 3 ,
|
||||||
|
.Xr rpc_clnt_create 3
|
||||||
514
libtirpc-1.3.1/man/rpc_clnt_create.3t
Normal file
514
libtirpc-1.3.1/man/rpc_clnt_create.3t
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
.\" @(#)rpc_clnt_create.3n 1.36 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_clnt_create 1.5 89/07/24 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $NetBSD: rpc_clnt_create.3,v 1.2 2000/06/20 00:53:08 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_clnt_create.3,v 1.12 2003/09/14 13:41:56 ru Exp $
|
||||||
|
.Dd May 7, 1993
|
||||||
|
.Dt RPC_CLNT_CREATE 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_clnt_create ,
|
||||||
|
.Nm clnt_control ,
|
||||||
|
.Nm clnt_create ,
|
||||||
|
.Nm clnt_create_timed ,
|
||||||
|
.Nm clnt_create_vers ,
|
||||||
|
.Nm clnt_create_vers_timed ,
|
||||||
|
.Nm clnt_destroy ,
|
||||||
|
.Nm clnt_dg_create ,
|
||||||
|
.Nm clnt_pcreateerror ,
|
||||||
|
.Nm clnt_raw_create ,
|
||||||
|
.Nm clnt_spcreateerror ,
|
||||||
|
.Nm clnt_tli_create ,
|
||||||
|
.Nm clnt_tp_create ,
|
||||||
|
.Nm clnt_tp_create_timed ,
|
||||||
|
.Nm clnt_vc_create ,
|
||||||
|
.Nm rpc_createerr
|
||||||
|
.Nd "library routines for dealing with creation and manipulation of"
|
||||||
|
.Vt CLIENT
|
||||||
|
handles
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn clnt_control "CLIENT *clnt" "const u_int req" "char *info"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" "const struct timeval *timeout"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_create_vers "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "const char *nettype"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_create_vers_timed "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "char *nettype" "const struct timeval *timeout"
|
||||||
|
.Ft void
|
||||||
|
.Fn clnt_destroy "CLIENT *clnt"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_dg_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Ft void
|
||||||
|
.Fn clnt_pcreateerror "const char *s"
|
||||||
|
.Ft "char *"
|
||||||
|
.Fn clnt_spcreateerror "const char *s"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_raw_create "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_tli_create "const int fildes" "const struct netconfig *netconf" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_tp_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_tp_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct timeval *timeout"
|
||||||
|
.Ft "CLIENT *"
|
||||||
|
.Fn clnt_vc_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "u_int sendsz" "u_int recvsz"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
RPC library routines allow C language programs to make procedure
|
||||||
|
calls on other machines across the network.
|
||||||
|
First a
|
||||||
|
.Vt CLIENT
|
||||||
|
handle is created and then the client calls a procedure to send a
|
||||||
|
request to the server.
|
||||||
|
On receipt of the request, the server calls a dispatch routine
|
||||||
|
to perform the requested service, and then sends a reply.
|
||||||
|
.Sh Routines
|
||||||
|
.Bl -tag -width YYYYYYY
|
||||||
|
.It Fn clnt_control
|
||||||
|
A function macro to change or retrieve various information
|
||||||
|
about a client object.
|
||||||
|
The
|
||||||
|
.Fa req
|
||||||
|
argument
|
||||||
|
indicates the type of operation, and
|
||||||
|
.Fa info
|
||||||
|
is a pointer to the information.
|
||||||
|
For both connectionless and connection-oriented transports,
|
||||||
|
the supported values of
|
||||||
|
.Fa req
|
||||||
|
and their argument types and what they do are:
|
||||||
|
.Bl -column "CLSET_FD_NCLOSE" "struct timeval *" "set total timeout"
|
||||||
|
.It Dv CLSET_TIMEOUT Ta "struct timeval *" Ta "set total timeout"
|
||||||
|
.It Dv CLGET_TIMEOUT Ta "struct timeval *" Ta "get total timeout"
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Note:
|
||||||
|
if you set the timeout using
|
||||||
|
.Fn clnt_control ,
|
||||||
|
the timeout argument passed by
|
||||||
|
.Fn clnt_call
|
||||||
|
is ignored in all subsequent calls.
|
||||||
|
.Pp
|
||||||
|
Note:
|
||||||
|
If you set the timeout value to 0,
|
||||||
|
.Fn clnt_control
|
||||||
|
immediately returns an error
|
||||||
|
.Pq Dv RPC_TIMEDOUT .
|
||||||
|
Set the timeout argument to 0 for batching calls.
|
||||||
|
.Bl -column CLSET_FD_NCLOSE "struct timeval *" "do not close fd on destroy"
|
||||||
|
.It Dv CLGET_SVC_ADDR Ta "struct netbuf *" Ta "get servers address"
|
||||||
|
.It Dv CLGET_FD Ta "int *" Ta "get fd from handle"
|
||||||
|
.It Dv CLSET_FD_CLOSE Ta "void" Ta "close fd on destroy"
|
||||||
|
.It Dv CLSET_FD_NCLOSE Ta void Ta "don't close fd on destroy"
|
||||||
|
.It Dv CLGET_VERS Ta "u_int32_t *" Ta "get RPC program version"
|
||||||
|
.It Dv CLSET_VERS Ta "u_int32_t *" Ta "set RPC program version"
|
||||||
|
.It Dv CLGET_XID Ta "u_int32_t *" Ta "get XID of previous call"
|
||||||
|
.It Dv CLSET_XID Ta "u_int32_t *" Ta "set XID of next call"
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The following operations are valid for connectionless transports only:
|
||||||
|
.Bl -column CLSET_RETRY_TIMEOUT "struct timeval *" "set total timeout"
|
||||||
|
.It Dv CLSET_RETRY_TIMEOUT Ta "struct timeval *" Ta "set the retry timeout"
|
||||||
|
.It Dv CLGET_RETRY_TIMEOUT Ta "struct timeval *" Ta "get the retry timeout"
|
||||||
|
.It Dv CLSET_CONNECT Ta Vt "int *" Ta use Xr connect 2
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The retry timeout is the time that RPC
|
||||||
|
waits for the server to reply before retransmitting the request.
|
||||||
|
The
|
||||||
|
.Fn clnt_control
|
||||||
|
function
|
||||||
|
returns
|
||||||
|
.Dv TRUE
|
||||||
|
on success and
|
||||||
|
.Dv FALSE
|
||||||
|
on failure.
|
||||||
|
.It Fn clnt_create
|
||||||
|
Generic client creation routine for program
|
||||||
|
.Fa prognum
|
||||||
|
and version
|
||||||
|
.Fa versnum .
|
||||||
|
The
|
||||||
|
.Fa host
|
||||||
|
argument
|
||||||
|
identifies the name of the remote host where the server
|
||||||
|
is located.
|
||||||
|
The
|
||||||
|
.Fa nettype
|
||||||
|
argument
|
||||||
|
indicates the class of transport protocol to use.
|
||||||
|
The transports are tried in left to right order in
|
||||||
|
.Ev NETPATH
|
||||||
|
environment variable or in top to bottom order in
|
||||||
|
the netconfig database.
|
||||||
|
The
|
||||||
|
.Fn clnt_create
|
||||||
|
function
|
||||||
|
tries all the transports of the
|
||||||
|
.Fa nettype
|
||||||
|
class available from the
|
||||||
|
.Ev NETPATH
|
||||||
|
environment variable and the netconfig database,
|
||||||
|
and chooses the first successful one.
|
||||||
|
A default timeout is set and can be modified using
|
||||||
|
.Fn clnt_control .
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn clnt_pcreateerror
|
||||||
|
routine can be used to print the reason for failure.
|
||||||
|
.Pp
|
||||||
|
Note:
|
||||||
|
.Fn clnt_create
|
||||||
|
returns a valid client handle even
|
||||||
|
if the particular version number supplied to
|
||||||
|
.Fn clnt_create
|
||||||
|
is not registered with the
|
||||||
|
.Xr rpcbind 8
|
||||||
|
service.
|
||||||
|
This mismatch will be discovered by a
|
||||||
|
.Fn clnt_call
|
||||||
|
later (see
|
||||||
|
.Xr rpc_clnt_calls 3 ) .
|
||||||
|
.It Fn clnt_create_timed
|
||||||
|
Generic client creation routine which is similar to
|
||||||
|
.Fn clnt_create
|
||||||
|
but which also has the additional argument
|
||||||
|
.Fa timeout
|
||||||
|
that specifies the maximum amount of time allowed for
|
||||||
|
each transport class tried.
|
||||||
|
In all other respects, the
|
||||||
|
.Fn clnt_create_timed
|
||||||
|
call behaves exactly like the
|
||||||
|
.Fn clnt_create
|
||||||
|
call.
|
||||||
|
.It Fn clnt_create_vers
|
||||||
|
Generic client creation routine which is similar to
|
||||||
|
.Fn clnt_create
|
||||||
|
but which also checks for the
|
||||||
|
version availability.
|
||||||
|
The
|
||||||
|
.Fa host
|
||||||
|
argument
|
||||||
|
identifies the name of the remote host where the server
|
||||||
|
is located.
|
||||||
|
The
|
||||||
|
.Fa nettype
|
||||||
|
argument
|
||||||
|
indicates the class transport protocols to be used.
|
||||||
|
If the routine is successful it returns a client handle created for
|
||||||
|
the highest version between
|
||||||
|
.Fa vers_low
|
||||||
|
and
|
||||||
|
.Fa vers_high
|
||||||
|
that is supported by the server.
|
||||||
|
The
|
||||||
|
.Fa vers_outp
|
||||||
|
argument
|
||||||
|
is set to this value.
|
||||||
|
That is, after a successful return
|
||||||
|
.Fa vers_low
|
||||||
|
<=
|
||||||
|
.Fa *vers_outp
|
||||||
|
<=
|
||||||
|
.Fa vers_high .
|
||||||
|
If no version between
|
||||||
|
.Fa vers_low
|
||||||
|
and
|
||||||
|
.Fa vers_high
|
||||||
|
is supported by the server then the routine fails and returns
|
||||||
|
.Dv NULL .
|
||||||
|
A default timeout is set and can be modified using
|
||||||
|
.Fn clnt_control .
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn clnt_pcreateerror
|
||||||
|
routine can be used to print the reason for failure.
|
||||||
|
Note:
|
||||||
|
.Fn clnt_create
|
||||||
|
returns a valid client handle even
|
||||||
|
if the particular version number supplied to
|
||||||
|
.Fn clnt_create
|
||||||
|
is not registered with the
|
||||||
|
.Xr rpcbind 8
|
||||||
|
service.
|
||||||
|
This mismatch will be discovered by a
|
||||||
|
.Fn clnt_call
|
||||||
|
later (see
|
||||||
|
.Xr rpc_clnt_calls 3 ) .
|
||||||
|
However,
|
||||||
|
.Fn clnt_create_vers
|
||||||
|
does this for you and returns a valid handle
|
||||||
|
only if a version within
|
||||||
|
the range supplied is supported by the server.
|
||||||
|
.It Fn clnt_create_vers_timed
|
||||||
|
Generic client creation routine which is similar to
|
||||||
|
.Fn clnt_create_vers
|
||||||
|
but which also has the additional argument
|
||||||
|
.Fa timeout
|
||||||
|
that specifies the maximum amount of time allowed for
|
||||||
|
each transport class tried.
|
||||||
|
In all other respects, the
|
||||||
|
.Fn clnt_create_vers_timed
|
||||||
|
call behaves exactly like the
|
||||||
|
.Fn clnt_create_vers
|
||||||
|
call.
|
||||||
|
.It Fn clnt_destroy
|
||||||
|
A function macro that destroys the client's RPC handle.
|
||||||
|
Destruction usually involves deallocation
|
||||||
|
of private data structures, including
|
||||||
|
.Fa clnt
|
||||||
|
itself.
|
||||||
|
Use of
|
||||||
|
.Fa clnt
|
||||||
|
is undefined after calling
|
||||||
|
.Fn clnt_destroy .
|
||||||
|
If the RPC library opened the associated file descriptor, or
|
||||||
|
.Dv CLSET_FD_CLOSE
|
||||||
|
was set using
|
||||||
|
.Fn clnt_control ,
|
||||||
|
the file descriptor will be closed.
|
||||||
|
The caller should call
|
||||||
|
.Fn auth_destroy "clnt->cl_auth"
|
||||||
|
(before calling
|
||||||
|
.Fn clnt_destroy )
|
||||||
|
to destroy the associated
|
||||||
|
.Vt AUTH
|
||||||
|
structure (see
|
||||||
|
.Xr rpc_clnt_auth 3 ) .
|
||||||
|
.It Fn clnt_dg_create
|
||||||
|
This routine creates an RPC client for the remote program
|
||||||
|
.Fa prognum
|
||||||
|
and version
|
||||||
|
.Fa versnum ;
|
||||||
|
the client uses a connectionless transport.
|
||||||
|
The remote program is located at address
|
||||||
|
.Fa svcaddr .
|
||||||
|
The
|
||||||
|
.Fa fildes
|
||||||
|
argument
|
||||||
|
is an open and bound file descriptor.
|
||||||
|
This routine will resend the call message in intervals of
|
||||||
|
15 seconds until a response is received or until the
|
||||||
|
call times out.
|
||||||
|
The total time for the call to time out is specified by
|
||||||
|
.Fn clnt_call
|
||||||
|
(see
|
||||||
|
.Fn clnt_call
|
||||||
|
in
|
||||||
|
.Xr rpc_clnt_calls 3 ) .
|
||||||
|
The retry time out and the total time out periods can
|
||||||
|
be changed using
|
||||||
|
.Fn clnt_control .
|
||||||
|
The user may set the size of the send and receive
|
||||||
|
buffers with the
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz
|
||||||
|
arguments;
|
||||||
|
values of 0 choose suitable defaults.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
.It Fn clnt_pcreateerror
|
||||||
|
Print a message to standard error indicating
|
||||||
|
why a client RPC handle could not be created.
|
||||||
|
The message is prepended with the string
|
||||||
|
.Fa s
|
||||||
|
and a colon, and appended with a newline.
|
||||||
|
.It Fn clnt_spcreateerror
|
||||||
|
Like
|
||||||
|
.Fn clnt_pcreateerror ,
|
||||||
|
except that it returns a string
|
||||||
|
instead of printing to the standard error.
|
||||||
|
A newline is not appended to the message in this case.
|
||||||
|
Warning:
|
||||||
|
returns a pointer to a buffer that is overwritten
|
||||||
|
on each call.
|
||||||
|
.It Fn clnt_raw_create
|
||||||
|
This routine creates an RPC
|
||||||
|
client handle for the remote program
|
||||||
|
.Fa prognum
|
||||||
|
and version
|
||||||
|
.Fa versnum .
|
||||||
|
The transport used to pass messages to the service is
|
||||||
|
a buffer within the process's address space,
|
||||||
|
so the corresponding RPC
|
||||||
|
server should live in the same address space;
|
||||||
|
(see
|
||||||
|
.Fn svc_raw_create
|
||||||
|
in
|
||||||
|
.Xr rpc_svc_create 3 ) .
|
||||||
|
This allows simulation of RPC and measurement of
|
||||||
|
RPC overheads, such as round trip times,
|
||||||
|
without any kernel or networking interference.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn clnt_raw_create
|
||||||
|
function
|
||||||
|
should be called after
|
||||||
|
.Fn svc_raw_create .
|
||||||
|
.It Fn clnt_tli_create
|
||||||
|
This routine creates an RPC
|
||||||
|
client handle for the remote program
|
||||||
|
.Fa prognum
|
||||||
|
and version
|
||||||
|
.Fa versnum .
|
||||||
|
The remote program is located at address
|
||||||
|
.Fa svcaddr .
|
||||||
|
If
|
||||||
|
.Fa svcaddr
|
||||||
|
is
|
||||||
|
.Dv NULL
|
||||||
|
and it is connection-oriented, it is assumed that the file descriptor
|
||||||
|
is connected.
|
||||||
|
For connectionless transports, if
|
||||||
|
.Fa svcaddr
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
.Dv RPC_UNKNOWNADDR
|
||||||
|
error is set.
|
||||||
|
The
|
||||||
|
.Fa fildes
|
||||||
|
argument
|
||||||
|
is a file descriptor which may be open, bound and connected.
|
||||||
|
If it is
|
||||||
|
.Dv RPC_ANYFD ,
|
||||||
|
it opens a file descriptor on the transport specified by
|
||||||
|
.Fa netconf .
|
||||||
|
If
|
||||||
|
.Fa fildes
|
||||||
|
is
|
||||||
|
.Dv RPC_ANYFD
|
||||||
|
and
|
||||||
|
.Fa netconf
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
a
|
||||||
|
.Dv RPC_UNKNOWNPROTO
|
||||||
|
error is set.
|
||||||
|
If
|
||||||
|
.Fa fildes
|
||||||
|
is unbound, then it will attempt to bind the descriptor.
|
||||||
|
The user may specify the size of the buffers with the
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz
|
||||||
|
arguments;
|
||||||
|
values of 0 choose suitable defaults.
|
||||||
|
Depending upon the type of the transport (connection-oriented
|
||||||
|
or connectionless),
|
||||||
|
.Fn clnt_tli_create
|
||||||
|
calls appropriate client creation routines.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn clnt_pcreateerror
|
||||||
|
routine can be used to print the reason for failure.
|
||||||
|
The remote rpcbind
|
||||||
|
service (see
|
||||||
|
.Xr rpcbind 8 )
|
||||||
|
is not consulted for the address of the remote
|
||||||
|
service.
|
||||||
|
.It Fn clnt_tp_create
|
||||||
|
Like
|
||||||
|
.Fn clnt_create
|
||||||
|
except
|
||||||
|
.Fn clnt_tp_create
|
||||||
|
tries only one transport specified through
|
||||||
|
.Fa netconf .
|
||||||
|
The
|
||||||
|
.Fn clnt_tp_create
|
||||||
|
function
|
||||||
|
creates a client handle for the program
|
||||||
|
.Fa prognum ,
|
||||||
|
the version
|
||||||
|
.Fa versnum ,
|
||||||
|
and for the transport specified by
|
||||||
|
.Fa netconf .
|
||||||
|
Default options are set,
|
||||||
|
which can be changed using
|
||||||
|
.Fn clnt_control
|
||||||
|
calls.
|
||||||
|
The remote rpcbind service on the host
|
||||||
|
.Fa host
|
||||||
|
is consulted for the address of the remote service.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn clnt_pcreateerror
|
||||||
|
routine can be used to print the reason for failure.
|
||||||
|
.It Fn clnt_tp_create_timed
|
||||||
|
Like
|
||||||
|
.Fn clnt_tp_create
|
||||||
|
except
|
||||||
|
.Fn clnt_tp_create_timed
|
||||||
|
has the extra argument
|
||||||
|
.Fa timeout
|
||||||
|
which specifies the maximum time allowed for
|
||||||
|
the creation attempt to succeed.
|
||||||
|
In all other respects, the
|
||||||
|
.Fn clnt_tp_create_timed
|
||||||
|
call behaves exactly like the
|
||||||
|
.Fn clnt_tp_create
|
||||||
|
call.
|
||||||
|
.It Fn clnt_vc_create
|
||||||
|
This routine creates an RPC
|
||||||
|
client for the remote program
|
||||||
|
.Fa prognum
|
||||||
|
and version
|
||||||
|
.Fa versnum ;
|
||||||
|
the client uses a connection-oriented transport.
|
||||||
|
The remote program is located at address
|
||||||
|
.Fa svcaddr .
|
||||||
|
The
|
||||||
|
.Fa fildes
|
||||||
|
argument
|
||||||
|
is an open and bound file descriptor.
|
||||||
|
The user may specify the size of the send and receive buffers
|
||||||
|
with the
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz
|
||||||
|
arguments;
|
||||||
|
values of 0 choose suitable defaults.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails.
|
||||||
|
The address
|
||||||
|
.Fa svcaddr
|
||||||
|
should not be
|
||||||
|
.Dv NULL
|
||||||
|
and should point to the actual address of the remote program.
|
||||||
|
The
|
||||||
|
.Fn clnt_vc_create
|
||||||
|
function
|
||||||
|
does not consult the remote rpcbind service for this information.
|
||||||
|
.It Xo
|
||||||
|
.Vt "struct rpc_createerr" Va rpc_createerr ;
|
||||||
|
.Xc
|
||||||
|
A global variable whose value is set by any RPC
|
||||||
|
client handle creation routine
|
||||||
|
that fails.
|
||||||
|
It is used by the routine
|
||||||
|
.Fn clnt_pcreateerror
|
||||||
|
to print the reason for the failure.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_clnt_auth 3 ,
|
||||||
|
.Xr rpc_clnt_calls 3 ,
|
||||||
|
.Xr rpcbind 8
|
||||||
55
libtirpc-1.3.1/man/rpc_gss_get_error.3t
Normal file
55
libtirpc-1.3.1/man/rpc_gss_get_error.3t
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GET_ERROR 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_get_error
|
||||||
|
.Nd "Get error details"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft void
|
||||||
|
.Fn rpc_gss_get_error "rpc_gss_error_t *error"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Get details of the last RPCSEC_GSS error.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It error"
|
||||||
|
.It error
|
||||||
|
A pointer to a structure where the error details will be returned
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_get_error
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
70
libtirpc-1.3.1/man/rpc_gss_get_mech_info.3t
Normal file
70
libtirpc-1.3.1/man/rpc_gss_get_mech_info.3t
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GET_MECH_INFO 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_get_mech_info
|
||||||
|
.Nd "Get Quality of Protection information for a security mechanism"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft const char **
|
||||||
|
.Fn rpc_gss_get_mech_info "const char *mech" "rpc_gss_service_t *service"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function returns the list of QOP names supported by the
|
||||||
|
GSS_API mechanism named "mech".
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It service"
|
||||||
|
.It mech
|
||||||
|
The name of a GSS_API mechanism.
|
||||||
|
"kerberos_v5" is currently the only supported mechanism.
|
||||||
|
.It service
|
||||||
|
Buffer in which maximum service type is planted
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
If the named GSS_API mechanism is recognized,
|
||||||
|
a list of the supported Qualities of Protection is returned.
|
||||||
|
The maximum supported service type for the mechanism is returned in
|
||||||
|
.Fa *service .
|
||||||
|
Otherwise
|
||||||
|
.Dv NULL
|
||||||
|
is returned.
|
||||||
|
.Pp
|
||||||
|
Note: The returned QOP list is statically allocated memory.
|
||||||
|
The caller must not free this array.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_get_mech_info
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
52
libtirpc-1.3.1/man/rpc_gss_get_mechanisms.3t
Normal file
52
libtirpc-1.3.1/man/rpc_gss_get_mechanisms.3t
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GET_MECHANISMS 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_get_mechanisms
|
||||||
|
.Nd "Get installed mechanisms"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft const char **
|
||||||
|
.Fn rpc_gss_get_mechanisms "void"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Return a
|
||||||
|
.Dv NULL
|
||||||
|
terminated list of installed security mechanisms.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_get_mechanisms
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
79
libtirpc-1.3.1/man/rpc_gss_get_principal_name.3t
Normal file
79
libtirpc-1.3.1/man/rpc_gss_get_principal_name.3t
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GET_PRINCIPAL_NAME 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_get_principal_name
|
||||||
|
.Nd "Get a principal name"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fo rpc_gss_get_principal_name
|
||||||
|
.Fa "rpc_gss_principal_t *principal"
|
||||||
|
.Fa "const char *mech"
|
||||||
|
.Fa "const char *name"
|
||||||
|
.Fa "const char *node"
|
||||||
|
.Fa "const char *domain"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function can be used to generate a client principal name from
|
||||||
|
various strings.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It principal"
|
||||||
|
.It principal
|
||||||
|
If the principal is created successfully,
|
||||||
|
.Fa *principal
|
||||||
|
will be set to point at the new principal in GSS-API exported name form
|
||||||
|
.It mech
|
||||||
|
The name of the mechanism for this principal
|
||||||
|
.It name
|
||||||
|
The name part of the principal
|
||||||
|
.It node
|
||||||
|
If non-null, the hostname or instance part of the principal
|
||||||
|
.It domain
|
||||||
|
If non-null, the domain or realm part of the principal
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the principal was created or
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_get_principal_name
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr gss_export_name 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
61
libtirpc-1.3.1/man/rpc_gss_get_versions.3t
Normal file
61
libtirpc-1.3.1/man/rpc_gss_get_versions.3t
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GET_VERSIONS 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_get_versions
|
||||||
|
.Nd "Get supported protocol version"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpc_gss_get_versions "u_int *vers_hi" "u_int *vers_lo"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Return the highest and lowest supported versions of the RPCSEC_GSS protocol.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It vers_lo"
|
||||||
|
.It vers_hi
|
||||||
|
The value of
|
||||||
|
.Fa *vers_hi
|
||||||
|
is set to the highest supported protocol version
|
||||||
|
.It vers_lo
|
||||||
|
The value of
|
||||||
|
.Fa *vers_lo
|
||||||
|
is set to the lowest supported protocol version
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_get_versions
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
81
libtirpc-1.3.1/man/rpc_gss_getcred.3t
Normal file
81
libtirpc-1.3.1/man/rpc_gss_getcred.3t
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_GETCRED 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_getcred
|
||||||
|
.Nd "Get authorization information for an RPC request"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft AUTH *
|
||||||
|
.Fo rpc_gss_getcred
|
||||||
|
.Fa "struct svc_req *req"
|
||||||
|
.Fa "rpc_gss_rawcred_t **rcred"
|
||||||
|
.Fa "rpc_gss_ucred_t **ucred"
|
||||||
|
.Fa "void **cookie"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function returns the RPCSEC_GSS authenticated credentials
|
||||||
|
associated with an RPC request.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It cookie"
|
||||||
|
.It req
|
||||||
|
The RPC request to query
|
||||||
|
.It rcred
|
||||||
|
If non-null,
|
||||||
|
.Fa *rcred
|
||||||
|
is set to point at the raw credentials for this request
|
||||||
|
.It ucred
|
||||||
|
If non-null,
|
||||||
|
.Fa *ucred
|
||||||
|
is set to point at the corresponding unix credentials
|
||||||
|
.It cookie
|
||||||
|
If non-null,
|
||||||
|
.Fa *cookie
|
||||||
|
is set to the cookie value returned by a callback function registered with
|
||||||
|
.Fn rpc_gss_set_callback
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if successful,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_getcred
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpc_gss_set_callback 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
63
libtirpc-1.3.1/man/rpc_gss_is_installed.3t
Normal file
63
libtirpc-1.3.1/man/rpc_gss_is_installed.3t
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_IS_INSTALLED 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_is_installed
|
||||||
|
.Nd "Query for the presence of a security mechanism"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpc_gss_is_installed "const char *mech"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function indicates whether the GSS_API mechanism named "mech"
|
||||||
|
is installed and enabled.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It mech"
|
||||||
|
.It mech
|
||||||
|
The name of a GSS_API mechanism.
|
||||||
|
"kerberos_v5" is currently the only supported mechanism.
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the named GSS_API mechanism is installed and enabled,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_is_installed
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
61
libtirpc-1.3.1/man/rpc_gss_max_data_length.3t
Normal file
61
libtirpc-1.3.1/man/rpc_gss_max_data_length.3t
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_MAX_DATA_LENGTH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_max_data_length
|
||||||
|
.Nd "calculate maximum data size"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft int
|
||||||
|
.Fn rpc_gss_max_data_length "AUTH *auth" "int max_tp_unit_len"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Calculate the maximum message size that will fit into a packet of size
|
||||||
|
.Fa max_tp_unit_len ,
|
||||||
|
given the current service and QoP setting.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It max_tp_unit_len"
|
||||||
|
.It auth
|
||||||
|
A handle to a RPCSEC_GSS security context
|
||||||
|
.It max_tp_unit_len
|
||||||
|
Maximum packet size of the underlying transport protocol
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The maximum message size that can be encoded
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_max_data_length
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
70
libtirpc-1.3.1/man/rpc_gss_mech_to_oid.3t
Normal file
70
libtirpc-1.3.1/man/rpc_gss_mech_to_oid.3t
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_MECH_TO_OID 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_mech_to_oid
|
||||||
|
.Nd "Convert a mechanism name to a GSS-API oid"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpc_gss_mech_to_oid "const char *mech" "gss_OID *oid_ret"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function returns the GSS OID associated with the GSS_API
|
||||||
|
mechanism "mech".
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It oid_ret"
|
||||||
|
.It mech
|
||||||
|
The name of a GSS_API mechanism.
|
||||||
|
"kerberos_v5" is currently the only supported mechanism.
|
||||||
|
.It oid_ret
|
||||||
|
Buffer in which to place the returned OID
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
If the GSS_API mechanism name is recognized,
|
||||||
|
.Dv TRUE
|
||||||
|
is returned.
|
||||||
|
The corresponding GSS-API oid is returned in
|
||||||
|
.Fa *oid_ret .
|
||||||
|
Otherwise
|
||||||
|
.Dv FALSE
|
||||||
|
is returned and
|
||||||
|
.Fa *oid_ret
|
||||||
|
is left untouched.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_mech_to_oid
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
74
libtirpc-1.3.1/man/rpc_gss_qop_to_num.3t
Normal file
74
libtirpc-1.3.1/man/rpc_gss_qop_to_num.3t
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_QOP_TO_NUM 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_qop_to_num
|
||||||
|
.Nd "Convert a Quality of Protection name to number"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpc_gss_qop_to_num "const char *qop" "const char *mech" "u_int *num_ret"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function returns the numeric QOP value associated with the
|
||||||
|
GSS_API QOP "qop" and mechanism "mech."
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It number_ret"
|
||||||
|
.It qop
|
||||||
|
The name of Quality of Protection associated with the
|
||||||
|
GSS_API mechanism "mech".
|
||||||
|
"GSS_C_QOP_DEFAULT" is currently the only supported QOP.
|
||||||
|
.It mech
|
||||||
|
The name of a GSS_API mechanism.
|
||||||
|
"kerberos_v5" is currently the only supported mechanism.
|
||||||
|
.It number_ret
|
||||||
|
Buffer in which to place the returned QOP number
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
If the QOP and mechanism names are recognized,
|
||||||
|
.Dv TRUE
|
||||||
|
is returned.
|
||||||
|
The corresponding QOP number is returned in
|
||||||
|
.Fa *num_ret .
|
||||||
|
Otherwise
|
||||||
|
.Dv FALSE
|
||||||
|
is returned and
|
||||||
|
.It number_ret
|
||||||
|
is left untouched.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_qop_to_num
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
109
libtirpc-1.3.1/man/rpc_gss_seccreate.3t
Normal file
109
libtirpc-1.3.1/man/rpc_gss_seccreate.3t
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SECCREATE 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_seccreate
|
||||||
|
.Nd "create a security context using the RPCSEC_GSS protocol"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft AUTH *
|
||||||
|
.Fo rpc_gss_seccreate
|
||||||
|
.Fa "CLIENT *clnt"
|
||||||
|
.Fa "const char *principal"
|
||||||
|
.Fa "const char *mechanism"
|
||||||
|
.Fa "rpc_gss_service_t service"
|
||||||
|
.Fa "const char *qop"
|
||||||
|
.Fa "rpc_gss_options_req_t *options_req"
|
||||||
|
.Fa "rpc_gss_options_ret_t *options_ret"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function is used to establish a security context between an
|
||||||
|
application and a remote peer using the RPSEC_GSS protocol.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width "options_req"
|
||||||
|
.It clnt
|
||||||
|
An RPC handle which is connected to the remote peer
|
||||||
|
.It principal
|
||||||
|
The name of the service principal on the remote peer.
|
||||||
|
For instance, a principal such as
|
||||||
|
.Qq nfs@server.example.com
|
||||||
|
might be used by an application which needs to contact an NFS server
|
||||||
|
.It mechanism
|
||||||
|
The name of the GSS_API mechanism to use for the new security context.
|
||||||
|
"kerberos_v5" is currently the only supported mechanism.
|
||||||
|
.It service
|
||||||
|
Type of service requested.
|
||||||
|
.Bl -tag -width "rpc_gss_svc_integrity"
|
||||||
|
.It rpc_gss_svc_default
|
||||||
|
The default - typically the same as
|
||||||
|
.Dv rpc_gss_svc_none .
|
||||||
|
.It rpc_gss_svc_none
|
||||||
|
RPC headers only are integrity protected by a checksum.
|
||||||
|
.It rpc_gss_svc_integrity
|
||||||
|
RPC headers and data are integrity protected by a checksum.
|
||||||
|
.It rpc_gss_svc_privacy
|
||||||
|
RPC headers are integrity protected by a checksum and data is encrypted.
|
||||||
|
.El
|
||||||
|
.It qop
|
||||||
|
The name of the Quality of Protection to use for the new security context,
|
||||||
|
or NULL to use the default QOP.
|
||||||
|
"GSS_C_QOP_DEFAULT" is currently the only supported QOP.
|
||||||
|
.It options_req
|
||||||
|
Extra security context options to be passed to the underlying GSS-API
|
||||||
|
mechanism.
|
||||||
|
Pass
|
||||||
|
.Dv NULL
|
||||||
|
to supply default values.
|
||||||
|
.It options_ret
|
||||||
|
Various values returned by the underlying GSS-API mechanism.
|
||||||
|
Pass
|
||||||
|
.Dv NULL
|
||||||
|
if these values are not required.
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
If the security context was created successfully, a pointer to an
|
||||||
|
.Vt AUTH
|
||||||
|
structure that represents the context is returned.
|
||||||
|
To use this security context for subsequent RPC calls, set
|
||||||
|
.Va clnt->cl_auth
|
||||||
|
to this value.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_seccreate
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr mech 5 ,
|
||||||
|
.Xr qop 5 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
112
libtirpc-1.3.1/man/rpc_gss_set_callback.3t
Normal file
112
libtirpc-1.3.1/man/rpc_gss_set_callback.3t
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SET_CALLBACK 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_set_callback
|
||||||
|
.Nd "Register a security context creation callback"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fo (*callback)
|
||||||
|
.Fa "struct svc_req *req"
|
||||||
|
.Fa "gss_cred_id_t deleg"
|
||||||
|
.Fa "gss_ctx_id_t gss_context"
|
||||||
|
.Fa "rpc_gss_lock_t *lock"
|
||||||
|
.Fa "void **cookie"
|
||||||
|
.Fc
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpc_gss_set_callback "rpc_gss_callback_t *cb"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Register a function which will be called when new security contexts
|
||||||
|
are created on a server.
|
||||||
|
This function will be called on the first RPC request which uses that
|
||||||
|
context and has the opportunity of rejecting the request (for instance
|
||||||
|
after matching the request credentials to an access control list).
|
||||||
|
To accept the new security context, the callback should return
|
||||||
|
.Dv TRUE ,
|
||||||
|
otherwise
|
||||||
|
.Dv FALSE .
|
||||||
|
If the callback accepts a context, it becomes responsible for the
|
||||||
|
lifetime of the delegated client credentials (if any).
|
||||||
|
.Pp
|
||||||
|
It is also possible to 'lock' the values of service and quality of
|
||||||
|
protection used by the context.
|
||||||
|
If a context is locked, any subsequent requests which use different
|
||||||
|
values for service and quality of protection will be rejected.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It gss_context"
|
||||||
|
.It cb
|
||||||
|
A structure containing the RPC program and version for this callback
|
||||||
|
and a function which will be called when new contexts are created for
|
||||||
|
the given RPC program and version
|
||||||
|
.It req
|
||||||
|
The RPC request using the new context
|
||||||
|
.It deleg
|
||||||
|
GSS-API delegated credentials (if any)
|
||||||
|
.It gss_context
|
||||||
|
The GSS-API context
|
||||||
|
.It lock
|
||||||
|
A structure used to enforce a particular QOP and service. Set
|
||||||
|
.Fa lock->locked
|
||||||
|
to
|
||||||
|
.Dv TRUE
|
||||||
|
to lock the service and QOP values
|
||||||
|
.It cookie
|
||||||
|
The callback function may set
|
||||||
|
.Fa *cookie
|
||||||
|
to any pointer sized value.
|
||||||
|
This value can be accessed during the lifetime of the context via
|
||||||
|
.Fn rpc_gss_getcred .
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the callback was registered successfully or
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_set_callback
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpc_gss_getcred 3
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
|
.Sh BUGS
|
||||||
|
There is no mechanism for informing a server when a security context
|
||||||
|
has been deleted.
|
||||||
|
This makes it difficult to allocate resources (e.g. to return via the
|
||||||
|
callback's
|
||||||
|
.Fa cookie
|
||||||
|
argument).
|
||||||
67
libtirpc-1.3.1/man/rpc_gss_set_defaults.3t
Normal file
67
libtirpc-1.3.1/man/rpc_gss_set_defaults.3t
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SET_DEFAULTS 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_set_defaults
|
||||||
|
.Nd "set service and quality of protection"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fo rpc_gss_set_defaults
|
||||||
|
.Fa "AUTH *auth"
|
||||||
|
.Fa "rpc_gss_service_t service"
|
||||||
|
.Fa "const char *qop"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Set the service and quality of protection to be used for RPC requests.
|
||||||
|
The new values apply for the rest of the lifetime of the context
|
||||||
|
(unless changed again with this function).
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It service"
|
||||||
|
.It service
|
||||||
|
The service type to use for subsequent RPC requests
|
||||||
|
.It qop
|
||||||
|
The quality of protection to use or NULL for the default
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the values were set
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_set_defaults
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
84
libtirpc-1.3.1/man/rpc_gss_set_svc_name.3t
Normal file
84
libtirpc-1.3.1/man/rpc_gss_set_svc_name.3t
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SET_SVC_NAME 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_set_svc_name
|
||||||
|
.Nd "Associate a GSS-API service principal with an RPC service"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fo rpc_gss_set_svc_name
|
||||||
|
.Fa "const char *principal"
|
||||||
|
.Fa "const char *mechanism"
|
||||||
|
.Fa "u_int req_time"
|
||||||
|
.Fa "u_int program"
|
||||||
|
.Fa "u_int version"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This function registers a service principal which will be used to
|
||||||
|
authenticate RPCSEC_GSS security contexts for a given RPC program and
|
||||||
|
version.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It mechanism"
|
||||||
|
.It principal
|
||||||
|
A string representing the service principal in the form
|
||||||
|
.Qq service@hostname
|
||||||
|
.It mechanism
|
||||||
|
The name of the security mechanism
|
||||||
|
.It req_time
|
||||||
|
The time in seconds that the service credentials should remain
|
||||||
|
valid.
|
||||||
|
See
|
||||||
|
.Xr gss_acquire_cred 3
|
||||||
|
for more details.
|
||||||
|
principal.
|
||||||
|
.It program
|
||||||
|
RPC program number for this service
|
||||||
|
.It version
|
||||||
|
RPC program version for this service
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the service principal was registered or
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_set_svc_name
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr gss_acquire_cred 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
61
libtirpc-1.3.1/man/rpc_gss_svc_max_data_length.3t
Normal file
61
libtirpc-1.3.1/man/rpc_gss_svc_max_data_length.3t
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SVC_MAX_DATA_LENGTH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_gss_svc_max_data_length
|
||||||
|
.Nd "calculate maximum data size"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Ft int
|
||||||
|
.Fn rpc_gss_svc_max_data_length "struct svc_req *req" "int max_tp_unit_len"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
Calculate the maximum message size that will fit into a packet of size
|
||||||
|
.Fa max_tp_unit_len ,
|
||||||
|
given the current service and QoP setting.
|
||||||
|
.Sh PARAMETERS
|
||||||
|
.Bl -tag -width ".It max_tp_unit_len"
|
||||||
|
.It req
|
||||||
|
An RPC request
|
||||||
|
.It max_tp_unit_len
|
||||||
|
Maximum packet size of the underlying transport protocol
|
||||||
|
.El
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The maximum message size that can be encoded
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rpc_gss_svc_max_data_length
|
||||||
|
function is part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3 ,
|
||||||
|
.Xr rpcsec_gss 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
295
libtirpc-1.3.1/man/rpc_secure.3t
Normal file
295
libtirpc-1.3.1/man/rpc_secure.3t
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_secure.3,v 1.14 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.\"
|
||||||
|
.Dd February 16, 1988
|
||||||
|
.Dt RPC 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_secure
|
||||||
|
.Nd library routines for secure remote procedure calls
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft AUTH *
|
||||||
|
.Fo authdes_create
|
||||||
|
.Fa "char *name"
|
||||||
|
.Fa "unsigned window"
|
||||||
|
.Fa "struct sockaddr *addr"
|
||||||
|
.Fa "des_block *ckey"
|
||||||
|
.Fc
|
||||||
|
.Ft AUTH *
|
||||||
|
.Fo authdes_pk_create
|
||||||
|
.Fa "char *name"
|
||||||
|
.Fa "netobj *publickey"
|
||||||
|
.Fa "unsigned window"
|
||||||
|
.Fa "struct sockaddr *addr"
|
||||||
|
.Fa "des_block *ckey"
|
||||||
|
.Fc
|
||||||
|
.Ft int
|
||||||
|
.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups"
|
||||||
|
.Ft int
|
||||||
|
.Fn getnetname "char *name"
|
||||||
|
.Ft int
|
||||||
|
.Fn host2netname "char *name" "const char *host" "const char *domain"
|
||||||
|
.Ft int
|
||||||
|
.Fn key_decryptsession "const char *remotename" "des_block *deskey"
|
||||||
|
.Ft int
|
||||||
|
.Fn key_encryptsession "const char *remotename" "des_block *deskey"
|
||||||
|
.Ft int
|
||||||
|
.Fn key_gendes "des_block *deskey"
|
||||||
|
.Ft int
|
||||||
|
.Fn key_setsecret "const char *key"
|
||||||
|
.Ft int
|
||||||
|
.Fn netname2host "char *name" "char *host" "int hostlen"
|
||||||
|
.Ft int
|
||||||
|
.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist"
|
||||||
|
.Ft int
|
||||||
|
.Fn user2netname "char *name" "const uid_t uid" "const char *domain"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are part of the
|
||||||
|
.Tn RPC
|
||||||
|
library. They implement
|
||||||
|
.Tn DES
|
||||||
|
Authentication. See
|
||||||
|
.Xr rpc 3
|
||||||
|
for further details about
|
||||||
|
.Tn RPC .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn authdes_create
|
||||||
|
is the first of two routines which interface to the
|
||||||
|
.Tn RPC
|
||||||
|
secure authentication system, known as
|
||||||
|
.Tn DES
|
||||||
|
authentication.
|
||||||
|
The second is
|
||||||
|
.Fn authdes_getucred ,
|
||||||
|
below.
|
||||||
|
.Pp
|
||||||
|
Note: the keyserver daemon
|
||||||
|
.Xr keyserv 8
|
||||||
|
must be running for the
|
||||||
|
.Tn DES
|
||||||
|
authentication system to work.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn authdes_create
|
||||||
|
function,
|
||||||
|
used on the client side, returns an authentication handle that
|
||||||
|
will enable the use of the secure authentication system.
|
||||||
|
The first argument
|
||||||
|
.Fa name
|
||||||
|
is the network name, or
|
||||||
|
.Fa netname ,
|
||||||
|
of the owner of the server process.
|
||||||
|
This field usually
|
||||||
|
represents a
|
||||||
|
.Fa hostname
|
||||||
|
derived from the utility routine
|
||||||
|
.Fn host2netname ,
|
||||||
|
but could also represent a user name using
|
||||||
|
.Fn user2netname .
|
||||||
|
The second field is window on the validity of
|
||||||
|
the client credential, given in seconds. A small
|
||||||
|
window is more secure than a large one, but choosing
|
||||||
|
too small of a window will increase the frequency of
|
||||||
|
resynchronizations because of clock drift.
|
||||||
|
The third
|
||||||
|
argument
|
||||||
|
.Fa addr
|
||||||
|
is optional. If it is
|
||||||
|
.Dv NULL ,
|
||||||
|
then the authentication system will assume
|
||||||
|
that the local clock is always in sync with the server's
|
||||||
|
clock, and will not attempt resynchronizations.
|
||||||
|
If an address
|
||||||
|
is supplied, however, then the system will use the address
|
||||||
|
for consulting the remote time service whenever
|
||||||
|
resynchronization
|
||||||
|
is required.
|
||||||
|
This argument is usually the
|
||||||
|
address of the
|
||||||
|
.Tn RPC
|
||||||
|
server itself.
|
||||||
|
The final argument
|
||||||
|
.Fa ckey
|
||||||
|
is also optional. If it is
|
||||||
|
.Dv NULL ,
|
||||||
|
then the authentication system will
|
||||||
|
generate a random
|
||||||
|
.Tn DES
|
||||||
|
key to be used for the encryption of credentials.
|
||||||
|
If it is supplied, however, then it will be used instead.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn authdes_pk_create
|
||||||
|
function is identical to
|
||||||
|
.Fn authdes_create ,
|
||||||
|
except that the public key needs to be provided at calling time and
|
||||||
|
will not looked up by this function itself.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn authdes_getucred
|
||||||
|
function,
|
||||||
|
the second of the two
|
||||||
|
.Tn DES
|
||||||
|
authentication routines,
|
||||||
|
is used on the server side for converting a
|
||||||
|
.Tn DES
|
||||||
|
credential, which is
|
||||||
|
operating system independent, into a
|
||||||
|
.Ux
|
||||||
|
credential.
|
||||||
|
This routine differs from utility routine
|
||||||
|
.Fn netname2user
|
||||||
|
in that
|
||||||
|
.Fn authdes_getucred
|
||||||
|
pulls its information from a cache, and does not have to do a
|
||||||
|
Yellow Pages lookup every time it is called to get its information.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn getnetname
|
||||||
|
function
|
||||||
|
installs the unique, operating-system independent netname of
|
||||||
|
the
|
||||||
|
caller in the fixed-length array
|
||||||
|
.Fa name .
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds and
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn host2netname
|
||||||
|
function
|
||||||
|
converts from a domain-specific hostname to an
|
||||||
|
operating-system independent netname.
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds and
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails.
|
||||||
|
Inverse of
|
||||||
|
.Fn netname2host .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn key_decryptsession
|
||||||
|
function
|
||||||
|
is an interface to the keyserver daemon, which is associated
|
||||||
|
with
|
||||||
|
.Tn RPC Ns 's
|
||||||
|
secure authentication system
|
||||||
|
.Tn ( DES
|
||||||
|
authentication).
|
||||||
|
User programs rarely need to call it, or its associated routines
|
||||||
|
.Fn key_encryptsession ,
|
||||||
|
.Fn key_gendes
|
||||||
|
and
|
||||||
|
.Fn key_setsecret .
|
||||||
|
System commands such as
|
||||||
|
.Xr login 1
|
||||||
|
and the
|
||||||
|
.Tn RPC
|
||||||
|
library are the main clients of these four routines.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn key_decryptsession
|
||||||
|
function
|
||||||
|
takes a server netname and a
|
||||||
|
.Tn DES
|
||||||
|
key, and decrypts the key by
|
||||||
|
using the public key of the server and the secret key
|
||||||
|
associated with the effective uid of the calling process. It
|
||||||
|
is the inverse of
|
||||||
|
.Fn key_encryptsession .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn key_encryptsession
|
||||||
|
function
|
||||||
|
is a keyserver interface routine.
|
||||||
|
It
|
||||||
|
takes a server netname and a des key, and encrypts
|
||||||
|
it using the public key of the server and the secret key
|
||||||
|
associated with the effective uid of the calling process. It
|
||||||
|
is the inverse of
|
||||||
|
.Fn key_decryptsession .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn key_gendes
|
||||||
|
function
|
||||||
|
is a keyserver interface routine.
|
||||||
|
It
|
||||||
|
is used to ask the keyserver for a secure conversation key.
|
||||||
|
Choosing one
|
||||||
|
.Qq random
|
||||||
|
is usually not good enough,
|
||||||
|
because
|
||||||
|
the common ways of choosing random numbers, such as using the
|
||||||
|
current time, are very easy to guess.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn key_setsecret
|
||||||
|
function
|
||||||
|
is a keyserver interface routine.
|
||||||
|
It is used to set the key for
|
||||||
|
the effective
|
||||||
|
.Fa uid
|
||||||
|
of the calling process.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn netname2host
|
||||||
|
function
|
||||||
|
converts from an operating-system independent netname to a
|
||||||
|
domain-specific hostname.
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds and
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails. Inverse of
|
||||||
|
.Fn host2netname .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn netname2user
|
||||||
|
function
|
||||||
|
converts from an operating-system independent netname to a
|
||||||
|
domain-specific user ID.
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds and
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails.
|
||||||
|
Inverse of
|
||||||
|
.Fn user2netname .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn user2netname
|
||||||
|
function
|
||||||
|
converts from a domain-specific username to an operating-system
|
||||||
|
independent netname.
|
||||||
|
Returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds and
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails.
|
||||||
|
Inverse of
|
||||||
|
.Fn netname2user .
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr xdr 3
|
||||||
|
.Pp
|
||||||
|
The following manuals:
|
||||||
|
.Rs
|
||||||
|
.%B Remote Procedure Calls: Protocol Specification
|
||||||
|
.Re
|
||||||
|
.Rs
|
||||||
|
.%B Remote Procedure Call Programming Guide
|
||||||
|
.Re
|
||||||
|
.Rs
|
||||||
|
.%B Rpcgen Programming Guide
|
||||||
|
.Re
|
||||||
|
.Rs
|
||||||
|
.%B RPC: Remote Procedure Call Protocol Specification
|
||||||
|
.%O RFC1050, Sun Microsystems Inc., USC-ISI
|
||||||
|
.Re
|
||||||
1726
libtirpc-1.3.1/man/rpc_soc.3t
Normal file
1726
libtirpc-1.3.1/man/rpc_soc.3t
Normal file
File diff suppressed because it is too large
Load Diff
267
libtirpc-1.3.1/man/rpc_svc_calls.3t
Normal file
267
libtirpc-1.3.1/man/rpc_svc_calls.3t
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
.\" @(#)rpc_svc_calls.3n 1.28 93/05/10 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_svc_calls 1.5 89/07/25 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $NetBSD: rpc_svc_calls.3,v 1.1 2000/06/02 23:11:13 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_svc_calls.3,v 1.8 2003/09/08 19:57:15 ru Exp $
|
||||||
|
.Dd May 3, 1993
|
||||||
|
.Dt RPC_SVC_CALLS 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm svc_dg_enablecache ,
|
||||||
|
.Nm svc_exit ,
|
||||||
|
.Nm svc_fdset ,
|
||||||
|
.Nm svc_freeargs ,
|
||||||
|
.Nm svc_getargs ,
|
||||||
|
.Nm svc_getreq_common ,
|
||||||
|
.Nm svc_getreq_poll ,
|
||||||
|
.Nm svc_getreqset ,
|
||||||
|
.Nm svc_getrpccaller ,
|
||||||
|
.Nm svc_pollset ,
|
||||||
|
.Nm svc_run ,
|
||||||
|
.Nm svc_sendreply
|
||||||
|
.Nd library routines for RPC servers
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft int
|
||||||
|
.Fn svc_dg_enablecache "SVCXPRT *xprt" "const unsigned cache_size"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_exit "void"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn svc_freeargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn svc_getargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_getreq_common "const int fd"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_getreq_poll "struct pollfd *pfdp" "const int pollretval"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_getreqset "fd_set * rdfds"
|
||||||
|
.Ft "struct netbuf *"
|
||||||
|
.Fn svc_getrpccaller "const SVCXPRT *xprt"
|
||||||
|
.Ft "struct cmsgcred *"
|
||||||
|
.Fn __svc_getcallercreds "const SVCXPRT *xprt"
|
||||||
|
.Vt struct pollfd svc_pollset[FD_SETSIZE];
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_run "void"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn svc_sendreply "SVCXPRT *xprt" "xdrproc_t outproc" "char *out"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are part of the
|
||||||
|
RPC
|
||||||
|
library which allows C language programs to make procedure
|
||||||
|
calls on other machines across the network.
|
||||||
|
.Pp
|
||||||
|
These routines are associated with the server side of the
|
||||||
|
RPC mechanism.
|
||||||
|
Some of them are called by the server side dispatch function,
|
||||||
|
while others
|
||||||
|
(such as
|
||||||
|
.Fn svc_run )
|
||||||
|
are called when the server is initiated.
|
||||||
|
.\" .Pp
|
||||||
|
.\" In the current implementation, the service transport handle,
|
||||||
|
.\" .Dv SVCXPRT ,
|
||||||
|
.\" contains a single data area for decoding arguments and encoding results.
|
||||||
|
.\" Therefore, this structure cannot be freely shared between threads that call
|
||||||
|
.\" functions that do this.
|
||||||
|
.\" Routines on this page that are affected by this
|
||||||
|
.\" restriction are marked as unsafe for MT applications.
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt SVCXPRT
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width __svc_getcallercreds()
|
||||||
|
.It Fn svc_dg_enablecache
|
||||||
|
This function allocates a duplicate request cache for the
|
||||||
|
service endpoint
|
||||||
|
.Fa xprt ,
|
||||||
|
large enough to hold
|
||||||
|
.Fa cache_size
|
||||||
|
entries.
|
||||||
|
Once enabled, there is no way to disable caching.
|
||||||
|
This routine returns 0 if space necessary for a cache of the given size
|
||||||
|
was successfully allocated, and 1 otherwise.
|
||||||
|
.It Fn svc_exit
|
||||||
|
This function, when called by any of the RPC server procedure or
|
||||||
|
otherwise, causes
|
||||||
|
.Fn svc_run
|
||||||
|
to return.
|
||||||
|
.Pp
|
||||||
|
As currently implemented,
|
||||||
|
.Fn svc_exit
|
||||||
|
zeroes the
|
||||||
|
.Va svc_fdset
|
||||||
|
global variable.
|
||||||
|
If RPC server activity is to be resumed,
|
||||||
|
services must be reregistered with the RPC library
|
||||||
|
either through one of the
|
||||||
|
.Xr rpc_svc_create 3
|
||||||
|
functions, or using
|
||||||
|
.Fn xprt_register .
|
||||||
|
The
|
||||||
|
.Fn svc_exit
|
||||||
|
function
|
||||||
|
has global scope and ends all RPC server activity.
|
||||||
|
.It Xo
|
||||||
|
.Vt fd_set Va svc_fdset
|
||||||
|
.Xc
|
||||||
|
A global variable reflecting the
|
||||||
|
RPC server's read file descriptor bit mask; it is suitable as an argument
|
||||||
|
to the
|
||||||
|
.Xr select 2
|
||||||
|
system call.
|
||||||
|
This is only of interest
|
||||||
|
if service implementors do not call
|
||||||
|
.Fn svc_run ,
|
||||||
|
but rather do their own asynchronous event processing.
|
||||||
|
This variable is read-only (do not pass its address to
|
||||||
|
.Xr select 2 ! ) ,
|
||||||
|
yet it may change after calls to
|
||||||
|
.Fn svc_getreqset
|
||||||
|
or any creation routines.
|
||||||
|
.It Fn svc_freeargs
|
||||||
|
A function macro that frees any data allocated by the
|
||||||
|
RPC/XDR system when it decoded the arguments to a service procedure
|
||||||
|
using
|
||||||
|
.Fn svc_getargs .
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if the results were successfully
|
||||||
|
freed, and
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.It Fn svc_getargs
|
||||||
|
A function macro that decodes the arguments of an
|
||||||
|
RPC request associated with the RPC
|
||||||
|
service transport handle
|
||||||
|
.Fa xprt .
|
||||||
|
The
|
||||||
|
.Fa in
|
||||||
|
argument
|
||||||
|
is the address where the arguments will be placed;
|
||||||
|
.Fa inproc
|
||||||
|
is the XDR
|
||||||
|
routine used to decode the arguments.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if decoding succeeds, and
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.It Fn svc_getreq_common
|
||||||
|
This routine is called to handle a request on the given
|
||||||
|
file descriptor.
|
||||||
|
.It Fn svc_getreq_poll
|
||||||
|
This routine is only of interest if a service implementor
|
||||||
|
does not call
|
||||||
|
.Fn svc_run ,
|
||||||
|
but instead implements custom asynchronous event processing.
|
||||||
|
It is called when
|
||||||
|
.Xr poll 2
|
||||||
|
has determined that an RPC request has arrived on some RPC
|
||||||
|
file descriptors;
|
||||||
|
.Fa pollretval
|
||||||
|
is the return value from
|
||||||
|
.Xr poll 2
|
||||||
|
and
|
||||||
|
.Fa pfdp
|
||||||
|
is the array of
|
||||||
|
.Vt pollfd
|
||||||
|
structures on which the
|
||||||
|
.Xr poll 2
|
||||||
|
was done.
|
||||||
|
It is assumed to be an array large enough to
|
||||||
|
contain the maximal number of descriptors allowed.
|
||||||
|
.It Fn svc_getreqset
|
||||||
|
This routine is only of interest if a service implementor
|
||||||
|
does not call
|
||||||
|
.Fn svc_run ,
|
||||||
|
but instead implements custom asynchronous event processing.
|
||||||
|
It is called when
|
||||||
|
.Xr poll 2
|
||||||
|
has determined that an RPC
|
||||||
|
request has arrived on some RPC file descriptors;
|
||||||
|
.Fa rdfds
|
||||||
|
is the resultant read file descriptor bit mask.
|
||||||
|
The routine returns when all file descriptors
|
||||||
|
associated with the value of
|
||||||
|
.Fa rdfds
|
||||||
|
have been serviced.
|
||||||
|
.It Fn svc_getrpccaller
|
||||||
|
The approved way of getting the network address of the caller
|
||||||
|
of a procedure associated with the
|
||||||
|
RPC service transport handle
|
||||||
|
.Fa xprt .
|
||||||
|
.It Fn __svc_getcallercreds
|
||||||
|
.Em Warning :
|
||||||
|
this macro is specific to
|
||||||
|
.Fx
|
||||||
|
and thus not portable.
|
||||||
|
This macro returns a pointer to a
|
||||||
|
.Vt cmsgcred
|
||||||
|
structure, defined in
|
||||||
|
.In sys/socket.h ,
|
||||||
|
identifying the calling client.
|
||||||
|
This only works if the client is
|
||||||
|
calling the server over an
|
||||||
|
.Dv AF_LOCAL
|
||||||
|
socket.
|
||||||
|
.It Xo
|
||||||
|
.Vt struct pollfd Va svc_pollset[FD_SETSIZE] ;
|
||||||
|
.Xc
|
||||||
|
.Va svc_pollset
|
||||||
|
is an array of
|
||||||
|
.Vt pollfd
|
||||||
|
structures derived from
|
||||||
|
.Va svc_fdset[] .
|
||||||
|
It is suitable as an argument to the
|
||||||
|
.Xr poll 2
|
||||||
|
system call.
|
||||||
|
The derivation of
|
||||||
|
.Va svc_pollset
|
||||||
|
from
|
||||||
|
.Va svc_fdset
|
||||||
|
is made in the current implementation in
|
||||||
|
.Fn svc_run .
|
||||||
|
Service implementors who do not call
|
||||||
|
.Fn svc_run
|
||||||
|
and who wish to use this array must perform this derivation themselves.
|
||||||
|
.It Fn svc_run
|
||||||
|
This routine never returns.
|
||||||
|
It waits for RPC
|
||||||
|
requests to arrive, and calls the appropriate service
|
||||||
|
procedure using
|
||||||
|
.Fn svc_getreq_poll
|
||||||
|
when one arrives.
|
||||||
|
This procedure is usually waiting for the
|
||||||
|
.Xr poll 2
|
||||||
|
system call to return.
|
||||||
|
.It Fn svc_sendreply
|
||||||
|
Called by an RPC service's dispatch routine to send the results of a
|
||||||
|
remote procedure call.
|
||||||
|
The
|
||||||
|
.Fa xprt
|
||||||
|
argument
|
||||||
|
is the request's associated transport handle;
|
||||||
|
.Fa outproc
|
||||||
|
is the XDR
|
||||||
|
routine which is used to encode the results; and
|
||||||
|
.Fa out
|
||||||
|
is the address of the results.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr poll 2 ,
|
||||||
|
.Xr select 2 ,
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_svc_create 3 ,
|
||||||
|
.Xr rpc_svc_err 3 ,
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
337
libtirpc-1.3.1/man/rpc_svc_create.3t
Normal file
337
libtirpc-1.3.1/man/rpc_svc_create.3t
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
.\" @(#)rpc_svc_create.3n 1.26 93/08/26 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_svc_create 1.3 89/06/28 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_svc_create.3,v 1.7 2003/09/08 19:57:15 ru Exp $
|
||||||
|
.Dd May 3, 1993
|
||||||
|
.Dt RPC_SVC_CREATE 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_svc_create ,
|
||||||
|
.Nm svc_control ,
|
||||||
|
.Nm svc_create ,
|
||||||
|
.Nm svc_destroy ,
|
||||||
|
.Nm svc_dg_create ,
|
||||||
|
.Nm svc_fd_create ,
|
||||||
|
.Nm svc_raw_create ,
|
||||||
|
.Nm svc_tli_create ,
|
||||||
|
.Nm svc_tp_create ,
|
||||||
|
.Nm svc_vc_create
|
||||||
|
.Nd library routines for the creation of server handles
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn svc_control "SVCXPRT *svc" "const u_int req" "void *info"
|
||||||
|
.Ft int
|
||||||
|
.Fn svc_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype"
|
||||||
|
.Ft SVCXPRT *
|
||||||
|
.Fn svc_dg_create "const int fildes" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_destroy "SVCXPRT *xprt"
|
||||||
|
.Ft "SVCXPRT *"
|
||||||
|
.Fn svc_fd_create "const int fildes" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Ft "SVCXPRT *"
|
||||||
|
.Fn svc_raw_create "void"
|
||||||
|
.Ft "SVCXPRT *"
|
||||||
|
.Fn svc_tli_create "const int fildes" "const struct netconfig *netconf" "const struct t_bind *bindaddr" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Ft "SVCXPRT *"
|
||||||
|
.Fn svc_tp_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf"
|
||||||
|
.Ft "SVCXPRT *"
|
||||||
|
.Fn svc_vc_create "const int fildes" "const u_int sendsz" "const u_int recvsz"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are part of the RPC
|
||||||
|
library which allows C language programs to make procedure
|
||||||
|
calls on servers across the network.
|
||||||
|
These routines deal with the creation of service handles.
|
||||||
|
Once the handle is created, the server can be invoked by calling
|
||||||
|
.Fn svc_run .
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt SVCXPRT
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn svc_control
|
||||||
|
A function to change or retrieve various information
|
||||||
|
about a service object.
|
||||||
|
The
|
||||||
|
.Fa req
|
||||||
|
argument
|
||||||
|
indicates the type of operation and
|
||||||
|
.Fa info
|
||||||
|
is a pointer to the information.
|
||||||
|
The supported values of
|
||||||
|
.Fa req ,
|
||||||
|
their argument types, and what they do are:
|
||||||
|
.Bl -tag -width SVCGET_XID
|
||||||
|
.It Dv SVCGET_VERSQUIET
|
||||||
|
If a request is received for a program number
|
||||||
|
served by this server but the version number
|
||||||
|
is outside the range registered with the server,
|
||||||
|
an
|
||||||
|
.Dv RPC_PROGVERSMISMATCH
|
||||||
|
error will normally
|
||||||
|
be returned.
|
||||||
|
The
|
||||||
|
.Fa info
|
||||||
|
argument
|
||||||
|
should be a pointer to an
|
||||||
|
integer.
|
||||||
|
Upon successful completion of the
|
||||||
|
.Dv SVCGET_VERSQUIET
|
||||||
|
request,
|
||||||
|
.Fa *info
|
||||||
|
contains an
|
||||||
|
integer which describes the server's current
|
||||||
|
behavior: 0 indicates normal server behavior
|
||||||
|
(that is, an
|
||||||
|
.Dv RPC_PROGVERSMISMATCH
|
||||||
|
error
|
||||||
|
will be returned); 1 indicates that the out of
|
||||||
|
range request will be silently ignored.
|
||||||
|
.It Dv SVCSET_VERSQUIET
|
||||||
|
If a request is received for a program number
|
||||||
|
served by this server but the version number
|
||||||
|
is outside the range registered with the server,
|
||||||
|
an
|
||||||
|
.Dv RPC_PROGVERSMISMATCH
|
||||||
|
error will normally
|
||||||
|
be returned.
|
||||||
|
It is sometimes desirable to
|
||||||
|
change this behavior.
|
||||||
|
The
|
||||||
|
.Fa info
|
||||||
|
argument
|
||||||
|
should be a
|
||||||
|
pointer to an integer which is either 0
|
||||||
|
(indicating normal server behavior - an
|
||||||
|
.Dv RPC_PROGVERSMISMATCH
|
||||||
|
error will be returned),
|
||||||
|
or 1 (indicating that the out of range request
|
||||||
|
should be silently ignored).
|
||||||
|
.El
|
||||||
|
.It Fn svc_create
|
||||||
|
The
|
||||||
|
.Fn svc_create
|
||||||
|
function
|
||||||
|
creates server handles for all the transports
|
||||||
|
belonging to the class
|
||||||
|
.Fa nettype .
|
||||||
|
The
|
||||||
|
.Fa nettype
|
||||||
|
argument
|
||||||
|
defines a class of transports which can be used
|
||||||
|
for a particular application.
|
||||||
|
The transports are tried in left to right order in
|
||||||
|
.Ev NETPATH
|
||||||
|
variable or in top to bottom order in the netconfig database.
|
||||||
|
If
|
||||||
|
.Fa nettype
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
it defaults to
|
||||||
|
.Qq netpath .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn svc_create
|
||||||
|
function
|
||||||
|
registers itself with the rpcbind
|
||||||
|
service (see
|
||||||
|
.Xr rpcbind 8 ) .
|
||||||
|
The
|
||||||
|
.Fa dispatch
|
||||||
|
function
|
||||||
|
is called when there is a remote procedure call for the given
|
||||||
|
.Fa prognum
|
||||||
|
and
|
||||||
|
.Fa versnum ;
|
||||||
|
this requires calling
|
||||||
|
.Fn svc_run
|
||||||
|
(see
|
||||||
|
.Fn svc_run
|
||||||
|
in
|
||||||
|
.Xr rpc_svc_reg 3 ) .
|
||||||
|
If
|
||||||
|
.Fn svc_create
|
||||||
|
succeeds, it returns the number of server
|
||||||
|
handles it created,
|
||||||
|
otherwise it returns 0 and an error message is logged.
|
||||||
|
.It Fn svc_destroy
|
||||||
|
A function macro that destroys the RPC
|
||||||
|
service handle
|
||||||
|
.Fa xprt .
|
||||||
|
Destruction usually involves deallocation
|
||||||
|
of private data structures,
|
||||||
|
including
|
||||||
|
.Fa xprt
|
||||||
|
itself.
|
||||||
|
Use of
|
||||||
|
.Fa xprt
|
||||||
|
is undefined after calling this routine.
|
||||||
|
.It Fn svc_dg_create
|
||||||
|
This routine creates a connectionless RPC
|
||||||
|
service handle, and returns a pointer to it.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails, and an error message is logged.
|
||||||
|
The
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz
|
||||||
|
arguments
|
||||||
|
are arguments used to specify the size of the buffers.
|
||||||
|
If they are 0, suitable defaults are chosen.
|
||||||
|
The file descriptor
|
||||||
|
.Fa fildes
|
||||||
|
should be open and bound.
|
||||||
|
The server is not registered with
|
||||||
|
.Xr rpcbind 8 .
|
||||||
|
.Pp
|
||||||
|
Warning:
|
||||||
|
since connectionless-based RPC
|
||||||
|
messages can only hold limited amount of encoded data,
|
||||||
|
this transport cannot be used for procedures
|
||||||
|
that take large arguments or return huge results.
|
||||||
|
.It Fn svc_fd_create
|
||||||
|
This routine creates a service on top of an open and bound file descriptor,
|
||||||
|
and returns the handle to it.
|
||||||
|
Typically, this descriptor is a connected file descriptor for a
|
||||||
|
connection-oriented transport.
|
||||||
|
The
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz
|
||||||
|
arguments
|
||||||
|
indicate sizes for the send and receive buffers.
|
||||||
|
If they are 0, reasonable defaults are chosen.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails, and an error message is logged.
|
||||||
|
.It Fn svc_raw_create
|
||||||
|
This routine creates an RPC
|
||||||
|
service handle and returns a pointer to it.
|
||||||
|
The transport is really a buffer within the process's
|
||||||
|
address space, so the corresponding RPC
|
||||||
|
client should live in the same address space;
|
||||||
|
(see
|
||||||
|
.Fn clnt_raw_create
|
||||||
|
in
|
||||||
|
.Xr rpc_clnt_create 3 ) .
|
||||||
|
This routine allows simulation of RPC and acquisition of
|
||||||
|
RPC overheads (such as round trip times),
|
||||||
|
without any kernel and networking interference.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails, and an error message is logged.
|
||||||
|
.Pp
|
||||||
|
Note:
|
||||||
|
.Fn svc_run
|
||||||
|
should not be called when the raw interface is being used.
|
||||||
|
.It Fn svc_tli_create
|
||||||
|
This routine creates an RPC
|
||||||
|
server handle, and returns a pointer to it.
|
||||||
|
The
|
||||||
|
.Fa fildes
|
||||||
|
argument
|
||||||
|
is the file descriptor on which the service is listening.
|
||||||
|
If
|
||||||
|
.Fa fildes
|
||||||
|
is
|
||||||
|
.Dv RPC_ANYFD ,
|
||||||
|
it opens a file descriptor on the transport specified by
|
||||||
|
.Fa netconf .
|
||||||
|
If the file descriptor is unbound and
|
||||||
|
.Fa bindaddr
|
||||||
|
is not
|
||||||
|
.Dv NULL ,
|
||||||
|
.Fa fildes
|
||||||
|
is bound to the address specified by
|
||||||
|
.Fa bindaddr ,
|
||||||
|
otherwise
|
||||||
|
.Fa fildes
|
||||||
|
is bound to a default address chosen by the transport.
|
||||||
|
.Pp
|
||||||
|
Note: the
|
||||||
|
.Vt t_bind
|
||||||
|
structure comes from the TLI/XTI SysV interface, which
|
||||||
|
.Nx
|
||||||
|
does not use.
|
||||||
|
The structure is defined in
|
||||||
|
.In rpc/types.h
|
||||||
|
for compatibility as:
|
||||||
|
.Bd -literal
|
||||||
|
struct t_bind {
|
||||||
|
struct netbuf addr; /* network address, see rpc(3) */
|
||||||
|
unsigned int qlen; /* queue length (for listen(2)) */
|
||||||
|
};
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
In the case where the default address is chosen,
|
||||||
|
the number of outstanding connect requests is set to 8
|
||||||
|
for connection-oriented transports.
|
||||||
|
The user may specify the size of the send and receive buffers
|
||||||
|
with the arguments
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz ;
|
||||||
|
values of 0 choose suitable defaults.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails,
|
||||||
|
and an error message is logged.
|
||||||
|
The server is not registered with the
|
||||||
|
.Xr rpcbind 8
|
||||||
|
service.
|
||||||
|
.It Fn svc_tp_create
|
||||||
|
The
|
||||||
|
.Fn svc_tp_create
|
||||||
|
function
|
||||||
|
creates a server handle for the network
|
||||||
|
specified by
|
||||||
|
.Fa netconf ,
|
||||||
|
and registers itself with the rpcbind service.
|
||||||
|
The
|
||||||
|
.Fa dispatch
|
||||||
|
function
|
||||||
|
is called when there is a remote procedure call
|
||||||
|
for the given
|
||||||
|
.Fa prognum
|
||||||
|
and
|
||||||
|
.Fa versnum ;
|
||||||
|
this requires calling
|
||||||
|
.Fn svc_run .
|
||||||
|
The
|
||||||
|
.Fn svc_tp_create
|
||||||
|
function
|
||||||
|
returns the service handle if it succeeds,
|
||||||
|
otherwise a
|
||||||
|
.Dv NULL
|
||||||
|
is returned and an error message is logged.
|
||||||
|
.It Fn svc_vc_create
|
||||||
|
This routine creates a connection-oriented RPC
|
||||||
|
service and returns a pointer to it.
|
||||||
|
This routine returns
|
||||||
|
.Dv NULL
|
||||||
|
if it fails, and an error message is logged.
|
||||||
|
The users may specify the size of the send and receive buffers
|
||||||
|
with the arguments
|
||||||
|
.Fa sendsz
|
||||||
|
and
|
||||||
|
.Fa recvsz ;
|
||||||
|
values of 0 choose suitable defaults.
|
||||||
|
The file descriptor
|
||||||
|
.Fa fildes
|
||||||
|
should be open and bound.
|
||||||
|
The server is not registered with the
|
||||||
|
.Xr rpcbind 8
|
||||||
|
service.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_svc_calls 3 ,
|
||||||
|
.Xr rpc_svc_err 3 ,
|
||||||
|
.Xr rpc_svc_reg 3 ,
|
||||||
|
.Xr rpcbind 8
|
||||||
97
libtirpc-1.3.1/man/rpc_svc_err.3t
Normal file
97
libtirpc-1.3.1/man/rpc_svc_err.3t
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
.\" @(#)rpc_svc_err.3n 1.23 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_svc_err 1.4 89/06/28 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $NetBSD: rpc_svc_err.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_svc_err.3,v 1.4 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.Dd May 3, 1993
|
||||||
|
.Dt RPC_SVC_ERR 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_svc_err ,
|
||||||
|
.Nm svcerr_auth ,
|
||||||
|
.Nm svcerr_decode ,
|
||||||
|
.Nm svcerr_noproc ,
|
||||||
|
.Nm svcerr_noprog ,
|
||||||
|
.Nm svcerr_progvers ,
|
||||||
|
.Nm svcerr_systemerr ,
|
||||||
|
.Nm svcerr_weakauth
|
||||||
|
.Nd library routines for server side remote procedure call errors
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_auth "SVCXPRT *xprt" "enum auth_stat why"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_decode "SVCXPRT *xprt"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_noproc "SVCXPRT *xprt"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_noprog "SVCXPRT *xprt"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_progvers "SVCXPRT *xprt" "rpcvers_t low_vers" "rpcvers_t high_vers"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_systemerr "SVCXPRT *xprt"
|
||||||
|
.Ft void
|
||||||
|
.Fn svcerr_weakauth "SVCXPRT *xprt"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are part of the RPC
|
||||||
|
library which allows C language programs to make procedure
|
||||||
|
calls on other machines across the network.
|
||||||
|
.Pp
|
||||||
|
These routines can be called by the server side
|
||||||
|
dispatch function if there is any error in the
|
||||||
|
transaction with the client.
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt SVCXPRT
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn svcerr_auth
|
||||||
|
Called by a service dispatch routine that refuses to perform
|
||||||
|
a remote procedure call due to an authentication error.
|
||||||
|
.It Fn svcerr_decode
|
||||||
|
Called by a service dispatch routine that cannot successfully
|
||||||
|
decode the remote arguments
|
||||||
|
(see
|
||||||
|
.Fn svc_getargs
|
||||||
|
in
|
||||||
|
.Xr rpc_svc_reg 3 ) .
|
||||||
|
.It Fn svcerr_noproc
|
||||||
|
Called by a service dispatch routine that does not implement
|
||||||
|
the procedure number that the caller requests.
|
||||||
|
.It Fn svcerr_noprog
|
||||||
|
Called when the desired program is not registered with the
|
||||||
|
RPC package.
|
||||||
|
Service implementors usually do not need this routine.
|
||||||
|
.It Fn svcerr_progvers
|
||||||
|
Called when the desired version of a program is not registered with the
|
||||||
|
RPC package.
|
||||||
|
The
|
||||||
|
.Fa low_vers
|
||||||
|
argument
|
||||||
|
is the lowest version number,
|
||||||
|
and
|
||||||
|
.Fa high_vers
|
||||||
|
is the highest version number.
|
||||||
|
Service implementors usually do not need this routine.
|
||||||
|
.It Fn svcerr_systemerr
|
||||||
|
Called by a service dispatch routine when it detects a system
|
||||||
|
error not covered by any particular protocol.
|
||||||
|
For example, if a service can no longer allocate storage,
|
||||||
|
it may call this routine.
|
||||||
|
.It Fn svcerr_weakauth
|
||||||
|
Called by a service dispatch routine that refuses to perform
|
||||||
|
a remote procedure call due to insufficient (but correct)
|
||||||
|
authentication arguments.
|
||||||
|
The routine calls
|
||||||
|
.Fn svcerr_auth "xprt" "AUTH_TOOWEAK" .
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpc_svc_calls 3 ,
|
||||||
|
.Xr rpc_svc_create 3 ,
|
||||||
|
.Xr rpc_svc_reg 3
|
||||||
183
libtirpc-1.3.1/man/rpc_svc_reg.3t
Normal file
183
libtirpc-1.3.1/man/rpc_svc_reg.3t
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
.\" @(#)rpc_svc_reg.3n 1.32 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_svc_call 1.6 89/07/20 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $NetBSD: rpc_svc_reg.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_svc_reg.3,v 1.5 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.Dd May 3, 1993
|
||||||
|
.Dt RPC_SVC_REG 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpc_svc_reg ,
|
||||||
|
.Nm rpc_reg ,
|
||||||
|
.Nm svc_reg ,
|
||||||
|
.Nm svc_unreg ,
|
||||||
|
.Nm svc_auth_reg ,
|
||||||
|
.Nm xprt_register ,
|
||||||
|
.Nm xprt_unregister
|
||||||
|
.Nd library routines for registering servers
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft int
|
||||||
|
.Fn rpc_reg "rpcprog_t prognum" "rpcvers_t versnum" "rpcproc_t procnum" "char *(*procname)()" "xdrproc_t inproc" "xdrproc_t outproc" "char *nettype"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn svc_reg "SVCXPRT *xprt" "const rpcprog_t prognum" "const rpcvers_t versnum" "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const struct netconfig *netconf"
|
||||||
|
.Ft void
|
||||||
|
.Fn svc_unreg "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||||
|
.Ft int
|
||||||
|
.Fn svc_auth_reg "int cred_flavor" "enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *)"
|
||||||
|
.Ft void
|
||||||
|
.Fn xprt_register "SVCXPRT *xprt"
|
||||||
|
.Ft void
|
||||||
|
.Fn xprt_unregister "SVCXPRT *xprt"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are a part of the RPC
|
||||||
|
library which allows the RPC
|
||||||
|
servers to register themselves with rpcbind
|
||||||
|
(see
|
||||||
|
.Xr rpcbind 8 ) ,
|
||||||
|
and associate the given program and version
|
||||||
|
number with the dispatch function.
|
||||||
|
When the RPC server receives a RPC request, the library invokes the
|
||||||
|
dispatch routine with the appropriate arguments.
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt SVCXPRT
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn rpc_reg
|
||||||
|
Register program
|
||||||
|
.Fa prognum ,
|
||||||
|
procedure
|
||||||
|
.Fa procname ,
|
||||||
|
and version
|
||||||
|
.Fa versnum
|
||||||
|
with the RPC
|
||||||
|
service package.
|
||||||
|
If a request arrives for program
|
||||||
|
.Fa prognum ,
|
||||||
|
version
|
||||||
|
.Fa versnum ,
|
||||||
|
and procedure
|
||||||
|
.Fa procnum ,
|
||||||
|
.Fa procname
|
||||||
|
is called with a pointer to its argument(s);
|
||||||
|
.Fa procname
|
||||||
|
should return a pointer to its static result(s);
|
||||||
|
.Fa inproc
|
||||||
|
is the XDR function used to decode the arguments while
|
||||||
|
.Fa outproc
|
||||||
|
is the XDR function used to encode the results.
|
||||||
|
Procedures are registered on all available transports of the class
|
||||||
|
.Fa nettype .
|
||||||
|
See
|
||||||
|
.Xr rpc 3 .
|
||||||
|
This routine returns 0 if the registration succeeded,
|
||||||
|
\-1 otherwise.
|
||||||
|
.It Fn svc_reg
|
||||||
|
Associates
|
||||||
|
.Fa prognum
|
||||||
|
and
|
||||||
|
.Fa versnum
|
||||||
|
with the service dispatch procedure,
|
||||||
|
.Fa dispatch .
|
||||||
|
If
|
||||||
|
.Fa netconf
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
the service is not registered with the
|
||||||
|
.Xr rpcbind 8
|
||||||
|
service.
|
||||||
|
If
|
||||||
|
.Fa netconf
|
||||||
|
is non-zero,
|
||||||
|
then a mapping of the triple
|
||||||
|
.Bq Fa prognum , versnum , netconf->nc_netid
|
||||||
|
to
|
||||||
|
.Fa xprt->xp_ltaddr
|
||||||
|
is established with the local rpcbind
|
||||||
|
service.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn svc_reg
|
||||||
|
routine returns 1 if it succeeds,
|
||||||
|
and 0 otherwise.
|
||||||
|
.It Fn svc_unreg
|
||||||
|
Remove from the rpcbind
|
||||||
|
service, all mappings of the triple
|
||||||
|
.Bq Fa prognum , versnum , No all-transports
|
||||||
|
to network address
|
||||||
|
and all mappings within the RPC service package
|
||||||
|
of the double
|
||||||
|
.Bq Fa prognum , versnum
|
||||||
|
to dispatch routines.
|
||||||
|
.It Fn svc_auth_reg
|
||||||
|
Registers the service authentication routine
|
||||||
|
.Fa handler
|
||||||
|
with the dispatch mechanism so that it can be
|
||||||
|
invoked to authenticate RPC requests received
|
||||||
|
with authentication type
|
||||||
|
.Fa cred_flavor .
|
||||||
|
This interface allows developers to add new authentication
|
||||||
|
types to their RPC applications without needing to modify
|
||||||
|
the libraries.
|
||||||
|
Service implementors usually do not need this routine.
|
||||||
|
.Pp
|
||||||
|
Typical service application would call
|
||||||
|
.Fn svc_auth_reg
|
||||||
|
after registering the service and prior to calling
|
||||||
|
.Fn svc_run .
|
||||||
|
When needed to process an RPC credential of type
|
||||||
|
.Fa cred_flavor ,
|
||||||
|
the
|
||||||
|
.Fa handler
|
||||||
|
procedure will be called with two arguments,
|
||||||
|
.Fa "struct svc_req *rqst"
|
||||||
|
and
|
||||||
|
.Fa "struct rpc_msg *msg" ,
|
||||||
|
and is expected to return a valid
|
||||||
|
.Vt "enum auth_stat"
|
||||||
|
value.
|
||||||
|
There is no provision to change or delete an authentication handler
|
||||||
|
once registered.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn svc_auth_reg
|
||||||
|
routine returns 0 if the registration is successful,
|
||||||
|
1 if
|
||||||
|
.Fa cred_flavor
|
||||||
|
already has an authentication handler registered for it,
|
||||||
|
and \-1 otherwise.
|
||||||
|
.It Fn xprt_register
|
||||||
|
After RPC service transport handle
|
||||||
|
.Fa xprt
|
||||||
|
is created, it is registered with the RPC
|
||||||
|
service package.
|
||||||
|
This routine modifies the global variable
|
||||||
|
.Va svc_fdset
|
||||||
|
(see
|
||||||
|
.Xr rpc_svc_calls 3 ) .
|
||||||
|
Service implementors usually do not need this routine.
|
||||||
|
.It Fn xprt_unregister
|
||||||
|
Before an RPC service transport handle
|
||||||
|
.Fa xprt
|
||||||
|
is destroyed, it unregisters itself with the
|
||||||
|
RPC service package.
|
||||||
|
This routine modifies the global variable
|
||||||
|
.Va svc_fdset
|
||||||
|
(see
|
||||||
|
.Xr rpc_svc_calls 3 ) .
|
||||||
|
Service implementors usually do not need this routine.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr select 2 ,
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr rpcbind 3 ,
|
||||||
|
.Xr rpc_svc_calls 3 ,
|
||||||
|
.Xr rpc_svc_create 3 ,
|
||||||
|
.Xr rpc_svc_err 3 ,
|
||||||
|
.Xr rpcbind 8
|
||||||
101
libtirpc-1.3.1/man/rpc_xdr.3t
Normal file
101
libtirpc-1.3.1/man/rpc_xdr.3t
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
.\" @(#)rpc_xdr.3n 1.24 93/08/31 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" @(#)rpc_xdr.new 1.1 89/04/06 SMI;
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpc_xdr.3,v 1.3 2001/10/03 16:47:56 bde Exp $
|
||||||
|
.Dd May 3, 1993
|
||||||
|
.Dt RPC_XDR 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm xdr_accepted_reply ,
|
||||||
|
.Nm xdr_authsys_parms ,
|
||||||
|
.Nm xdr_callhdr ,
|
||||||
|
.Nm xdr_callmsg ,
|
||||||
|
.Nm xdr_opaque_auth ,
|
||||||
|
.Nm xdr_rejected_reply ,
|
||||||
|
.Nm xdr_replymsg
|
||||||
|
.Nd XDR library routines for remote procedure calls
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_authsys_parms "XDR *xdrs" "struct authsys_parms *aupp"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_callhdr "XDR *xdrs" "struct rpc_msg *chdr"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_callmsg "XDR *xdrs" "struct rpc_msg *cmsg"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_opaque_auth "XDR *xdrs" "struct opaque_auth *ap"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines are used for describing the
|
||||||
|
RPC messages in XDR language.
|
||||||
|
They should normally be used by those who do not
|
||||||
|
want to use the RPC
|
||||||
|
package directly.
|
||||||
|
These routines return
|
||||||
|
.Dv TRUE
|
||||||
|
if they succeed,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
.Sh Routines
|
||||||
|
See
|
||||||
|
.Xr rpc 3
|
||||||
|
for the definition of the
|
||||||
|
.Vt XDR
|
||||||
|
data structure.
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn xdr_accepted_reply
|
||||||
|
Used to translate between RPC
|
||||||
|
reply messages and their external representation.
|
||||||
|
It includes the status of the RPC
|
||||||
|
call in the XDR language format.
|
||||||
|
In the case of success, it also includes the call results.
|
||||||
|
.It Fn xdr_authsys_parms
|
||||||
|
Used for describing
|
||||||
|
.Ux
|
||||||
|
operating system credentials.
|
||||||
|
It includes machine-name, uid, gid list, etc.
|
||||||
|
.It Fn xdr_callhdr
|
||||||
|
Used for describing
|
||||||
|
RPC
|
||||||
|
call header messages.
|
||||||
|
It encodes the static part of the call message header in the
|
||||||
|
XDR language format.
|
||||||
|
It includes information such as transaction
|
||||||
|
ID, RPC version number, program and version number.
|
||||||
|
.It Fn xdr_callmsg
|
||||||
|
Used for describing
|
||||||
|
RPC call messages.
|
||||||
|
This includes all the RPC
|
||||||
|
call information such as transaction
|
||||||
|
ID, RPC version number, program number, version number,
|
||||||
|
authentication information, etc.
|
||||||
|
This is normally used by servers to determine information about the client
|
||||||
|
RPC call.
|
||||||
|
.It Fn xdr_opaque_auth
|
||||||
|
Used for describing RPC
|
||||||
|
opaque authentication information messages.
|
||||||
|
.It Fn xdr_rejected_reply
|
||||||
|
Used for describing RPC reply messages.
|
||||||
|
It encodes the rejected RPC message in the XDR language format.
|
||||||
|
The message could be rejected either because of version
|
||||||
|
number mis-match or because of authentication errors.
|
||||||
|
.It Fn xdr_replymsg
|
||||||
|
Used for describing RPC
|
||||||
|
reply messages.
|
||||||
|
It translates between the
|
||||||
|
RPC reply message and its external representation.
|
||||||
|
This reply could be either an acceptance,
|
||||||
|
rejection or
|
||||||
|
.Dv NULL .
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr xdr 3
|
||||||
194
libtirpc-1.3.1/man/rpcbind.3t
Normal file
194
libtirpc-1.3.1/man/rpcbind.3t
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
.\" @(#)rpcbind.3n 1.25 93/05/07 SMI; from SVr4
|
||||||
|
.\" Copyright 1989 AT&T
|
||||||
|
.\" Copyright (c) 1988 Sun Microsystem's, Inc. - All Right's Reserved.
|
||||||
|
.\" $NetBSD: rpcbind.3,v 1.2 2000/06/03 18:47:28 fvdl Exp $
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rpcbind.3,v 1.5 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.Dd May 7, 1993
|
||||||
|
.Dt RPCBIND 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rpcb_getmaps ,
|
||||||
|
.Nm rpcb_getaddr ,
|
||||||
|
.Nm rpcb_gettime ,
|
||||||
|
.Nm rpcb_rmtcall ,
|
||||||
|
.Nm rpcb_set ,
|
||||||
|
.Nm rpcb_unset
|
||||||
|
.Nd library routines for RPC bind service
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpc.h
|
||||||
|
.Ft "rpcblist *"
|
||||||
|
.Fn rpcb_getmaps "const struct netconfig *netconf" "const char *host"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpcb_getaddr "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "struct netbuf *svcaddr" "const char *host"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpcb_gettime "const char *host" "time_t * timep"
|
||||||
|
.Ft "enum clnt_stat"
|
||||||
|
.Fn rpcb_rmtcall "const struct netconfig *netconf" "const char *host" "const rpcprog_t prognum, const rpcvers_t versnum" "const rpcproc_t procnum, const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "const caddr_t out" "const struct timeval tout, const struct netbuf *svcaddr"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpcb_set "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct netbuf *svcaddr"
|
||||||
|
.Ft bool_t
|
||||||
|
.Fn rpcb_unset "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These routines allow client C programs to make procedure
|
||||||
|
calls to the RPC binder service.
|
||||||
|
(see
|
||||||
|
.Xr rpcbind 8 )
|
||||||
|
maintains a list of mappings between programs
|
||||||
|
and their universal addresses.
|
||||||
|
.Sh Routines
|
||||||
|
.Bl -tag -width XXXXX
|
||||||
|
.It Fn rpcb_getmaps
|
||||||
|
An interface to the rpcbind service,
|
||||||
|
which returns a list of the current
|
||||||
|
RPC program-to-address mappings on
|
||||||
|
.Fa host .
|
||||||
|
It uses the transport specified through
|
||||||
|
.Fa netconf
|
||||||
|
to contact the remote rpcbind
|
||||||
|
service on
|
||||||
|
.Fa host .
|
||||||
|
This routine will return
|
||||||
|
.Dv NULL ,
|
||||||
|
if the remote rpcbind could not be contacted.
|
||||||
|
.It Fn rpcb_getaddr
|
||||||
|
An interface to the rpcbind
|
||||||
|
service, which finds the address of the service on
|
||||||
|
.Fa host
|
||||||
|
that is registered with program number
|
||||||
|
.Fa prognum ,
|
||||||
|
version
|
||||||
|
.Fa versnum ,
|
||||||
|
and speaks the transport protocol associated with
|
||||||
|
.Fa netconf .
|
||||||
|
The address found is returned in
|
||||||
|
.Fa svcaddr .
|
||||||
|
The
|
||||||
|
.Fa svcaddr
|
||||||
|
argument
|
||||||
|
should be preallocated.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds.
|
||||||
|
A return value of
|
||||||
|
.Dv FALSE
|
||||||
|
means that the mapping does not exist
|
||||||
|
or that the RPC
|
||||||
|
system failed to contact the remote
|
||||||
|
rpcbind service.
|
||||||
|
In the latter case, the global variable
|
||||||
|
.Va rpc_createerr
|
||||||
|
(see
|
||||||
|
.Xr rpc_clnt_create 3 )
|
||||||
|
contains the
|
||||||
|
RPC status.
|
||||||
|
.It Fn rpcb_gettime
|
||||||
|
This routine returns the time on
|
||||||
|
.Fa host
|
||||||
|
in
|
||||||
|
.Fa timep .
|
||||||
|
If
|
||||||
|
.Fa host
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
.Fn rpcb_gettime
|
||||||
|
returns the time on its own machine.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds,
|
||||||
|
.Dv FALSE
|
||||||
|
if it fails.
|
||||||
|
The
|
||||||
|
.Fn rpcb_gettime
|
||||||
|
function
|
||||||
|
can be used to synchronize the time between the
|
||||||
|
client and the remote server.
|
||||||
|
.It Fn rpcb_rmtcall
|
||||||
|
An interface to the rpcbind service, which instructs
|
||||||
|
rpcbind on
|
||||||
|
.Fa host
|
||||||
|
to make an RPC
|
||||||
|
call on your behalf to a procedure on that host.
|
||||||
|
The
|
||||||
|
.Fn netconfig
|
||||||
|
structure should correspond to a connectionless transport.
|
||||||
|
The
|
||||||
|
.Fa svcaddr
|
||||||
|
argument
|
||||||
|
will be modified to the server's address if the procedure succeeds
|
||||||
|
(see
|
||||||
|
.Fn rpc_call
|
||||||
|
and
|
||||||
|
.Fn clnt_call
|
||||||
|
in
|
||||||
|
.Xr rpc_clnt_calls 3
|
||||||
|
for the definitions of other arguments).
|
||||||
|
.Pp
|
||||||
|
This procedure should normally be used for a
|
||||||
|
.Dq ping
|
||||||
|
and nothing else.
|
||||||
|
This routine allows programs to do lookup and call, all in one step.
|
||||||
|
.Pp
|
||||||
|
Note: Even if the server is not running
|
||||||
|
.Fn rpcb_rmtcall
|
||||||
|
does not return any error messages to the caller.
|
||||||
|
In such a case, the caller times out.
|
||||||
|
.Pp
|
||||||
|
Note:
|
||||||
|
.Fn rpcb_rmtcall
|
||||||
|
is only available for connectionless transports.
|
||||||
|
.It Fn rpcb_set
|
||||||
|
An interface to the rpcbind
|
||||||
|
service, which establishes a mapping between the triple
|
||||||
|
.Bq Fa prognum , versnum , netconf->nc_netid
|
||||||
|
and
|
||||||
|
.Fa svcaddr
|
||||||
|
on the machine's rpcbind
|
||||||
|
service.
|
||||||
|
The value of
|
||||||
|
.Fa nc_netid
|
||||||
|
must correspond to a network identifier that is defined by the
|
||||||
|
netconfig database.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
(See also
|
||||||
|
.Fn svc_reg
|
||||||
|
in
|
||||||
|
.Xr rpc_svc_calls 3 . )
|
||||||
|
If there already exists such an entry with rpcbind,
|
||||||
|
.Fn rpcb_set
|
||||||
|
will fail.
|
||||||
|
.It Fn rpcb_unset
|
||||||
|
An interface to the rpcbind
|
||||||
|
service, which destroys the mapping between the triple
|
||||||
|
.Bq Fa prognum , versnum , netconf->nc_netid
|
||||||
|
and the address on the machine's rpcbind
|
||||||
|
service.
|
||||||
|
If
|
||||||
|
.Fa netconf
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
.Fn rpcb_unset
|
||||||
|
destroys all mapping between the triple
|
||||||
|
.Bq Fa prognum , versnum , No all-transports
|
||||||
|
and the addresses on the machine's rpcbind service.
|
||||||
|
This routine returns
|
||||||
|
.Dv TRUE
|
||||||
|
if it succeeds,
|
||||||
|
.Dv FALSE
|
||||||
|
otherwise.
|
||||||
|
Only the owner of the service or the super-user can destroy the mapping.
|
||||||
|
(See also
|
||||||
|
.Fn svc_unreg
|
||||||
|
in
|
||||||
|
.Xr rpc_svc_calls 3 . )
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc_clnt_calls 3 ,
|
||||||
|
.Xr rpc_svc_calls 3 ,
|
||||||
|
.Xr rpcbind 8 ,
|
||||||
|
.Xr rpcinfo 8
|
||||||
222
libtirpc-1.3.1/man/rpcsec_gss.3t
Normal file
222
libtirpc-1.3.1/man/rpcsec_gss.3t
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
|
||||||
|
.\" Authors: Doug Rabson <dfr@rabson.org>
|
||||||
|
.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.Dd January 26, 2010
|
||||||
|
.Dt RPC_GSS_SECCREATE 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm RPCSEC_GSS
|
||||||
|
.Nd "GSS-API based authentication for RPC"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In rpc/rpcsec_gss.h
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
is a security mechanism for the RPC protocol.
|
||||||
|
It uses the Generic Security Service API (GSS-API) to establish a
|
||||||
|
security context between a client and a server and to ensure that all
|
||||||
|
subsequent communication between client and server are properly
|
||||||
|
authenticated.
|
||||||
|
Optionally, extra protection can be applied to the connection.
|
||||||
|
The integrity service uses checksums to ensure that all data sent by
|
||||||
|
a peer is received without modification.
|
||||||
|
The privacy service uses encryption to ensure that no third party can
|
||||||
|
access the data for a connection.
|
||||||
|
.Pp
|
||||||
|
To use this system, an application must first use
|
||||||
|
.Fn rpc_gss_seccreate
|
||||||
|
to establish a security context.
|
||||||
|
.Sh DATA STRUCTURES
|
||||||
|
Data structures used by
|
||||||
|
.Nm
|
||||||
|
appear below.
|
||||||
|
.Bl -tag -width "MMMM"
|
||||||
|
.It Vt rpc_gss_service_t
|
||||||
|
This type defines the types of security service required for
|
||||||
|
.Fn rpc_gss_seccreate .
|
||||||
|
.Bd -literal
|
||||||
|
typedef enum {
|
||||||
|
rpc_gss_svc_default = 0,
|
||||||
|
rpc_gss_svc_none = 1,
|
||||||
|
rpc_gss_svc_integrity = 2,
|
||||||
|
rpc_gss_svc_privacy = 3
|
||||||
|
} rpc_gss_service_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_options_ret_t
|
||||||
|
This structure contains various optional values which are used while
|
||||||
|
creating a security context.
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
int req_flags; /* GSS request bits */
|
||||||
|
int time_req; /* requested lifetime */
|
||||||
|
gss_cred_id_t my_cred; /* GSS credential */
|
||||||
|
gss_channel_bindings_t input_channel_bindings;
|
||||||
|
} rpc_gss_options_req_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_options_ret_t
|
||||||
|
Various details of the created security context are returned using
|
||||||
|
this structure.
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
int major_status;
|
||||||
|
int minor_status;
|
||||||
|
u_int rpcsec_version;
|
||||||
|
int ret_flags;
|
||||||
|
int time_req;
|
||||||
|
gss_ctx_id_t gss_context;
|
||||||
|
char actual_mechanism[MAX_GSS_MECH];
|
||||||
|
} rpc_gss_options_ret_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_principal_t
|
||||||
|
This type is used to refer to an client principal which is represented
|
||||||
|
in GSS-API exported name form
|
||||||
|
(see
|
||||||
|
.Xr gss_export_name 3
|
||||||
|
for more details).
|
||||||
|
Names in this format may be stored in access control lists or compared
|
||||||
|
with other names in exported name form.
|
||||||
|
This structure is returned by
|
||||||
|
.Fn rpc_gss_get_principal_name
|
||||||
|
and is also referenced by the
|
||||||
|
.Vt rpc_gss_rawcred_t
|
||||||
|
structure.
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
int len;
|
||||||
|
char name[1];
|
||||||
|
} *rpc_gss_principal_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_rawcred_t
|
||||||
|
This structure is used to access the raw credentials associated with a
|
||||||
|
security context.
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
u_int version; /* RPC version number */
|
||||||
|
const char *mechanism; /* security mechanism */
|
||||||
|
const char *qop; /* quality of protection */
|
||||||
|
rpc_gss_principal_t client_principal; /* client name */
|
||||||
|
const char *svc_principal; /* server name */
|
||||||
|
rpc_gss_service_t service; /* service type */
|
||||||
|
} rpc_gss_rawcred_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_ucred_t
|
||||||
|
Unix credentials which are derived form the raw credentials,
|
||||||
|
accessed via
|
||||||
|
.Fn rpc_gss_getcred .
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
uid_t uid; /* user ID */
|
||||||
|
gid_t gid; /* group ID */
|
||||||
|
short gidlen;
|
||||||
|
gid_t *gidlist; /* list of groups */
|
||||||
|
} rpc_gss_ucred_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_lock_t
|
||||||
|
Structure used to enforce a particular QOP and service.
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
bool_t locked;
|
||||||
|
rpc_gss_rawcred_t *raw_cred;
|
||||||
|
} rpc_gss_lock_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_callback_t
|
||||||
|
Callback structure used by
|
||||||
|
.Fn rpc_gss_set_callback .
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
u_int program; /* RPC program number */
|
||||||
|
u_int version; /* RPC version number */
|
||||||
|
/* user defined callback */
|
||||||
|
bool_t (*callback)(struct svc_req *req,
|
||||||
|
gss_cred_id_t deleg,
|
||||||
|
gss_ctx_id_t gss_context,
|
||||||
|
rpc_gss_lock_t *lock,
|
||||||
|
void **cookie);
|
||||||
|
} rpc_gss_callback_t;
|
||||||
|
.Ed
|
||||||
|
.It Vt rpc_gss_error_t
|
||||||
|
Structure used to return error information by
|
||||||
|
.Fn rpc_gss_get_error .
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct {
|
||||||
|
int rpc_gss_error;
|
||||||
|
int system_error; /* same as errno */
|
||||||
|
} rpc_gss_error_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for rpc_gss_error
|
||||||
|
*/
|
||||||
|
#define RPC_GSS_ER_SUCCESS 0 /* no error */
|
||||||
|
#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
|
||||||
|
.Ed
|
||||||
|
.El
|
||||||
|
.Sh INDEX
|
||||||
|
.Bl -tag -width "MMMM"
|
||||||
|
.It Xr rpc_gss_seccreate 3
|
||||||
|
Create a new security context
|
||||||
|
.It Xr rpc_gss_set_defaults 3
|
||||||
|
Set service and quality of protection for a context
|
||||||
|
.It Xr rpc_gss_max_data_length 3
|
||||||
|
Calculate maximum client message sizes.
|
||||||
|
.It Xr rpc_gss_get_error 3
|
||||||
|
Get details of the last error
|
||||||
|
.It Xr rpc_gss_mech_to_oid 3
|
||||||
|
Convert a mechanism name to the corresponding GSS-API oid.
|
||||||
|
.It Xr rpc_gss_oid_to_mech 3
|
||||||
|
Convert a GSS-API oid to a mechanism name
|
||||||
|
.It Xr rpc_gss_qop_to_num 3
|
||||||
|
Convert a quality of protection name to the corresponding number
|
||||||
|
.It Xr rpc_gss_get_mechanisms 3
|
||||||
|
Get a list of security mechanisms.
|
||||||
|
.It Xr rpc_gss_get_mech_info 3
|
||||||
|
Return extra information about a security mechanism
|
||||||
|
.It Xr rpc_gss_get_versions 3
|
||||||
|
Return the maximum and minimum supported versions of the
|
||||||
|
.Nm
|
||||||
|
protocol
|
||||||
|
.It Xr rpc_gss_is_installed 3
|
||||||
|
Query for the presence of a particular security mechanism
|
||||||
|
.It Xr rpc_gss_set_svc_name 3
|
||||||
|
Set the name of a service principal which matches a given RPC program
|
||||||
|
plus version pair
|
||||||
|
.It Xr rpc_gss_getcred 3
|
||||||
|
Get credential details for the security context of an RPC request
|
||||||
|
.It Xr rpc_gss_set_callback 3
|
||||||
|
Install a callback routine which is called on the server when new
|
||||||
|
security contexts are created
|
||||||
|
.It Xr rpc_gss_get_principal_name 3
|
||||||
|
Create a client principal name from various strings
|
||||||
|
.It Xr rpc_gss_svc_max_data_length 3
|
||||||
|
Calculate maximum server message sizes.
|
||||||
|
.El
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
These functions are part of libtirpc.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr rpc 3 ,
|
||||||
|
.Xr gssapi 3
|
||||||
|
.Sh AUTHORS
|
||||||
|
This
|
||||||
|
manual page was written by
|
||||||
|
.An Doug Rabson Aq dfr@FreeBSD.org .
|
||||||
50
libtirpc-1.3.1/man/rtime.3t
Normal file
50
libtirpc-1.3.1/man/rtime.3t
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI
|
||||||
|
.\" $FreeBSD: src/lib/libc/rpc/rtime.3,v 1.8 2002/12/19 09:40:23 ru Exp $
|
||||||
|
.\"
|
||||||
|
.Dd November 22, 1987
|
||||||
|
.Dt RTIME 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm rtime
|
||||||
|
.Nd "get remote time"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In sys/types.h
|
||||||
|
.In sys/time.h
|
||||||
|
.In netinet/in.h
|
||||||
|
.Ft int
|
||||||
|
.Fo rtime
|
||||||
|
.Fa "struct sockaddr_in *addrp"
|
||||||
|
.Fa "struct timeval *timep"
|
||||||
|
.Fa "struct timeval *timeout"
|
||||||
|
.Fc
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn rtime
|
||||||
|
function
|
||||||
|
consults the Internet Time Server at the address pointed to by
|
||||||
|
.Fa addrp
|
||||||
|
and returns the remote time in the
|
||||||
|
.Vt timeval
|
||||||
|
struct pointed to by
|
||||||
|
.Fa timep .
|
||||||
|
Normally, the
|
||||||
|
.Tn UDP
|
||||||
|
protocol is used when consulting the Time Server.
|
||||||
|
The
|
||||||
|
.Fa timeout
|
||||||
|
argument specifies how long the
|
||||||
|
routine should wait before giving
|
||||||
|
up when waiting for a reply.
|
||||||
|
If
|
||||||
|
.Fa timeout
|
||||||
|
is specified as
|
||||||
|
.Dv NULL ,
|
||||||
|
however, the routine will instead use
|
||||||
|
.Tn TCP
|
||||||
|
and block until a reply is received from the time server.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
.Rv -std rtime
|
||||||
|
.Sh AVAILABILITY
|
||||||
|
The
|
||||||
|
.Fn rtime
|
||||||
|
function is part of libtirpc.
|
||||||
52
libtirpc-1.3.1/src/Makefile.am
Normal file
52
libtirpc-1.3.1/src/Makefile.am
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
## Process this file with automake to create Makefile.in.
|
||||||
|
|
||||||
|
## NOTE: this file doesn't really try to be complete. In particular
|
||||||
|
## `make dist' won't work at all. We're just aiming to get the
|
||||||
|
## program built. We also don't bother trying to assemble code, or
|
||||||
|
## anything like that.
|
||||||
|
|
||||||
|
noinst_HEADERS = rpc_com.h debug.h
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/tirpc -include config.h -DPORTMAP -DINET6 \
|
||||||
|
-D_GNU_SOURCE -Wall -pipe
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libtirpc.la
|
||||||
|
|
||||||
|
libtirpc_la_LDFLAGS = @LDFLAG_NOUNDEFINED@ -no-undefined -lpthread
|
||||||
|
libtirpc_la_LDFLAGS += -version-info @LT_VERSION_INFO@
|
||||||
|
|
||||||
|
libtirpc_la_SOURCES = auth_none.c auth_unix.c authunix_prot.c \
|
||||||
|
binddynport.c bindresvport.c \
|
||||||
|
clnt_bcast.c clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \
|
||||||
|
clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \
|
||||||
|
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
|
||||||
|
pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
|
||||||
|
rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
|
||||||
|
rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_auth_none.c \
|
||||||
|
svc_generic.c svc_raw.c svc_run.c svc_simple.c svc_vc.c getpeereid.c \
|
||||||
|
auth_time.c debug.c
|
||||||
|
|
||||||
|
if AUTHDES
|
||||||
|
libtirpc_la_SOURCES += auth_des.c authdes_prot.c des_crypt.c des_impl.c des_soft.c svc_auth_des.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
## XDR
|
||||||
|
libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c xdr_sizeof.c
|
||||||
|
|
||||||
|
if SYMVERS
|
||||||
|
libtirpc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libtirpc.map
|
||||||
|
endif
|
||||||
|
|
||||||
|
## Secure-RPC
|
||||||
|
if GSS
|
||||||
|
libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c \
|
||||||
|
rpc_gss_utils.c
|
||||||
|
libtirpc_la_LIBADD = $(GSSAPI_LIBS)
|
||||||
|
libtirpc_la_CFLAGS = -DHAVE_RPCSEC_GSS $(GSSAPI_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
libtirpc_la_SOURCES += key_call.c key_prot_xdr.c getpublickey.c
|
||||||
|
libtirpc_la_SOURCES += netname.c netnamer.c rpcdname.c rtime.c
|
||||||
|
|
||||||
|
CLEANFILES = cscope.* *~
|
||||||
|
DISTCLEANFILES = Makefile.in
|
||||||
500
libtirpc-1.3.1/src/auth_des.c
Normal file
500
libtirpc-1.3.1/src/auth_des.c
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1988 by Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* auth_des.c, client-side implementation of DES authentication
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <rpc/des_crypt.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_des.h>
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "nis.h"
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define USEC_PER_SEC 1000000
|
||||||
|
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
|
||||||
|
|
||||||
|
#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
|
||||||
|
#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
|
||||||
|
#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
|
||||||
|
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
|
||||||
|
|
||||||
|
extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *);
|
||||||
|
extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *);
|
||||||
|
extern int key_encryptsession_pk( char *, netobj *, des_block *);
|
||||||
|
|
||||||
|
extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *,
|
||||||
|
char **, char **);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DES authenticator operations vector
|
||||||
|
*/
|
||||||
|
static void authdes_nextverf(AUTH *);
|
||||||
|
static bool_t authdes_marshal(AUTH *, XDR *);
|
||||||
|
static bool_t authdes_validate(AUTH *, struct opaque_auth *);
|
||||||
|
static bool_t authdes_refresh(AUTH *, void *);
|
||||||
|
static void authdes_destroy(AUTH *);
|
||||||
|
|
||||||
|
static struct auth_ops *authdes_ops(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This struct is pointed to by the ah_private field of an "AUTH *"
|
||||||
|
*/
|
||||||
|
struct ad_private {
|
||||||
|
char *ad_fullname; /* client's full name */
|
||||||
|
u_int ad_fullnamelen; /* length of name, rounded up */
|
||||||
|
char *ad_servername; /* server's full name */
|
||||||
|
u_int ad_servernamelen; /* length of name, rounded up */
|
||||||
|
u_int ad_window; /* client specified window */
|
||||||
|
bool_t ad_dosync; /* synchronize? */
|
||||||
|
struct netbuf ad_syncaddr; /* remote host to synch with */
|
||||||
|
char *ad_timehost; /* remote host to synch with */
|
||||||
|
struct timeval ad_timediff; /* server's time - client's time */
|
||||||
|
u_int ad_nickname; /* server's nickname for client */
|
||||||
|
struct authdes_cred ad_cred; /* storage for credential */
|
||||||
|
struct authdes_verf ad_verf; /* storage for verifier */
|
||||||
|
struct timeval ad_timestamp; /* timestamp sent */
|
||||||
|
des_block ad_xkey; /* encrypted conversation key */
|
||||||
|
u_char ad_pkey[1024]; /* Server's actual public key */
|
||||||
|
char *ad_netid; /* Timehost netid */
|
||||||
|
char *ad_uaddr; /* Timehost uaddr */
|
||||||
|
nis_server *ad_nis_srvr; /* NIS+ server struct */
|
||||||
|
};
|
||||||
|
|
||||||
|
AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *,
|
||||||
|
const des_block *, nis_server *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* documented version of authdes_seccreate
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
servername: network name of server
|
||||||
|
win: time to live
|
||||||
|
timehost: optional hostname to sync with
|
||||||
|
ckey: optional conversation key to use
|
||||||
|
*/
|
||||||
|
|
||||||
|
AUTH *
|
||||||
|
authdes_seccreate(const char *servername, const u_int win,
|
||||||
|
const char *timehost, const des_block *ckey)
|
||||||
|
{
|
||||||
|
u_char pkey_data[1024];
|
||||||
|
netobj pkey;
|
||||||
|
AUTH *dummy;
|
||||||
|
|
||||||
|
if (! getpublickey(servername, (char *) pkey_data)) {
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"authdes_seccreate: no public key found for %s",
|
||||||
|
servername);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pkey.n_bytes = (char *) pkey_data;
|
||||||
|
pkey.n_len = (u_int)strlen((char *)pkey_data) + 1;
|
||||||
|
dummy = authdes_pk_seccreate(servername, &pkey, win, timehost,
|
||||||
|
ckey, NULL);
|
||||||
|
return (dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Slightly modified version of authdessec_create which takes the public key
|
||||||
|
* of the server principal as an argument. This spares us a call to
|
||||||
|
* getpublickey() which in the nameserver context can cause a deadlock.
|
||||||
|
*/
|
||||||
|
AUTH *
|
||||||
|
authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
|
||||||
|
const char *timehost, const des_block *ckey, nis_server *srvr)
|
||||||
|
{
|
||||||
|
AUTH *auth;
|
||||||
|
struct ad_private *ad;
|
||||||
|
char namebuf[MAXNETNAMELEN+1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate everything now
|
||||||
|
*/
|
||||||
|
auth = ALLOC(AUTH);
|
||||||
|
if (auth == NULL) {
|
||||||
|
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
ad = ALLOC(struct ad_private);
|
||||||
|
if (ad == NULL) {
|
||||||
|
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
|
||||||
|
ad->ad_timehost = NULL;
|
||||||
|
ad->ad_netid = NULL;
|
||||||
|
ad->ad_uaddr = NULL;
|
||||||
|
ad->ad_nis_srvr = NULL;
|
||||||
|
ad->ad_timediff.tv_sec = 0;
|
||||||
|
ad->ad_timediff.tv_usec = 0;
|
||||||
|
memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
|
||||||
|
if (!getnetname(namebuf))
|
||||||
|
goto failed;
|
||||||
|
ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
|
||||||
|
ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
|
||||||
|
ad->ad_servernamelen = strlen(servername);
|
||||||
|
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
|
||||||
|
|
||||||
|
if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
|
||||||
|
syslog(LOG_ERR, "authdes_seccreate: out of memory");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
if (timehost != NULL) {
|
||||||
|
ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
|
||||||
|
if (ad->ad_timehost == NULL) {
|
||||||
|
syslog(LOG_ERR, "authdes_seccreate: out of memory");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
|
||||||
|
ad->ad_dosync = TRUE;
|
||||||
|
} else if (srvr != NULL) {
|
||||||
|
ad->ad_nis_srvr = srvr; /* transient */
|
||||||
|
ad->ad_dosync = TRUE;
|
||||||
|
} else {
|
||||||
|
ad->ad_dosync = FALSE;
|
||||||
|
}
|
||||||
|
memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
|
||||||
|
memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
|
||||||
|
ad->ad_window = window;
|
||||||
|
if (ckey == NULL) {
|
||||||
|
if (key_gendes(&auth->ah_key) < 0) {
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"authdes_seccreate: keyserv(1m) is unable to generate session key");
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auth->ah_key = *ckey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up auth handle
|
||||||
|
*/
|
||||||
|
auth->ah_cred.oa_flavor = AUTH_DES;
|
||||||
|
auth->ah_verf.oa_flavor = AUTH_DES;
|
||||||
|
auth->ah_ops = authdes_ops();
|
||||||
|
auth->ah_private = (caddr_t)ad;
|
||||||
|
|
||||||
|
if (!authdes_refresh(auth, NULL)) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
ad->ad_nis_srvr = NULL; /* not needed any longer */
|
||||||
|
return (auth);
|
||||||
|
|
||||||
|
failed:
|
||||||
|
if (auth)
|
||||||
|
FREE(auth, sizeof (AUTH));
|
||||||
|
if (ad) {
|
||||||
|
if (ad->ad_fullname)
|
||||||
|
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
|
||||||
|
if (ad->ad_servername)
|
||||||
|
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
|
||||||
|
if (ad->ad_timehost)
|
||||||
|
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
|
||||||
|
if (ad->ad_netid)
|
||||||
|
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
|
||||||
|
if (ad->ad_uaddr)
|
||||||
|
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
|
||||||
|
FREE(ad, sizeof (struct ad_private));
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement the five authentication operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Next Verifier
|
||||||
|
*/
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
authdes_nextverf(AUTH *auth)
|
||||||
|
{
|
||||||
|
/* what the heck am I supposed to do??? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2. Marshal
|
||||||
|
*/
|
||||||
|
static bool_t
|
||||||
|
authdes_marshal(AUTH *auth, XDR *xdrs)
|
||||||
|
{
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||||
|
struct authdes_cred *cred = &ad->ad_cred;
|
||||||
|
struct authdes_verf *verf = &ad->ad_verf;
|
||||||
|
des_block cryptbuf[2];
|
||||||
|
des_block ivec;
|
||||||
|
int status;
|
||||||
|
int len;
|
||||||
|
rpc_inline_t *ixdr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out the "time", accounting for any time difference
|
||||||
|
* with the server if necessary.
|
||||||
|
*/
|
||||||
|
(void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
|
||||||
|
ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
|
||||||
|
ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
|
||||||
|
while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) {
|
||||||
|
ad->ad_timestamp.tv_usec -= USEC_PER_SEC;
|
||||||
|
ad->ad_timestamp.tv_sec++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR the timestamp and possibly some other things, then
|
||||||
|
* encrypt them.
|
||||||
|
*/
|
||||||
|
ixdr = (rpc_inline_t *)cryptbuf;
|
||||||
|
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec);
|
||||||
|
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec);
|
||||||
|
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
|
||||||
|
IXDR_PUT_U_INT32(ixdr, ad->ad_window);
|
||||||
|
IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1);
|
||||||
|
ivec.key.high = ivec.key.low = 0;
|
||||||
|
status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
|
||||||
|
(u_int) 2 * sizeof (des_block),
|
||||||
|
DES_ENCRYPT | DES_HW, (char *)&ivec);
|
||||||
|
} else {
|
||||||
|
status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
|
||||||
|
(u_int) sizeof (des_block),
|
||||||
|
DES_ENCRYPT | DES_HW);
|
||||||
|
}
|
||||||
|
if (DES_FAILED(status)) {
|
||||||
|
syslog(LOG_ERR, "authdes_marshal: DES encryption failure");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
ad->ad_verf.adv_xtimestamp = cryptbuf[0];
|
||||||
|
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
|
||||||
|
ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
|
||||||
|
ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
|
||||||
|
} else {
|
||||||
|
ad->ad_cred.adc_nickname = ad->ad_nickname;
|
||||||
|
ad->ad_verf.adv_winverf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialize the credential and verifier into opaque
|
||||||
|
* authentication data.
|
||||||
|
*/
|
||||||
|
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
|
||||||
|
len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
|
||||||
|
} else {
|
||||||
|
len = (1 + 1)*BYTES_PER_XDR_UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
|
||||||
|
IXDR_PUT_INT32(ixdr, AUTH_DES);
|
||||||
|
IXDR_PUT_INT32(ixdr, len);
|
||||||
|
} else {
|
||||||
|
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor));
|
||||||
|
ATTEMPT(xdr_putint32(xdrs, &len));
|
||||||
|
}
|
||||||
|
ATTEMPT(xdr_authdes_cred(xdrs, cred));
|
||||||
|
|
||||||
|
len = (2 + 1)*BYTES_PER_XDR_UNIT;
|
||||||
|
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
|
||||||
|
IXDR_PUT_INT32(ixdr, AUTH_DES);
|
||||||
|
IXDR_PUT_INT32(ixdr, len);
|
||||||
|
} else {
|
||||||
|
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor));
|
||||||
|
ATTEMPT(xdr_putint32(xdrs, &len));
|
||||||
|
}
|
||||||
|
ATTEMPT(xdr_authdes_verf(xdrs, verf));
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3. Validate
|
||||||
|
*/
|
||||||
|
static bool_t
|
||||||
|
authdes_validate(AUTH *auth, struct opaque_auth *rverf)
|
||||||
|
{
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||||
|
struct authdes_verf verf;
|
||||||
|
int status;
|
||||||
|
uint32_t *ixdr;
|
||||||
|
des_block buf;
|
||||||
|
|
||||||
|
if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) {
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
ixdr = (uint32_t *)rverf->oa_base;
|
||||||
|
buf.key.high = (uint32_t)*ixdr++;
|
||||||
|
buf.key.low = (uint32_t)*ixdr++;
|
||||||
|
verf.adv_int_u = (uint32_t)*ixdr++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrypt the timestamp
|
||||||
|
*/
|
||||||
|
status = ecb_crypt((char *)&auth->ah_key, (char *)&buf,
|
||||||
|
(u_int)sizeof (des_block), DES_DECRYPT | DES_HW);
|
||||||
|
|
||||||
|
if (DES_FAILED(status)) {
|
||||||
|
syslog(LOG_ERR, "authdes_validate: DES decryption failure");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xdr the decrypted timestamp
|
||||||
|
*/
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
ixdr = (uint32_t *)buf.c;
|
||||||
|
verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1;
|
||||||
|
verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* validate
|
||||||
|
*/
|
||||||
|
if (memcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
|
||||||
|
sizeof(struct timeval)) != 0) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("authdes_validate: verifier mismatch"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have a nickname now, let's use it
|
||||||
|
*/
|
||||||
|
ad->ad_nickname = verf.adv_nickname;
|
||||||
|
ad->ad_cred.adc_namekind = ADN_NICKNAME;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 4. Refresh
|
||||||
|
*/
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static bool_t
|
||||||
|
authdes_refresh(AUTH *auth, void *dummy)
|
||||||
|
{
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||||
|
struct authdes_cred *cred = &ad->ad_cred;
|
||||||
|
int ok;
|
||||||
|
netobj pkey;
|
||||||
|
|
||||||
|
if (ad->ad_dosync) {
|
||||||
|
ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr,
|
||||||
|
ad->ad_timehost, &(ad->ad_uaddr),
|
||||||
|
&(ad->ad_netid));
|
||||||
|
if (! ok) {
|
||||||
|
/*
|
||||||
|
* Hope the clocks are synced!
|
||||||
|
*/
|
||||||
|
ad->ad_dosync = 0;
|
||||||
|
LIBTIRPC_DEBUG(1, ("authdes_refresh: unable to synchronize clock"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ad->ad_xkey = auth->ah_key;
|
||||||
|
pkey.n_bytes = (char *)(ad->ad_pkey);
|
||||||
|
pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1;
|
||||||
|
if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("authdes_refresh: keyserv(1m) is unable to encrypt session key"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
cred->adc_fullname.key = ad->ad_xkey;
|
||||||
|
cred->adc_namekind = ADN_FULLNAME;
|
||||||
|
cred->adc_fullname.name = ad->ad_fullname;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5. Destroy
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
authdes_destroy(AUTH *auth)
|
||||||
|
{
|
||||||
|
/* LINTED pointer alignment */
|
||||||
|
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
|
||||||
|
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
|
||||||
|
if (ad->ad_timehost)
|
||||||
|
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
|
||||||
|
if (ad->ad_netid)
|
||||||
|
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
|
||||||
|
if (ad->ad_uaddr)
|
||||||
|
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
|
||||||
|
FREE(ad, sizeof (struct ad_private));
|
||||||
|
FREE(auth, sizeof(AUTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authdes_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere)
|
||||||
|
{
|
||||||
|
return ((*xfunc)(xdrs, xwhere));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct auth_ops *
|
||||||
|
authdes_ops(void)
|
||||||
|
{
|
||||||
|
static struct auth_ops ops;
|
||||||
|
extern mutex_t authdes_ops_lock;
|
||||||
|
|
||||||
|
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||||
|
|
||||||
|
mutex_lock(&authdes_ops_lock);
|
||||||
|
if (ops.ah_nextverf == NULL) {
|
||||||
|
ops.ah_nextverf = authdes_nextverf;
|
||||||
|
ops.ah_marshal = authdes_marshal;
|
||||||
|
ops.ah_validate = authdes_validate;
|
||||||
|
ops.ah_refresh = authdes_refresh;
|
||||||
|
ops.ah_destroy = authdes_destroy;
|
||||||
|
ops.ah_wrap = authdes_wrap;
|
||||||
|
ops.ah_unwrap = authdes_wrap;
|
||||||
|
}
|
||||||
|
mutex_unlock(&authdes_ops_lock);
|
||||||
|
return (&ops);
|
||||||
|
}
|
||||||
984
libtirpc-1.3.1/src/auth_gss.c
Normal file
984
libtirpc-1.3.1/src/auth_gss.c
Normal file
@ -0,0 +1,984 @@
|
|||||||
|
/*
|
||||||
|
auth_gss.c
|
||||||
|
|
||||||
|
RPCSEC_GSS client routines.
|
||||||
|
|
||||||
|
Copyright (c) 2000 The Regents of the University of Michigan.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
|
||||||
|
All rights reserved, all wrongs reversed.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. 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.
|
||||||
|
3. Neither the name of the University 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 ``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 REGENTS 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_gss.h>
|
||||||
|
#include <rpc/rpcsec_gss.h>
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static void authgss_nextverf(AUTH *);
|
||||||
|
static bool_t authgss_marshal(AUTH *, XDR *);
|
||||||
|
static bool_t authgss_refresh(AUTH *, void *);
|
||||||
|
static bool_t authgss_validate(AUTH *, struct opaque_auth *);
|
||||||
|
static void authgss_destroy(AUTH *);
|
||||||
|
static void authgss_destroy_context(AUTH *);
|
||||||
|
static bool_t authgss_wrap(AUTH *, XDR *, xdrproc_t, caddr_t);
|
||||||
|
static bool_t authgss_unwrap(AUTH *, XDR *, xdrproc_t, caddr_t);
|
||||||
|
|
||||||
|
void rpc_gss_set_error(int);
|
||||||
|
void rpc_gss_clear_error(void);
|
||||||
|
bool_t rpc_gss_oid_to_mech(rpc_gss_OID, char **);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* from mit-krb5-1.2.1 mechglue/mglueP.h:
|
||||||
|
* Array of context IDs typed by mechanism OID
|
||||||
|
*/
|
||||||
|
typedef struct gss_union_ctx_id_t {
|
||||||
|
gss_OID mech_type;
|
||||||
|
gss_ctx_id_t internal_ctx_id;
|
||||||
|
} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
|
||||||
|
|
||||||
|
static struct auth_ops authgss_ops = {
|
||||||
|
authgss_nextverf,
|
||||||
|
authgss_marshal,
|
||||||
|
authgss_validate,
|
||||||
|
authgss_refresh,
|
||||||
|
authgss_destroy,
|
||||||
|
authgss_wrap,
|
||||||
|
authgss_unwrap
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* useful as i add more mechanisms */
|
||||||
|
void
|
||||||
|
print_rpc_gss_sec(struct rpc_gss_sec *ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (libtirpc_debug_level < 4 || log_stderr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gss_log_debug("rpc_gss_sec:");
|
||||||
|
if(ptr->mech == NULL)
|
||||||
|
gss_log_debug("NULL gss_OID mech");
|
||||||
|
else {
|
||||||
|
fprintf(stderr, " mechanism_OID: {");
|
||||||
|
p = (char *)ptr->mech->elements;
|
||||||
|
for (i=0; i < ptr->mech->length; i++)
|
||||||
|
/* First byte of OIDs encoded to save a byte */
|
||||||
|
if (i == 0) {
|
||||||
|
int first, second;
|
||||||
|
if (*p < 40) {
|
||||||
|
first = 0;
|
||||||
|
second = *p;
|
||||||
|
}
|
||||||
|
else if (40 <= *p && *p < 80) {
|
||||||
|
first = 1;
|
||||||
|
second = *p - 40;
|
||||||
|
}
|
||||||
|
else if (80 <= *p && *p < 127) {
|
||||||
|
first = 2;
|
||||||
|
second = *p - 80;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Invalid value! */
|
||||||
|
first = -1;
|
||||||
|
second = -1;
|
||||||
|
}
|
||||||
|
fprintf(stderr, " %u %u", first, second);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, " %u", (unsigned char)*p++);
|
||||||
|
}
|
||||||
|
fprintf(stderr, " }\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, " qop: %d\n", ptr->qop);
|
||||||
|
fprintf(stderr, " service: %d\n", ptr->svc);
|
||||||
|
fprintf(stderr, " cred: %p\n", ptr->cred);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern pthread_mutex_t auth_ref_lock;
|
||||||
|
|
||||||
|
struct rpc_gss_data {
|
||||||
|
bool_t established; /* context established */
|
||||||
|
gss_buffer_desc gc_wire_verf; /* save GSS_S_COMPLETE NULL RPC verfier
|
||||||
|
* to process at end of context negotiation*/
|
||||||
|
CLIENT *clnt; /* client handle */
|
||||||
|
gss_name_t name; /* service name */
|
||||||
|
struct rpc_gss_sec sec; /* security tuple */
|
||||||
|
gss_ctx_id_t ctx; /* context id */
|
||||||
|
struct rpc_gss_cred gc; /* client credentials */
|
||||||
|
u_int win; /* sequence window */
|
||||||
|
int time_req; /* init_sec_context time_req */
|
||||||
|
gss_channel_bindings_t icb; /* input channel bindings */
|
||||||
|
int refcnt; /* reference count gss AUTHs */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define AUTH_PRIVATE(auth) ((struct rpc_gss_data *)auth->ah_private)
|
||||||
|
|
||||||
|
static struct timeval AUTH_TIMEOUT = { 25, 0 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
authgss_auth_get(AUTH *auth)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
mutex_lock(&auth_ref_lock);
|
||||||
|
++gd->refcnt;
|
||||||
|
mutex_unlock(&auth_ref_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
authgss_auth_put(AUTH *auth)
|
||||||
|
{
|
||||||
|
int refcnt;
|
||||||
|
struct rpc_gss_data *gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
mutex_lock(&auth_ref_lock);
|
||||||
|
refcnt = --gd->refcnt;
|
||||||
|
mutex_unlock(&auth_ref_lock);
|
||||||
|
return refcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
AUTH *
|
||||||
|
authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec)
|
||||||
|
{
|
||||||
|
AUTH *auth, *save_auth;
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
OM_uint32 min_stat = 0;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_create()");
|
||||||
|
|
||||||
|
memset(&rpc_createerr, 0, sizeof(rpc_createerr));
|
||||||
|
|
||||||
|
if ((auth = calloc(sizeof(*auth), 1)) == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if ((gd = calloc(sizeof(*gd), 1)) == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
free(auth);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
LIBTIRPC_DEBUG(3, ("authgss_create: name is %p", name));
|
||||||
|
if (name != GSS_C_NO_NAME) {
|
||||||
|
if (gss_duplicate_name(&min_stat, name, &gd->name)
|
||||||
|
!= GSS_S_COMPLETE) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
free(auth);
|
||||||
|
free(gd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gd->name = name;
|
||||||
|
|
||||||
|
LIBTIRPC_DEBUG(3, ("authgss_create: gd->name is %p", gd->name));
|
||||||
|
gd->clnt = clnt;
|
||||||
|
gd->ctx = GSS_C_NO_CONTEXT;
|
||||||
|
gd->sec = *sec;
|
||||||
|
|
||||||
|
gd->gc.gc_v = RPCSEC_GSS_VERSION;
|
||||||
|
gd->gc.gc_proc = RPCSEC_GSS_INIT;
|
||||||
|
gd->gc.gc_svc = gd->sec.svc;
|
||||||
|
|
||||||
|
auth->ah_ops = &authgss_ops;
|
||||||
|
auth->ah_private = (caddr_t)gd;
|
||||||
|
|
||||||
|
save_auth = clnt->cl_auth;
|
||||||
|
clnt->cl_auth = auth;
|
||||||
|
|
||||||
|
if (!authgss_refresh(auth, NULL))
|
||||||
|
auth = NULL;
|
||||||
|
else
|
||||||
|
authgss_auth_get(auth); /* Reference for caller */
|
||||||
|
|
||||||
|
clnt->cl_auth = save_auth;
|
||||||
|
|
||||||
|
return (auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
AUTH *
|
||||||
|
authgss_create_default(CLIENT *clnt, char *service, struct rpc_gss_sec *sec)
|
||||||
|
{
|
||||||
|
AUTH *auth;
|
||||||
|
OM_uint32 maj_stat = 0, min_stat = 0;
|
||||||
|
gss_buffer_desc sname;
|
||||||
|
gss_name_t name = GSS_C_NO_NAME;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_create_default()");
|
||||||
|
|
||||||
|
|
||||||
|
sname.value = service;
|
||||||
|
sname.length = strlen(service);
|
||||||
|
|
||||||
|
maj_stat = gss_import_name(&min_stat, &sname,
|
||||||
|
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
|
||||||
|
&name);
|
||||||
|
|
||||||
|
if (maj_stat != GSS_S_COMPLETE) {
|
||||||
|
gss_log_status("authgss_create_default: gss_import_name",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
rpc_createerr.cf_stat = RPC_AUTHERROR;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
auth = authgss_create(clnt, name, sec);
|
||||||
|
|
||||||
|
if (name != GSS_C_NO_NAME) {
|
||||||
|
LIBTIRPC_DEBUG(3, ("authgss_create_default: freeing name %p", name));
|
||||||
|
gss_release_name(&min_stat, &name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
authgss_get_private_data(AUTH *auth, struct authgss_private_data *pd)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_get_private_data()");
|
||||||
|
|
||||||
|
if (!auth || !pd)
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (!gd || !gd->established)
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
pd->pd_ctx = gd->ctx;
|
||||||
|
pd->pd_ctx_hndl = gd->gc.gc_ctx;
|
||||||
|
pd->pd_seq_win = gd->win;
|
||||||
|
/*
|
||||||
|
* We've given this away -- don't try to use it ourself any more
|
||||||
|
* Caller should call authgss_free_private_data to free data.
|
||||||
|
* This also ensures that authgss_destroy_context() won't try to
|
||||||
|
* send an RPCSEC_GSS_DESTROY request which might inappropriately
|
||||||
|
* destroy the context.
|
||||||
|
*/
|
||||||
|
gd->ctx = GSS_C_NO_CONTEXT;
|
||||||
|
gd->gc.gc_ctx.length = 0;
|
||||||
|
gd->gc.gc_ctx.value = NULL;
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
authgss_free_private_data(struct authgss_private_data *pd)
|
||||||
|
{
|
||||||
|
OM_uint32 min_stat;
|
||||||
|
gss_log_debug("in authgss_free_private_data()");
|
||||||
|
|
||||||
|
if (!pd)
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
if (pd->pd_ctx != GSS_C_NO_CONTEXT)
|
||||||
|
gss_delete_sec_context(&min_stat, &pd->pd_ctx, NULL);
|
||||||
|
gss_release_buffer(&min_stat, &pd->pd_ctx_hndl);
|
||||||
|
memset(&pd->pd_ctx_hndl, 0, sizeof(pd->pd_ctx_hndl));
|
||||||
|
pd->pd_seq_win = 0;
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
authgss_nextverf(AUTH *auth)
|
||||||
|
{
|
||||||
|
gss_log_debug("in authgss_nextverf()");
|
||||||
|
/* no action necessary */
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authgss_marshal(AUTH *auth, XDR *xdrs)
|
||||||
|
{
|
||||||
|
XDR tmpxdrs;
|
||||||
|
char tmp[MAX_AUTH_BYTES];
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
gss_buffer_desc rpcbuf, checksum;
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
bool_t xdr_stat;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_marshal()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (gd->established)
|
||||||
|
gd->gc.gc_seq++;
|
||||||
|
|
||||||
|
xdrmem_create(&tmpxdrs, tmp, sizeof(tmp), XDR_ENCODE);
|
||||||
|
|
||||||
|
if (!xdr_rpc_gss_cred(&tmpxdrs, &gd->gc)) {
|
||||||
|
XDR_DESTROY(&tmpxdrs);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
auth->ah_cred.oa_flavor = RPCSEC_GSS;
|
||||||
|
auth->ah_cred.oa_base = tmp;
|
||||||
|
auth->ah_cred.oa_length = XDR_GETPOS(&tmpxdrs);
|
||||||
|
|
||||||
|
XDR_DESTROY(&tmpxdrs);
|
||||||
|
|
||||||
|
if (!xdr_opaque_auth(xdrs, &auth->ah_cred))
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
if (gd->gc.gc_proc == RPCSEC_GSS_INIT ||
|
||||||
|
gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
|
||||||
|
return (xdr_opaque_auth(xdrs, &_null_auth));
|
||||||
|
}
|
||||||
|
/* Checksum serialized RPC header, up to and including credential. */
|
||||||
|
rpcbuf.length = XDR_GETPOS(xdrs);
|
||||||
|
XDR_SETPOS(xdrs, 0);
|
||||||
|
rpcbuf.value = XDR_INLINE(xdrs, rpcbuf.length);
|
||||||
|
|
||||||
|
maj_stat = gss_get_mic(&min_stat, gd->ctx, gd->sec.qop,
|
||||||
|
&rpcbuf, &checksum);
|
||||||
|
|
||||||
|
if (maj_stat != GSS_S_COMPLETE) {
|
||||||
|
gss_log_status("authgss_marshal: gss_get_mic",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
|
||||||
|
gd->established = FALSE;
|
||||||
|
authgss_destroy_context(auth);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
auth->ah_verf.oa_flavor = RPCSEC_GSS;
|
||||||
|
auth->ah_verf.oa_base = checksum.value;
|
||||||
|
auth->ah_verf.oa_length = checksum.length;
|
||||||
|
|
||||||
|
xdr_stat = xdr_opaque_auth(xdrs, &auth->ah_verf);
|
||||||
|
gss_release_buffer(&min_stat, &checksum);
|
||||||
|
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authgss_validate(AUTH *auth, struct opaque_auth *verf)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
u_int num, qop_state;
|
||||||
|
gss_buffer_desc signbuf, checksum;
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_validate()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (gd->established == FALSE) {
|
||||||
|
/* would like to do this only on NULL rpc --
|
||||||
|
* gc->established is good enough.
|
||||||
|
* save the on the wire verifier to validate last
|
||||||
|
* INIT phase packet after decode if the major
|
||||||
|
* status is GSS_S_COMPLETE
|
||||||
|
*/
|
||||||
|
if ((gd->gc_wire_verf.value =
|
||||||
|
mem_alloc(verf->oa_length)) == NULL) {
|
||||||
|
fprintf(stderr, "gss_validate: out of memory\n");
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
memcpy(gd->gc_wire_verf.value, verf->oa_base, verf->oa_length);
|
||||||
|
gd->gc_wire_verf.length = verf->oa_length;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd->gc.gc_proc == RPCSEC_GSS_INIT ||
|
||||||
|
gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
|
||||||
|
num = htonl(gd->win);
|
||||||
|
}
|
||||||
|
else num = htonl(gd->gc.gc_seq);
|
||||||
|
|
||||||
|
signbuf.value = #
|
||||||
|
signbuf.length = sizeof(num);
|
||||||
|
|
||||||
|
checksum.value = verf->oa_base;
|
||||||
|
checksum.length = verf->oa_length;
|
||||||
|
|
||||||
|
maj_stat = gss_verify_mic(&min_stat, gd->ctx, &signbuf,
|
||||||
|
&checksum, &qop_state);
|
||||||
|
|
||||||
|
if (maj_stat != GSS_S_COMPLETE || qop_state != gd->sec.qop) {
|
||||||
|
gss_log_status("authgss_validate: gss_verify_mic",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
|
||||||
|
gd->established = FALSE;
|
||||||
|
authgss_destroy_context(auth);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
_rpc_gss_refresh(AUTH *auth, rpc_gss_options_ret_t *options_ret)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
struct rpc_gss_init_res gr;
|
||||||
|
gss_buffer_desc *recv_tokenp, send_token;
|
||||||
|
OM_uint32 maj_stat, min_stat, call_stat, ret_flags,
|
||||||
|
time_ret;
|
||||||
|
gss_OID actual_mech_type;
|
||||||
|
char *mechanism;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_refresh()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (gd->established)
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
/* GSS context establishment loop. */
|
||||||
|
memset(&gr, 0, sizeof(gr));
|
||||||
|
recv_tokenp = GSS_C_NO_BUFFER;
|
||||||
|
|
||||||
|
print_rpc_gss_sec(&gd->sec);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* print the token we just received */
|
||||||
|
if (recv_tokenp != GSS_C_NO_BUFFER) {
|
||||||
|
gss_log_debug("The token we just received (length %lu):",
|
||||||
|
recv_tokenp->length);
|
||||||
|
gss_log_hexdump(recv_tokenp->value, recv_tokenp->length, 0);
|
||||||
|
}
|
||||||
|
maj_stat = gss_init_sec_context(&min_stat,
|
||||||
|
gd->sec.cred,
|
||||||
|
&gd->ctx,
|
||||||
|
gd->name,
|
||||||
|
gd->sec.mech,
|
||||||
|
gd->sec.req_flags,
|
||||||
|
gd->time_req,
|
||||||
|
gd->icb,
|
||||||
|
recv_tokenp,
|
||||||
|
&actual_mech_type,
|
||||||
|
&send_token,
|
||||||
|
&ret_flags,
|
||||||
|
&time_ret);
|
||||||
|
|
||||||
|
if (recv_tokenp != GSS_C_NO_BUFFER) {
|
||||||
|
gss_release_buffer(&min_stat, &gr.gr_token);
|
||||||
|
recv_tokenp = GSS_C_NO_BUFFER;
|
||||||
|
}
|
||||||
|
if (maj_stat != GSS_S_COMPLETE &&
|
||||||
|
maj_stat != GSS_S_CONTINUE_NEEDED) {
|
||||||
|
gss_log_status("gss_init_sec_context", maj_stat, min_stat);
|
||||||
|
options_ret->major_status = maj_stat;
|
||||||
|
options_ret->minor_status = min_stat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (send_token.length != 0) {
|
||||||
|
memset(&gr, 0, sizeof(gr));
|
||||||
|
|
||||||
|
/* print the token we are about to send */
|
||||||
|
gss_log_debug("The token being sent (length %lu):",
|
||||||
|
send_token.length);
|
||||||
|
gss_log_hexdump(send_token.value, send_token.length, 0);
|
||||||
|
|
||||||
|
call_stat = clnt_call(gd->clnt, NULLPROC,
|
||||||
|
(xdrproc_t)xdr_rpc_gss_init_args,
|
||||||
|
&send_token,
|
||||||
|
(xdrproc_t)xdr_rpc_gss_init_res,
|
||||||
|
(caddr_t)&gr, AUTH_TIMEOUT);
|
||||||
|
|
||||||
|
gss_release_buffer(&min_stat, &send_token);
|
||||||
|
|
||||||
|
if (call_stat != RPC_SUCCESS ||
|
||||||
|
(gr.gr_major != GSS_S_COMPLETE &&
|
||||||
|
gr.gr_major != GSS_S_CONTINUE_NEEDED)) {
|
||||||
|
options_ret->major_status = gr.gr_major;
|
||||||
|
options_ret->minor_status = gr.gr_minor;
|
||||||
|
if (call_stat != RPC_SUCCESS) {
|
||||||
|
struct rpc_err err;
|
||||||
|
clnt_geterr(gd->clnt, &err);
|
||||||
|
LIBTIRPC_DEBUG(1, ("authgss_refresh: %s errno: %s",
|
||||||
|
clnt_sperrno(call_stat), strerror(err.re_errno)));
|
||||||
|
} else
|
||||||
|
gss_log_status("authgss_refresh:",
|
||||||
|
gr.gr_major, gr.gr_minor);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gr.gr_ctx.length != 0) {
|
||||||
|
if (gd->gc.gc_ctx.value)
|
||||||
|
gss_release_buffer(&min_stat,
|
||||||
|
&gd->gc.gc_ctx);
|
||||||
|
gd->gc.gc_ctx = gr.gr_ctx;
|
||||||
|
}
|
||||||
|
if (gr.gr_token.length != 0) {
|
||||||
|
if (maj_stat != GSS_S_CONTINUE_NEEDED)
|
||||||
|
break;
|
||||||
|
recv_tokenp = &gr.gr_token;
|
||||||
|
}
|
||||||
|
gd->gc.gc_proc = RPCSEC_GSS_CONTINUE_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GSS_S_COMPLETE => check gss header verifier,
|
||||||
|
* usually checked in gss_validate
|
||||||
|
*/
|
||||||
|
if (maj_stat == GSS_S_COMPLETE) {
|
||||||
|
gss_buffer_desc bufin;
|
||||||
|
gss_buffer_desc bufout;
|
||||||
|
u_int seq, qop_state = 0;
|
||||||
|
|
||||||
|
seq = htonl(gr.gr_win);
|
||||||
|
bufin.value = (unsigned char *)&seq;
|
||||||
|
bufin.length = sizeof(seq);
|
||||||
|
bufout.value = (unsigned char *)gd->gc_wire_verf.value;
|
||||||
|
bufout.length = gd->gc_wire_verf.length;
|
||||||
|
|
||||||
|
maj_stat = gss_verify_mic(&min_stat, gd->ctx,
|
||||||
|
&bufin, &bufout, &qop_state);
|
||||||
|
|
||||||
|
if (maj_stat != GSS_S_COMPLETE
|
||||||
|
|| qop_state != gd->sec.qop) {
|
||||||
|
gss_log_status("authgss_refresh: gss_verify_mic",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
|
||||||
|
gd->established = FALSE;
|
||||||
|
authgss_destroy_context(auth);
|
||||||
|
}
|
||||||
|
rpc_gss_set_error(EPERM);
|
||||||
|
options_ret->major_status = maj_stat;
|
||||||
|
options_ret->minor_status = min_stat;
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
options_ret->major_status = GSS_S_COMPLETE;
|
||||||
|
options_ret->minor_status = 0;
|
||||||
|
options_ret->rpcsec_version = gd->gc.gc_v;
|
||||||
|
options_ret->ret_flags = ret_flags;
|
||||||
|
options_ret->time_ret = time_ret;
|
||||||
|
options_ret->gss_context = gd->ctx;
|
||||||
|
options_ret->actual_mechanism[0] = '\0';
|
||||||
|
if (rpc_gss_oid_to_mech(actual_mech_type, &mechanism)) {
|
||||||
|
strncpy(options_ret->actual_mechanism,
|
||||||
|
mechanism,
|
||||||
|
(sizeof(options_ret->actual_mechanism)-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->established = TRUE;
|
||||||
|
gd->gc.gc_proc = RPCSEC_GSS_DATA;
|
||||||
|
gd->gc.gc_seq = 0;
|
||||||
|
gd->win = gr.gr_win;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* End context negotiation loop. */
|
||||||
|
if (gd->gc.gc_proc != RPCSEC_GSS_DATA) {
|
||||||
|
if (gr.gr_token.length != 0)
|
||||||
|
gss_release_buffer(&min_stat, &gr.gr_token);
|
||||||
|
|
||||||
|
authgss_destroy(auth);
|
||||||
|
auth = NULL;
|
||||||
|
rpc_createerr.cf_stat = RPC_AUTHERROR;
|
||||||
|
rpc_gss_set_error(EPERM);
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authgss_refresh(AUTH *auth, void *dummy)
|
||||||
|
{
|
||||||
|
rpc_gss_options_ret_t ret;
|
||||||
|
|
||||||
|
memset(&ret, 0, sizeof(ret));
|
||||||
|
return _rpc_gss_refresh(auth, &ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
authgss_service(AUTH *auth, int svc)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_service()");
|
||||||
|
|
||||||
|
if (!auth)
|
||||||
|
return(FALSE);
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
if (!gd || !gd->established)
|
||||||
|
return (FALSE);
|
||||||
|
gd->sec.svc = svc;
|
||||||
|
gd->gc.gc_svc = svc;
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
authgss_destroy_context(AUTH *auth)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
OM_uint32 min_stat;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_destroy_context()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (gd->gc.gc_ctx.length != 0) {
|
||||||
|
if (gd->established) {
|
||||||
|
AUTH *save_auth = NULL;
|
||||||
|
|
||||||
|
/* Make sure we use the right auth_ops */
|
||||||
|
if (gd->clnt->cl_auth != auth) {
|
||||||
|
save_auth = gd->clnt->cl_auth;
|
||||||
|
gd->clnt->cl_auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->gc.gc_proc = RPCSEC_GSS_DESTROY;
|
||||||
|
clnt_call(gd->clnt, NULLPROC, (xdrproc_t)xdr_void, NULL,
|
||||||
|
(xdrproc_t)xdr_void, NULL, AUTH_TIMEOUT);
|
||||||
|
|
||||||
|
if (save_auth != NULL)
|
||||||
|
gd->clnt->cl_auth = save_auth;
|
||||||
|
}
|
||||||
|
gss_release_buffer(&min_stat, &gd->gc.gc_ctx);
|
||||||
|
/* XXX ANDROS check size of context - should be 8 */
|
||||||
|
memset(&gd->gc.gc_ctx, 0, sizeof(gd->gc.gc_ctx));
|
||||||
|
}
|
||||||
|
if (gd->ctx != GSS_C_NO_CONTEXT) {
|
||||||
|
gss_delete_sec_context(&min_stat, &gd->ctx, NULL);
|
||||||
|
gd->ctx = GSS_C_NO_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free saved wire verifier (if any) */
|
||||||
|
mem_free(gd->gc_wire_verf.value, gd->gc_wire_verf.length);
|
||||||
|
gd->gc_wire_verf.value = NULL;
|
||||||
|
gd->gc_wire_verf.length = 0;
|
||||||
|
|
||||||
|
gd->established = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
authgss_destroy(AUTH *auth)
|
||||||
|
{
|
||||||
|
if(authgss_auth_put(auth) == 0)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
OM_uint32 min_stat;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_destroy()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
authgss_destroy_context(auth);
|
||||||
|
|
||||||
|
LIBTIRPC_DEBUG(3, ("authgss_destroy: freeing name %p", gd->name));
|
||||||
|
if (gd->name != GSS_C_NO_NAME)
|
||||||
|
gss_release_name(&min_stat, &gd->name);
|
||||||
|
|
||||||
|
free(gd);
|
||||||
|
free(auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authgss_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_wrap()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) {
|
||||||
|
return ((*xdr_func)(xdrs, xdr_ptr));
|
||||||
|
}
|
||||||
|
return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr,
|
||||||
|
gd->ctx, gd->sec.qop,
|
||||||
|
gd->sec.svc, gd->gc.gc_seq));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authgss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
|
||||||
|
gss_log_debug("in authgss_unwrap()");
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
|
||||||
|
if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) {
|
||||||
|
return ((*xdr_func)(xdrs, xdr_ptr));
|
||||||
|
}
|
||||||
|
return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr,
|
||||||
|
gd->ctx, gd->sec.qop,
|
||||||
|
gd->sec.svc, gd->gc.gc_seq));
|
||||||
|
}
|
||||||
|
|
||||||
|
static AUTH *
|
||||||
|
_rpc_gss_seccreate_error(int system_error)
|
||||||
|
{
|
||||||
|
rpc_gss_set_error(system_error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External API: Create a GSS security context for this "clnt"
|
||||||
|
*
|
||||||
|
* clnt: a valid RPC CLIENT structure
|
||||||
|
* principal: NUL-terminated C string containing GSS principal
|
||||||
|
* mechanism: NUL-terminated C string containing GSS mechanism name
|
||||||
|
* service: GSS security value to use
|
||||||
|
* qop: NUL-terminated C string containing QOP name
|
||||||
|
* req: pointer to additional request parameters, or NULL
|
||||||
|
* ret: pointer to additional results, or NULL
|
||||||
|
*
|
||||||
|
* Returns pointer to a filled in RPC AUTH structure or NULL.
|
||||||
|
* Caller must free returned structure with AUTH_DESTROY.
|
||||||
|
*/
|
||||||
|
AUTH *
|
||||||
|
rpc_gss_seccreate(CLIENT *clnt, char *principal, char *mechanism,
|
||||||
|
rpc_gss_service_t service, char *qop,
|
||||||
|
rpc_gss_options_req_t *req, rpc_gss_options_ret_t *ret)
|
||||||
|
{
|
||||||
|
rpc_gss_options_ret_t options_ret;
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
struct rpc_gss_sec sec = {
|
||||||
|
.req_flags = GSS_C_MUTUAL_FLAG,
|
||||||
|
.cred = GSS_C_NO_CREDENTIAL,
|
||||||
|
};
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
AUTH *auth, *save_auth;
|
||||||
|
gss_buffer_desc sname;
|
||||||
|
|
||||||
|
if (clnt == NULL || principal == NULL)
|
||||||
|
return _rpc_gss_seccreate_error(EINVAL);
|
||||||
|
|
||||||
|
if (rpc_gss_mech_to_oid(mechanism, &sec.mech) == FALSE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sec.qop = GSS_C_QOP_DEFAULT;
|
||||||
|
if (qop != NULL) {
|
||||||
|
u_int qop_num;
|
||||||
|
if (rpc_gss_qop_to_num(qop, mechanism, &qop_num) == FALSE)
|
||||||
|
return NULL;
|
||||||
|
sec.qop = qop_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (service) {
|
||||||
|
case rpcsec_gss_svc_none:
|
||||||
|
sec.svc = RPCSEC_GSS_SVC_NONE;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_integrity:
|
||||||
|
sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_privacy:
|
||||||
|
sec.svc = RPCSEC_GSS_SVC_PRIVACY;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_default:
|
||||||
|
sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return _rpc_gss_seccreate_error(ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == NULL)
|
||||||
|
ret = &options_ret;
|
||||||
|
memset(ret, 0, sizeof(*ret));
|
||||||
|
|
||||||
|
auth = calloc(1, sizeof(*auth));
|
||||||
|
gd = calloc(1, sizeof(*gd));
|
||||||
|
if (auth == NULL || gd == NULL) {
|
||||||
|
free(gd);
|
||||||
|
free(auth);
|
||||||
|
return _rpc_gss_seccreate_error(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
sname.value = principal;
|
||||||
|
sname.length = strlen(principal);
|
||||||
|
maj_stat = gss_import_name(&min_stat, &sname,
|
||||||
|
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
|
||||||
|
&gd->name);
|
||||||
|
if (maj_stat != GSS_S_COMPLETE) {
|
||||||
|
ret->major_status = maj_stat;
|
||||||
|
ret->minor_status = min_stat;
|
||||||
|
free(gd);
|
||||||
|
free(auth);
|
||||||
|
return _rpc_gss_seccreate_error(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->clnt = clnt;
|
||||||
|
gd->ctx = GSS_C_NO_CONTEXT;
|
||||||
|
gd->sec = sec;
|
||||||
|
|
||||||
|
if (req) {
|
||||||
|
sec.req_flags = req->req_flags;
|
||||||
|
gd->time_req = req->time_req;
|
||||||
|
sec.cred = req->my_cred;
|
||||||
|
gd->icb = req->input_channel_bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->gc.gc_v = RPCSEC_GSS_VERSION;
|
||||||
|
gd->gc.gc_proc = RPCSEC_GSS_INIT;
|
||||||
|
gd->gc.gc_svc = sec.svc;
|
||||||
|
|
||||||
|
auth->ah_ops = &authgss_ops;
|
||||||
|
auth->ah_private = (caddr_t)gd;
|
||||||
|
|
||||||
|
save_auth = clnt->cl_auth;
|
||||||
|
clnt->cl_auth = auth;
|
||||||
|
|
||||||
|
if (_rpc_gss_refresh(auth, ret) == FALSE) {
|
||||||
|
auth = NULL;
|
||||||
|
} else {
|
||||||
|
rpc_gss_clear_error();
|
||||||
|
authgss_auth_get(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
clnt->cl_auth = save_auth;
|
||||||
|
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External API: Modify an AUTH's service and QOP settings
|
||||||
|
*
|
||||||
|
* auth: a valid RPC AUTH structure
|
||||||
|
* service: GSS security value to use
|
||||||
|
* qop: NUL-terminated C string containing QOP name
|
||||||
|
*
|
||||||
|
* Returns TRUE if successful, otherwise FALSE is returned.
|
||||||
|
*/
|
||||||
|
bool_t
|
||||||
|
rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service, char *qop)
|
||||||
|
{
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
char *mechanism;
|
||||||
|
u_int qop_num;
|
||||||
|
|
||||||
|
if (auth == NULL) {
|
||||||
|
rpc_gss_set_error(EINVAL);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
if (gd == NULL) {
|
||||||
|
rpc_gss_set_error(EINVAL);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rpc_gss_oid_to_mech(gd->sec.mech, &mechanism) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
qop_num = GSS_C_QOP_DEFAULT;
|
||||||
|
if (qop != NULL) {
|
||||||
|
if (rpc_gss_qop_to_num(qop, mechanism, &qop_num) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (service) {
|
||||||
|
case rpcsec_gss_svc_none:
|
||||||
|
gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_NONE;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_integrity:
|
||||||
|
gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_privacy:
|
||||||
|
gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_PRIVACY;
|
||||||
|
break;
|
||||||
|
case rpcsec_gss_svc_default:
|
||||||
|
gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rpc_gss_set_error(ENOENT);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd->sec.qop = (gss_qop_t)qop_num;
|
||||||
|
rpc_gss_clear_error();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External API: Return maximum data size for a security mechanism and transport
|
||||||
|
*
|
||||||
|
* auth: a valid RPC AUTH structure
|
||||||
|
* maxlen: transport's maximum data size, in bytes
|
||||||
|
*
|
||||||
|
* Returns maximum data size given transformations done by current
|
||||||
|
* security setting of "auth", in bytes, or zero if that value
|
||||||
|
* cannot be determined.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rpc_gss_max_data_length(AUTH *auth, int maxlen)
|
||||||
|
{
|
||||||
|
OM_uint32 max_input_size, maj_stat, min_stat;
|
||||||
|
struct rpc_gss_data *gd;
|
||||||
|
int conf_req_flag;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (auth == NULL) {
|
||||||
|
rpc_gss_set_error(EINVAL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd = AUTH_PRIVATE(auth);
|
||||||
|
if (gd == NULL) {
|
||||||
|
rpc_gss_set_error(EINVAL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gd->sec.svc) {
|
||||||
|
case RPCSEC_GSS_SVC_NONE:
|
||||||
|
rpc_gss_clear_error();
|
||||||
|
return maxlen;
|
||||||
|
case RPCSEC_GSS_SVC_INTEGRITY:
|
||||||
|
conf_req_flag = 0;
|
||||||
|
break;
|
||||||
|
case RPCSEC_GSS_SVC_PRIVACY:
|
||||||
|
conf_req_flag = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rpc_gss_set_error(ENOENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
maj_stat = gss_wrap_size_limit(&min_stat, gd->ctx, conf_req_flag,
|
||||||
|
gd->sec.qop, maxlen, &max_input_size);
|
||||||
|
if (maj_stat == GSS_S_COMPLETE)
|
||||||
|
if ((int)max_input_size > 0)
|
||||||
|
result = (int)max_input_size;
|
||||||
|
rpc_gss_clear_error();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
182
libtirpc-1.3.1/src/auth_none.c
Normal file
182
libtirpc-1.3.1/src/auth_none.c
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
__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.
|
||||||
|
*/
|
||||||
|
#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 *);
|
||||||
|
static void authnone_verf (AUTH *);
|
||||||
|
static bool_t authnone_validate (AUTH *, struct opaque_auth *);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
struct authnone_private *ap;
|
||||||
|
bool_t rv = FALSE;
|
||||||
|
extern mutex_t authnone_lock;
|
||||||
|
|
||||||
|
assert(xdrs != NULL);
|
||||||
|
|
||||||
|
mutex_lock(&authnone_lock);
|
||||||
|
ap = authnone_private;
|
||||||
|
if (ap) {
|
||||||
|
rv = (*xdrs->x_ops->x_putbytes)(xdrs, ap->marshalled_client,
|
||||||
|
ap->mcnt);
|
||||||
|
}
|
||||||
|
mutex_unlock(&authnone_lock);
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static bool_t
|
||||||
|
authnone_refresh(AUTH *client, void *dummy)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
authnone_destroy(AUTH *client)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authnone_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere)
|
||||||
|
{
|
||||||
|
return ((*xfunc)(xdrs, xwhere));
|
||||||
|
}
|
||||||
|
|
||||||
|
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_wrap;
|
||||||
|
}
|
||||||
|
mutex_unlock(&ops_lock);
|
||||||
|
return (&ops);
|
||||||
|
}
|
||||||
495
libtirpc-1.3.1/src/auth_time.c
Normal file
495
libtirpc-1.3.1/src/auth_time.c
Normal file
@ -0,0 +1,495 @@
|
|||||||
|
/*
|
||||||
|
* auth_time.c
|
||||||
|
*
|
||||||
|
* This module contains the private function __rpc_get_time_offset()
|
||||||
|
* which will return the difference in seconds between the local system's
|
||||||
|
* notion of time and a remote server's notion of time. This must be
|
||||||
|
* possible without calling any functions that may invoke the name
|
||||||
|
* service. (netdir_getbyxxx, getXbyY, etc). The function is used in the
|
||||||
|
* synchronize call of the authdes code to synchronize clocks between
|
||||||
|
* NIS+ clients and their servers.
|
||||||
|
*
|
||||||
|
* Note to minimize the amount of duplicate code, portions of the
|
||||||
|
* synchronize() function were folded into this code, and the synchronize
|
||||||
|
* call becomes simply a wrapper around this function. Further, if this
|
||||||
|
* function is called with a timehost it *DOES* recurse to the name
|
||||||
|
* server so don't use it in that mode if you are doing name service code.
|
||||||
|
*
|
||||||
|
* Copyright (c) 1992 Sun Microsystems Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Side effects :
|
||||||
|
* When called a client handle to a RPCBIND process is created
|
||||||
|
* and destroyed. Two strings "netid" and "uaddr" are malloc'd
|
||||||
|
* and returned. The SIGALRM processing is modified only if
|
||||||
|
* needed to deal with TCP connections.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/rpc_com.h>
|
||||||
|
#include <rpc/rpcb_prot.h>
|
||||||
|
//#include <clnt_soc.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#include "nis.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TESTING
|
||||||
|
#define msg(x) printf("ERROR: %s\n", x)
|
||||||
|
/* #define msg(x) syslog(LOG_ERR, "%s", x) */
|
||||||
|
#else
|
||||||
|
#define msg(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int saw_alarm = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
alarm_hndler(s)
|
||||||
|
int s;
|
||||||
|
{
|
||||||
|
saw_alarm = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The internet time server defines the epoch to be Jan 1, 1900
|
||||||
|
* whereas UNIX defines it to be Jan 1, 1970. To adjust the result
|
||||||
|
* from internet time-service time, into UNIX time we subtract the
|
||||||
|
* following offset :
|
||||||
|
*/
|
||||||
|
#define NYEARS (1970 - 1900)
|
||||||
|
#define TOFFSET ((u_long)60*60*24*(365*NYEARS + (NYEARS/4)))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stolen from rpc.nisd:
|
||||||
|
* Turn a 'universal address' into a struct sockaddr_in.
|
||||||
|
* Bletch.
|
||||||
|
*/
|
||||||
|
static int uaddr_to_sockaddr(uaddr, sin)
|
||||||
|
#ifdef foo
|
||||||
|
endpoint *endpt;
|
||||||
|
#endif
|
||||||
|
char *uaddr;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
{
|
||||||
|
unsigned char p_bytes[2];
|
||||||
|
int i;
|
||||||
|
unsigned long a[6];
|
||||||
|
|
||||||
|
i = sscanf(uaddr, "%lu.%lu.%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2],
|
||||||
|
&a[3], &a[4], &a[5]);
|
||||||
|
|
||||||
|
if (i < 6)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
sin->sin_addr.s_addr |= (a[i] & 0x000000FF) << (8 * i);
|
||||||
|
|
||||||
|
p_bytes[0] = (unsigned char)a[4] & 0x000000FF;
|
||||||
|
p_bytes[1] = (unsigned char)a[5] & 0x000000FF;
|
||||||
|
|
||||||
|
sin->sin_family = AF_INET; /* always */
|
||||||
|
memcpy((char *)&sin->sin_port, (char *)&p_bytes, 2);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free_eps()
|
||||||
|
*
|
||||||
|
* Free the strings that were strduped into the eps structure.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_eps(eps, num)
|
||||||
|
endpoint eps[];
|
||||||
|
int num;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
free(eps[i].uaddr);
|
||||||
|
free(eps[i].proto);
|
||||||
|
free(eps[i].family);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_server()
|
||||||
|
*
|
||||||
|
* This function constructs a nis_server structure description for the
|
||||||
|
* indicated hostname.
|
||||||
|
*
|
||||||
|
* NOTE: There is a chance we may end up recursing here due to the
|
||||||
|
* fact that gethostbyname() could do an NIS search. Ideally, the
|
||||||
|
* NIS+ server will call __rpc_get_time_offset() with the nis_server
|
||||||
|
* structure already populated.
|
||||||
|
*/
|
||||||
|
static nis_server *
|
||||||
|
get_server(sin, host, srv, eps, maxep)
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
char *host; /* name of the time host */
|
||||||
|
nis_server *srv; /* nis_server struct to use. */
|
||||||
|
endpoint eps[]; /* array of endpoints */
|
||||||
|
int maxep; /* max array size */
|
||||||
|
{
|
||||||
|
char hname[256];
|
||||||
|
int num_ep = 0, i;
|
||||||
|
struct hostent *he;
|
||||||
|
struct hostent dummy;
|
||||||
|
char *ptr[2];
|
||||||
|
|
||||||
|
if (host == NULL && sin == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (sin == NULL) {
|
||||||
|
he = gethostbyname(host);
|
||||||
|
if (he == NULL)
|
||||||
|
return(NULL);
|
||||||
|
} else {
|
||||||
|
he = &dummy;
|
||||||
|
ptr[0] = (char *)&sin->sin_addr.s_addr;
|
||||||
|
ptr[1] = NULL;
|
||||||
|
dummy.h_addr_list = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is lame. We go around once for TCP, then again
|
||||||
|
* for UDP.
|
||||||
|
*/
|
||||||
|
for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
|
||||||
|
i++, num_ep++) {
|
||||||
|
struct in_addr *a;
|
||||||
|
|
||||||
|
a = (struct in_addr *)he->h_addr_list[i];
|
||||||
|
snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
|
||||||
|
eps[num_ep].uaddr = strdup(hname);
|
||||||
|
eps[num_ep].family = strdup("inet");
|
||||||
|
eps[num_ep].proto = strdup("tcp");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; (he->h_addr_list[i] != NULL) && (num_ep < maxep);
|
||||||
|
i++, num_ep++) {
|
||||||
|
struct in_addr *a;
|
||||||
|
|
||||||
|
a = (struct in_addr *)he->h_addr_list[i];
|
||||||
|
snprintf(hname, sizeof(hname), "%s.0.111", inet_ntoa(*a));
|
||||||
|
eps[num_ep].uaddr = strdup(hname);
|
||||||
|
eps[num_ep].family = strdup("inet");
|
||||||
|
eps[num_ep].proto = strdup("udp");
|
||||||
|
}
|
||||||
|
|
||||||
|
srv->name = (nis_name) host;
|
||||||
|
srv->ep.ep_len = num_ep;
|
||||||
|
srv->ep.ep_val = eps;
|
||||||
|
srv->key_type = NIS_PK_NONE;
|
||||||
|
srv->pkey.n_bytes = NULL;
|
||||||
|
srv->pkey.n_len = 0;
|
||||||
|
return (srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __rpc_get_time_offset()
|
||||||
|
*
|
||||||
|
* This function uses a nis_server structure to contact the a remote
|
||||||
|
* machine (as named in that structure) and returns the offset in time
|
||||||
|
* between that machine and this one. This offset is returned in seconds
|
||||||
|
* and may be positive or negative.
|
||||||
|
*
|
||||||
|
* The first time through, a lot of fiddling is done with the netconfig
|
||||||
|
* stuff to find a suitable transport. The function is very aggressive
|
||||||
|
* about choosing UDP or at worst TCP if it can. This is because
|
||||||
|
* those transports support both the RCPBIND call and the internet
|
||||||
|
* time service.
|
||||||
|
*
|
||||||
|
* Once through, *uaddr is set to the universal address of
|
||||||
|
* the machine and *netid is set to the local netid for the transport
|
||||||
|
* that uaddr goes with. On the second call, the netconfig stuff
|
||||||
|
* is skipped and the uaddr/netid pair are used to fetch the netconfig
|
||||||
|
* structure and to then contact the machine for the time.
|
||||||
|
*
|
||||||
|
* td = "server" - "client"
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__rpc_get_time_offset(td, srv, thost, uaddr, netid)
|
||||||
|
struct timeval *td; /* Time difference */
|
||||||
|
nis_server *srv; /* NIS Server description */
|
||||||
|
char *thost; /* if no server, this is the timehost */
|
||||||
|
char **uaddr; /* known universal address */
|
||||||
|
struct sockaddr_in *netid; /* known network identifier */
|
||||||
|
{
|
||||||
|
CLIENT *clnt; /* Client handle */
|
||||||
|
endpoint *ep, /* useful endpoints */
|
||||||
|
*useep = NULL; /* endpoint of xp */
|
||||||
|
char *useua = NULL; /* uaddr of selected xp */
|
||||||
|
int epl, i; /* counters */
|
||||||
|
enum clnt_stat status; /* result of clnt_call */
|
||||||
|
u_long thetime, delta;
|
||||||
|
int needfree = 0;
|
||||||
|
struct timeval tv;
|
||||||
|
int time_valid;
|
||||||
|
int udp_ep = -1, tcp_ep = -1;
|
||||||
|
int a1, a2, a3, a4;
|
||||||
|
char ut[64], ipuaddr[64];
|
||||||
|
endpoint teps[32];
|
||||||
|
nis_server tsrv;
|
||||||
|
void (*oldsig)() = NULL; /* old alarm handler */
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int s = RPC_ANYSOCK;
|
||||||
|
socklen_t len;
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
td->tv_sec = 0;
|
||||||
|
td->tv_usec = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First check to see if we need to find and address for this
|
||||||
|
* server.
|
||||||
|
*/
|
||||||
|
if (*uaddr == NULL) {
|
||||||
|
if ((srv != NULL) && (thost != NULL)) {
|
||||||
|
msg("both timehost and srv pointer used!");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (! srv) {
|
||||||
|
srv = get_server(netid, thost, &tsrv, teps, 32);
|
||||||
|
if (srv == NULL) {
|
||||||
|
msg("unable to contruct server data.");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
needfree = 1; /* need to free data in endpoints */
|
||||||
|
}
|
||||||
|
|
||||||
|
ep = srv->ep.ep_val;
|
||||||
|
epl = srv->ep.ep_len;
|
||||||
|
|
||||||
|
/* Identify the TCP and UDP endpoints */
|
||||||
|
for (i = 0;
|
||||||
|
(i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
|
||||||
|
if (strcasecmp(ep[i].proto, "udp") == 0)
|
||||||
|
udp_ep = i;
|
||||||
|
if (strcasecmp(ep[i].proto, "tcp") == 0)
|
||||||
|
tcp_ep = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check to see if it is UDP or TCP */
|
||||||
|
if (tcp_ep > -1) {
|
||||||
|
useep = &ep[tcp_ep];
|
||||||
|
useua = ep[tcp_ep].uaddr;
|
||||||
|
type = SOCK_STREAM;
|
||||||
|
} else if (udp_ep > -1) {
|
||||||
|
useep = &ep[udp_ep];
|
||||||
|
useua = ep[udp_ep].uaddr;
|
||||||
|
type = SOCK_DGRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useep == NULL) {
|
||||||
|
msg("no acceptable transport endpoints.");
|
||||||
|
if (needfree)
|
||||||
|
free_eps(teps, tsrv.ep.ep_len);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a sockaddr from the uaddr.
|
||||||
|
*/
|
||||||
|
if (*uaddr != NULL)
|
||||||
|
useua = *uaddr;
|
||||||
|
|
||||||
|
/* Fixup test for NIS+ */
|
||||||
|
sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
|
||||||
|
sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
|
||||||
|
useua = &ipuaddr[0];
|
||||||
|
|
||||||
|
memset(&sin, 0, sizeof(sin));
|
||||||
|
if (uaddr_to_sockaddr(useua, &sin)) {
|
||||||
|
msg("unable to translate uaddr to sockaddr.");
|
||||||
|
if (needfree)
|
||||||
|
free_eps(teps, tsrv.ep.ep_len);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the client handle to rpcbind. Note we always try
|
||||||
|
* version 3 since that is the earliest version that supports
|
||||||
|
* the RPCB_GETTIME call. Also it is the version that comes
|
||||||
|
* standard with SVR4. Since most everyone supports TCP/IP
|
||||||
|
* we could consider trying the rtime call first.
|
||||||
|
*/
|
||||||
|
clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
|
||||||
|
if (clnt == NULL) {
|
||||||
|
msg("unable to create client handle to rpcbind.");
|
||||||
|
if (needfree)
|
||||||
|
free_eps(teps, tsrv.ep.ep_len);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tv.tv_sec = 5;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
time_valid = 0;
|
||||||
|
status = clnt_call(clnt, RPCBPROC_GETTIME, (xdrproc_t)xdr_void, NULL,
|
||||||
|
(xdrproc_t)xdr_u_long, &thetime, tv);
|
||||||
|
/*
|
||||||
|
* The only error we check for is anything but success. In
|
||||||
|
* fact we could have seen PROGMISMATCH if talking to a 4.1
|
||||||
|
* machine (pmap v2) or TIMEDOUT if the net was busy.
|
||||||
|
*/
|
||||||
|
if (status == RPC_SUCCESS)
|
||||||
|
time_valid = 1;
|
||||||
|
else {
|
||||||
|
int save;
|
||||||
|
|
||||||
|
/* Blow away possible stale CLNT handle. */
|
||||||
|
if (clnt != NULL) {
|
||||||
|
clnt_destroy(clnt);
|
||||||
|
clnt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert PMAP address into timeservice address
|
||||||
|
* We take advantage of the fact that we "know" what
|
||||||
|
* the universal address looks like for inet transports.
|
||||||
|
*
|
||||||
|
* We also know that the internet timeservice is always
|
||||||
|
* listening on port 37.
|
||||||
|
*/
|
||||||
|
sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
|
||||||
|
sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);
|
||||||
|
|
||||||
|
if (uaddr_to_sockaddr(ut, &sin)) {
|
||||||
|
msg("cannot convert timeservice uaddr to sockaddr.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = socket(AF_INET, type, 0);
|
||||||
|
if (s == -1) {
|
||||||
|
msg("unable to open fd to network.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now depending on whether or not we're talking to
|
||||||
|
* UDP we set a timeout or not.
|
||||||
|
*/
|
||||||
|
if (type == SOCK_DGRAM) {
|
||||||
|
struct timeval timeout = { 20, 0 };
|
||||||
|
struct sockaddr_in from;
|
||||||
|
fd_set readfds;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (sendto(s, &thetime, sizeof(thetime), 0,
|
||||||
|
(struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
||||||
|
msg("udp : sendto failed.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(s, &readfds);
|
||||||
|
res = select(_rpc_dtablesize(), &readfds,
|
||||||
|
(fd_set *)NULL, (fd_set *)NULL, &timeout);
|
||||||
|
} while (res < 0 && errno == EINTR);
|
||||||
|
if (res <= 0)
|
||||||
|
goto error;
|
||||||
|
len = sizeof(from);
|
||||||
|
res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
|
||||||
|
(struct sockaddr *)&from, &len);
|
||||||
|
if (res == -1) {
|
||||||
|
msg("recvfrom failed on udp transport.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
time_valid = 1;
|
||||||
|
} else {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
|
||||||
|
saw_alarm = 0; /* global tracking the alarm */
|
||||||
|
alarm(20); /* only wait 20 seconds */
|
||||||
|
res = connect(s, (struct sockaddr *)&sin, sizeof(sin));
|
||||||
|
if (res == -1) {
|
||||||
|
msg("failed to connect to tcp endpoint.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (saw_alarm) {
|
||||||
|
msg("alarm caught it, must be unreachable.");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
res = read(s, (char *)&thetime, sizeof(thetime));
|
||||||
|
if (res != sizeof(thetime)) {
|
||||||
|
if (saw_alarm)
|
||||||
|
msg("timed out TCP call.");
|
||||||
|
else
|
||||||
|
msg("wrong size of results returned");
|
||||||
|
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
time_valid = 1;
|
||||||
|
}
|
||||||
|
save = errno;
|
||||||
|
(void)close(s);
|
||||||
|
errno = save;
|
||||||
|
s = RPC_ANYSOCK;
|
||||||
|
|
||||||
|
if (time_valid) {
|
||||||
|
thetime = ntohl(thetime);
|
||||||
|
thetime = thetime - TOFFSET; /* adjust to UNIX time */
|
||||||
|
} else
|
||||||
|
thetime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(&tv, 0);
|
||||||
|
|
||||||
|
error:
|
||||||
|
/*
|
||||||
|
* clean up our allocated data structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (s != RPC_ANYSOCK)
|
||||||
|
(void)close(s);
|
||||||
|
|
||||||
|
if (clnt != NULL)
|
||||||
|
clnt_destroy(clnt);
|
||||||
|
|
||||||
|
alarm(0); /* reset that alarm if its outstanding */
|
||||||
|
if (oldsig) {
|
||||||
|
signal(SIGALRM, oldsig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* note, don't free uaddr strings until after we've made a
|
||||||
|
* copy of them.
|
||||||
|
*/
|
||||||
|
if (time_valid) {
|
||||||
|
if (*uaddr == NULL)
|
||||||
|
*uaddr = strdup(useua);
|
||||||
|
|
||||||
|
/* Round to the nearest second */
|
||||||
|
tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
|
||||||
|
delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
|
||||||
|
tv.tv_sec - thetime;
|
||||||
|
td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
|
||||||
|
td->tv_usec = 0;
|
||||||
|
} else {
|
||||||
|
msg("unable to get the server's time.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needfree)
|
||||||
|
free_eps(teps, tsrv.ep.ep_len);
|
||||||
|
|
||||||
|
return (time_valid);
|
||||||
|
}
|
||||||
424
libtirpc-1.3.1/src/auth_unix.c
Normal file
424
libtirpc-1.3.1/src/auth_unix.c
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#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 <errno.h>
|
||||||
|
|
||||||
|
#include <rpc/clnt.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 *);
|
||||||
|
static bool_t authunix_validate (AUTH *, struct opaque_auth *);
|
||||||
|
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;
|
||||||
|
|
||||||
|
memset(&rpc_createerr, 0, sizeof(rpc_createerr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and set up auth handle
|
||||||
|
*/
|
||||||
|
au = NULL;
|
||||||
|
auth = mem_alloc(sizeof(*auth));
|
||||||
|
#ifndef _KERNEL
|
||||||
|
if (auth == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
goto cleanup_authunix_create;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
au = mem_alloc(sizeof(*au));
|
||||||
|
#ifndef _KERNEL
|
||||||
|
if (au == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
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)) {
|
||||||
|
rpc_createerr.cf_stat = RPC_CANTENCODEARGS;
|
||||||
|
goto cleanup_authunix_create;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
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, *gids;
|
||||||
|
AUTH *result;
|
||||||
|
|
||||||
|
memset(&rpc_createerr, 0, sizeof(rpc_createerr));
|
||||||
|
|
||||||
|
if (gethostname(machname, sizeof machname) == -1) {
|
||||||
|
rpc_createerr.cf_error.re_errno = errno;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
machname[sizeof(machname) - 1] = 0;
|
||||||
|
uid = geteuid();
|
||||||
|
gid = getegid();
|
||||||
|
|
||||||
|
/* According to glibc comments, an intervening setgroups(2)
|
||||||
|
* call can increase the number of supplemental groups between
|
||||||
|
* these two getgroups(2) calls. */
|
||||||
|
retry:
|
||||||
|
len = getgroups(0, NULL);
|
||||||
|
if (len == -1) {
|
||||||
|
rpc_createerr.cf_error.re_errno = errno;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bump allocation size. A zero allocation size may result in a
|
||||||
|
* NULL calloc(3) result, which is not reliably distinguishable
|
||||||
|
* from a memory allocation error. */
|
||||||
|
gids = calloc(len + 1, sizeof(gid_t));
|
||||||
|
if (gids == NULL) {
|
||||||
|
rpc_createerr.cf_error.re_errno = ENOMEM;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = getgroups(len, gids);
|
||||||
|
if (len == -1) {
|
||||||
|
rpc_createerr.cf_error.re_errno = errno;
|
||||||
|
free(gids);
|
||||||
|
if (rpc_createerr.cf_error.re_errno == EINVAL) {
|
||||||
|
rpc_createerr.cf_error.re_errno = 0;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AUTH_UNIX sends on the wire only the first NGRPS groups in the
|
||||||
|
* supplemental groups list.
|
||||||
|
*/
|
||||||
|
if (len > NGRPS)
|
||||||
|
len = NGRPS;
|
||||||
|
|
||||||
|
/* XXX: interface problem; those should all have been unsigned */
|
||||||
|
result = authunix_create(machname, uid, gid, len, gids);
|
||||||
|
free(gids);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* authunix operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static void
|
||||||
|
authunix_nextverf(auth)
|
||||||
|
AUTH *auth;
|
||||||
|
{
|
||||||
|
/* no action necessary */
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
authunix_marshal(auth, xdrs)
|
||||||
|
AUTH *auth;
|
||||||
|
XDR *xdrs;
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
AUTH *auth;
|
||||||
|
struct opaque_auth *verf;
|
||||||
|
{
|
||||||
|
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))))
|
||||||
|
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 xfunc, caddr_t xwhere)
|
||||||
|
{
|
||||||
|
return ((*xfunc)(xdrs, xwhere));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
85
libtirpc-1.3.1/src/authdes_prot.c
Normal file
85
libtirpc-1.3.1/src/authdes_prot.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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-1991 by Sun Microsystems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* authdes_prot.c, XDR routines for DES authentication
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_des.h>
|
||||||
|
|
||||||
|
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_authdes_cred(xdrs, cred)
|
||||||
|
XDR *xdrs;
|
||||||
|
struct authdes_cred *cred;
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Unrolled xdr
|
||||||
|
*/
|
||||||
|
ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind));
|
||||||
|
switch (cred->adc_namekind) {
|
||||||
|
case ADN_FULLNAME:
|
||||||
|
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name,
|
||||||
|
MAXNETNAMELEN));
|
||||||
|
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key,
|
||||||
|
sizeof(des_block)));
|
||||||
|
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window,
|
||||||
|
sizeof(cred->adc_fullname.window)));
|
||||||
|
return (TRUE);
|
||||||
|
case ADN_NICKNAME:
|
||||||
|
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname,
|
||||||
|
sizeof(cred->adc_nickname)));
|
||||||
|
return (TRUE);
|
||||||
|
default:
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_authdes_verf(xdrs, verf)
|
||||||
|
XDR *xdrs;
|
||||||
|
struct authdes_verf *verf;
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Unrolled xdr
|
||||||
|
*/
|
||||||
|
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp,
|
||||||
|
sizeof(des_block)));
|
||||||
|
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u,
|
||||||
|
sizeof(verf->adv_int_u)));
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
371
libtirpc-1.3.1/src/authgss_prot.c
Normal file
371
libtirpc-1.3.1/src/authgss_prot.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
/*
|
||||||
|
authgss_prot.c
|
||||||
|
|
||||||
|
Copyright (c) 2000 The Regents of the University of Michigan.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
|
||||||
|
All rights reserved, all wrongs reversed.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. 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.
|
||||||
|
3. Neither the name of the University 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 ``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 REGENTS 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_gss.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <gssapi/gssapi.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
/* additional space needed for encoding */
|
||||||
|
#define RPC_SLACK_SPACE 1024
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
|
||||||
|
{
|
||||||
|
bool_t xdr_stat;
|
||||||
|
u_int tmplen;
|
||||||
|
|
||||||
|
if (xdrs->x_op != XDR_DECODE) {
|
||||||
|
if (buf->length > UINT_MAX)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
tmplen = buf->length;
|
||||||
|
}
|
||||||
|
xdr_stat = xdr_bytes(xdrs, (char **)&buf->value, &tmplen, maxsize);
|
||||||
|
|
||||||
|
if (xdr_stat && xdrs->x_op == XDR_DECODE)
|
||||||
|
buf->length = tmplen;
|
||||||
|
|
||||||
|
gss_log_debug("xdr_rpc_gss_buf: %s %s (%p:%lu)",
|
||||||
|
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
|
||||||
|
(xdr_stat == TRUE) ? "success" : "failure",
|
||||||
|
buf->value, buf->length);
|
||||||
|
|
||||||
|
return xdr_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
|
||||||
|
{
|
||||||
|
bool_t xdr_stat;
|
||||||
|
|
||||||
|
xdr_stat = (xdr_u_int(xdrs, &p->gc_v) &&
|
||||||
|
xdr_enum(xdrs, (enum_t *)&p->gc_proc) &&
|
||||||
|
xdr_u_int(xdrs, &p->gc_seq) &&
|
||||||
|
xdr_enum(xdrs, (enum_t *)&p->gc_svc) &&
|
||||||
|
xdr_rpc_gss_buf(xdrs, &p->gc_ctx, MAX_AUTH_BYTES));
|
||||||
|
|
||||||
|
gss_log_debug("xdr_rpc_gss_cred: %s %s "
|
||||||
|
"(v %d, proc %d, seq %d, svc %d, ctx %p:%lu)",
|
||||||
|
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
|
||||||
|
(xdr_stat == TRUE) ? "success" : "failure",
|
||||||
|
p->gc_v, p->gc_proc, p->gc_seq, p->gc_svc,
|
||||||
|
p->gc_ctx.value, p->gc_ctx.length);
|
||||||
|
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p)
|
||||||
|
{
|
||||||
|
bool_t xdr_stat;
|
||||||
|
u_int maxlen = (u_int)(p->length + RPC_SLACK_SPACE);
|
||||||
|
|
||||||
|
xdr_stat = xdr_rpc_gss_buf(xdrs, p, maxlen);
|
||||||
|
|
||||||
|
gss_log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%lu)",
|
||||||
|
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
|
||||||
|
(xdr_stat == TRUE) ? "success" : "failure",
|
||||||
|
p->value, p->length);
|
||||||
|
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p)
|
||||||
|
{
|
||||||
|
bool_t xdr_stat;
|
||||||
|
|
||||||
|
u_int ctx_maxlen = (u_int)(p->gr_ctx.length + RPC_SLACK_SPACE);
|
||||||
|
u_int tok_maxlen = (u_int)(p->gr_token.length + RPC_SLACK_SPACE);
|
||||||
|
|
||||||
|
xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, ctx_maxlen) &&
|
||||||
|
xdr_u_int(xdrs, &p->gr_major) &&
|
||||||
|
xdr_u_int(xdrs, &p->gr_minor) &&
|
||||||
|
xdr_u_int(xdrs, &p->gr_win) &&
|
||||||
|
xdr_rpc_gss_buf(xdrs, &p->gr_token, tok_maxlen));
|
||||||
|
|
||||||
|
gss_log_debug("xdr_rpc_gss_init_res %s %s "
|
||||||
|
"(ctx %p:%lu, maj %d, min %d, win %d, token %p:%lu)",
|
||||||
|
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
|
||||||
|
(xdr_stat == TRUE) ? "success" : "failure",
|
||||||
|
p->gr_ctx.value, p->gr_ctx.length,
|
||||||
|
p->gr_major, p->gr_minor, p->gr_win,
|
||||||
|
p->gr_token.value, p->gr_token.length);
|
||||||
|
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
|
||||||
|
gss_ctx_id_t ctx, gss_qop_t qop,
|
||||||
|
rpc_gss_svc_t svc, u_int seq)
|
||||||
|
{
|
||||||
|
gss_buffer_desc databuf, wrapbuf;
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
int start, end, conf_state;
|
||||||
|
bool_t xdr_stat;
|
||||||
|
u_int databuflen, maxwrapsz;
|
||||||
|
|
||||||
|
/* Skip databody length. */
|
||||||
|
start = XDR_GETPOS(xdrs);
|
||||||
|
XDR_SETPOS(xdrs, start + 4);
|
||||||
|
|
||||||
|
memset(&databuf, 0, sizeof(databuf));
|
||||||
|
memset(&wrapbuf, 0, sizeof(wrapbuf));
|
||||||
|
|
||||||
|
/* Marshal rpc_gss_data_t (sequence number + arguments). */
|
||||||
|
if (!xdr_u_int(xdrs, &seq) || !(*xdr_func)(xdrs, xdr_ptr))
|
||||||
|
return (FALSE);
|
||||||
|
end = XDR_GETPOS(xdrs);
|
||||||
|
|
||||||
|
/* Set databuf to marshalled rpc_gss_data_t. */
|
||||||
|
databuflen = end - start - 4;
|
||||||
|
XDR_SETPOS(xdrs, start + 4);
|
||||||
|
databuf.value = XDR_INLINE(xdrs, databuflen);
|
||||||
|
databuf.length = databuflen;
|
||||||
|
|
||||||
|
xdr_stat = FALSE;
|
||||||
|
|
||||||
|
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
|
||||||
|
/* Marshal databody_integ length. */
|
||||||
|
XDR_SETPOS(xdrs, start);
|
||||||
|
if (!xdr_u_int(xdrs, (u_int *)&databuflen))
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
|
/* Checksum rpc_gss_data_t. */
|
||||||
|
maj_stat = gss_get_mic(&min_stat, ctx, qop,
|
||||||
|
&databuf, &wrapbuf);
|
||||||
|
if (maj_stat != GSS_S_COMPLETE) {
|
||||||
|
gss_log_status("xdr_rpc_gss_wrap_data: gss_get_mic",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* Marshal checksum. */
|
||||||
|
XDR_SETPOS(xdrs, end);
|
||||||
|
maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
|
||||||
|
xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
|
||||||
|
gss_release_buffer(&min_stat, &wrapbuf);
|
||||||
|
}
|
||||||
|
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
|
||||||
|
/* Encrypt rpc_gss_data_t. */
|
||||||
|
maj_stat = gss_wrap(&min_stat, ctx, TRUE, qop, &databuf,
|
||||||
|
&conf_state, &wrapbuf);
|
||||||
|
if (maj_stat != GSS_S_COMPLETE) {
|
||||||
|
gss_log_status("xdr_rpc_gss_wrap_data: gss_wrap",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* Marshal databody_priv. */
|
||||||
|
XDR_SETPOS(xdrs, start);
|
||||||
|
maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
|
||||||
|
xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
|
||||||
|
gss_release_buffer(&min_stat, &wrapbuf);
|
||||||
|
}
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
|
||||||
|
gss_ctx_id_t ctx, gss_qop_t qop,
|
||||||
|
rpc_gss_svc_t svc, u_int seq)
|
||||||
|
{
|
||||||
|
XDR tmpxdrs;
|
||||||
|
gss_buffer_desc databuf, wrapbuf;
|
||||||
|
OM_uint32 maj_stat, min_stat;
|
||||||
|
u_int seq_num, qop_state;
|
||||||
|
int conf_state;
|
||||||
|
bool_t xdr_stat;
|
||||||
|
|
||||||
|
if (xdr_func == (xdrproc_t)xdr_void || xdr_ptr == NULL)
|
||||||
|
return (TRUE);
|
||||||
|
|
||||||
|
memset(&databuf, 0, sizeof(databuf));
|
||||||
|
memset(&wrapbuf, 0, sizeof(wrapbuf));
|
||||||
|
|
||||||
|
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
|
||||||
|
/* Decode databody_integ. */
|
||||||
|
if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode databody_integ failed"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* Decode checksum. */
|
||||||
|
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
|
||||||
|
gss_release_buffer(&min_stat, &databuf);
|
||||||
|
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode checksum failed"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* Verify checksum and QOP. */
|
||||||
|
maj_stat = gss_verify_mic(&min_stat, ctx, &databuf,
|
||||||
|
&wrapbuf, &qop_state);
|
||||||
|
gss_release_buffer(&min_stat, &wrapbuf);
|
||||||
|
|
||||||
|
if (maj_stat != GSS_S_COMPLETE || qop_state != qop) {
|
||||||
|
gss_release_buffer(&min_stat, &databuf);
|
||||||
|
gss_log_status("xdr_rpc_gss_unwrap_data: gss_verify_mic",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
|
||||||
|
/* Decode databody_priv. */
|
||||||
|
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode databody_priv failed"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
/* Decrypt databody. */
|
||||||
|
maj_stat = gss_unwrap(&min_stat, ctx, &wrapbuf, &databuf,
|
||||||
|
&conf_state, &qop_state);
|
||||||
|
|
||||||
|
gss_release_buffer(&min_stat, &wrapbuf);
|
||||||
|
|
||||||
|
/* Verify encryption and QOP. */
|
||||||
|
if (maj_stat != GSS_S_COMPLETE || qop_state != qop ||
|
||||||
|
conf_state != TRUE) {
|
||||||
|
gss_release_buffer(&min_stat, &databuf);
|
||||||
|
gss_log_status("xdr_rpc_gss_unwrap_data: gss_unwrap",
|
||||||
|
maj_stat, min_stat);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Decode rpc_gss_data_t (sequence number + arguments). */
|
||||||
|
xdrmem_create(&tmpxdrs, databuf.value, databuf.length, XDR_DECODE);
|
||||||
|
xdr_stat = (xdr_u_int(&tmpxdrs, &seq_num) &&
|
||||||
|
(*xdr_func)(&tmpxdrs, xdr_ptr));
|
||||||
|
XDR_DESTROY(&tmpxdrs);
|
||||||
|
gss_release_buffer(&min_stat, &databuf);
|
||||||
|
|
||||||
|
/* Verify sequence number. */
|
||||||
|
if (xdr_stat == TRUE && seq_num != seq) {
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("xdr_rpc_gss_unwrap_data: wrong sequence number in databody"));
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
return (xdr_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_rpc_gss_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
|
||||||
|
gss_ctx_id_t ctx, gss_qop_t qop,
|
||||||
|
rpc_gss_svc_t svc, u_int seq)
|
||||||
|
{
|
||||||
|
switch (xdrs->x_op) {
|
||||||
|
|
||||||
|
case XDR_ENCODE:
|
||||||
|
return (xdr_rpc_gss_wrap_data(xdrs, xdr_func, xdr_ptr,
|
||||||
|
ctx, qop, svc, seq));
|
||||||
|
case XDR_DECODE:
|
||||||
|
return (xdr_rpc_gss_unwrap_data(xdrs, xdr_func, xdr_ptr,
|
||||||
|
ctx, qop,svc, seq));
|
||||||
|
case XDR_FREE:
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gss_log_debug(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vlibtirpc_log_dbg(2, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gss_log_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat)
|
||||||
|
{
|
||||||
|
OM_uint32 min, maj;
|
||||||
|
gss_buffer_desc maj_msg, min_msg;
|
||||||
|
u_int32_t msg_ctx = 0;
|
||||||
|
|
||||||
|
gss_display_status(&maj, maj_stat, GSS_C_GSS_CODE, GSS_C_NULL_OID,
|
||||||
|
&msg_ctx, &maj_msg);
|
||||||
|
gss_display_status(&min, min_stat, GSS_C_MECH_CODE, GSS_C_NULL_OID,
|
||||||
|
&msg_ctx, &min_msg);
|
||||||
|
|
||||||
|
LIBTIRPC_DEBUG(1, ("%s: %s - %s", m, (char *)maj_msg.value, (char *)min_msg.value));
|
||||||
|
|
||||||
|
gss_release_buffer(&maj, &maj_msg);
|
||||||
|
gss_release_buffer(&min, &min_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gss_log_hexdump(const u_char *buf, int len, int offset)
|
||||||
|
{
|
||||||
|
u_int i, j, jm;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (libtirpc_debug_level < 4 || log_stderr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
for (i = 0; i < len; i += 0x10) {
|
||||||
|
fprintf(stderr, " %04x: ", (u_int)(i + offset));
|
||||||
|
jm = len - i;
|
||||||
|
jm = jm > 16 ? 16 : jm;
|
||||||
|
|
||||||
|
for (j = 0; j < jm; j++) {
|
||||||
|
if ((j % 2) == 1)
|
||||||
|
fprintf(stderr, "%02x ", (u_int) buf[i+j]);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "%02x", (u_int) buf[i+j]);
|
||||||
|
}
|
||||||
|
for (; j < 16; j++) {
|
||||||
|
if ((j % 2) == 1) printf(" ");
|
||||||
|
else fprintf(stderr, " ");
|
||||||
|
}
|
||||||
|
fprintf(stderr, " ");
|
||||||
|
|
||||||
|
for (j = 0; j < jm; j++) {
|
||||||
|
c = buf[i+j];
|
||||||
|
c = isprint(c) ? c : '.';
|
||||||
|
fprintf(stderr, "%c", c);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
65
libtirpc-1.3.1/src/authunix_prot.c
Normal file
65
libtirpc-1.3.1/src/authunix_prot.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* authunix_prot.c
|
||||||
|
* XDR for UNIX style authentication parameters for RPC
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_unix.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XDR for unix authentication parameters.
|
||||||
|
*/
|
||||||
|
bool_t
|
||||||
|
xdr_authunix_parms(xdrs, p)
|
||||||
|
XDR *xdrs;
|
||||||
|
struct authunix_parms *p;
|
||||||
|
{
|
||||||
|
|
||||||
|
assert(xdrs != NULL);
|
||||||
|
assert(p != NULL);
|
||||||
|
|
||||||
|
if (xdr_u_long(xdrs, &(p->aup_time))
|
||||||
|
&& xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
|
||||||
|
&& xdr_u_int(xdrs, &(p->aup_uid))
|
||||||
|
&& xdr_u_int(xdrs, &(p->aup_gid))
|
||||||
|
&& xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
|
||||||
|
&(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
139
libtirpc-1.3.1/src/binddynport.c
Normal file
139
libtirpc-1.3.1/src/binddynport.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle America, 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 "Oracle America, 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/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
|
#include "reentrant.h"
|
||||||
|
#include "rpc_com.h"
|
||||||
|
|
||||||
|
extern pthread_mutex_t port_lock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dynamic port range as defined in RFC 6335 Section 6.
|
||||||
|
* This range avoids all IANA-assigned service port
|
||||||
|
* numbers.
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
LOWPORT = 49152,
|
||||||
|
ENDPORT = 65534,
|
||||||
|
NPORTS = ENDPORT - LOWPORT + 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a socket to a dynamically-assigned IP port.
|
||||||
|
*
|
||||||
|
* @fd is an open but unbound socket.
|
||||||
|
*
|
||||||
|
* On each call, a port number is chosen at random from
|
||||||
|
* within the dynamic/private port range, even if the
|
||||||
|
* caller has CAP_NET_ADMIN_BIND.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure. errno may be
|
||||||
|
* set to a non-determinant value.
|
||||||
|
*
|
||||||
|
* This function is re-entrant.
|
||||||
|
*/
|
||||||
|
int __binddynport(int fd)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
static unsigned int seed;
|
||||||
|
in_port_t port, *portp;
|
||||||
|
struct sockaddr *sap;
|
||||||
|
socklen_t salen;
|
||||||
|
int i, res;
|
||||||
|
|
||||||
|
if (__rpc_sockisbound(fd))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
res = -1;
|
||||||
|
sap = (struct sockaddr *)(void *)&ss;
|
||||||
|
salen = sizeof(ss);
|
||||||
|
memset(sap, 0, salen);
|
||||||
|
|
||||||
|
mutex_lock(&port_lock);
|
||||||
|
|
||||||
|
if (getsockname(fd, sap, &salen) == -1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
switch (ss.ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
sin = (struct sockaddr_in *)(void *)&ss;
|
||||||
|
portp = &sin->sin_port;
|
||||||
|
salen = sizeof(struct sockaddr_in);
|
||||||
|
break;
|
||||||
|
#ifdef INET6
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *)(void *)&ss;
|
||||||
|
portp = &sin6->sin6_port;
|
||||||
|
salen = sizeof(struct sockaddr_in6);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seed) {
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
seed = tv.tv_usec * getpid();
|
||||||
|
}
|
||||||
|
port = (rand_r(&seed) % NPORTS) + LOWPORT;
|
||||||
|
for (i = 0; i < NPORTS; ++i) {
|
||||||
|
*portp = htons(port++);
|
||||||
|
res = bind(fd, sap, salen);
|
||||||
|
if (res >= 0) {
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno != EADDRINUSE)
|
||||||
|
break;
|
||||||
|
if (port > ENDPORT)
|
||||||
|
port = LOWPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&port_lock);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
336
libtirpc-1.3.1/src/bindresvport.c
Normal file
336
libtirpc-1.3.1/src/bindresvport.c
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1987 by Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* Portions Copyright(C) 1996, Jason Downs. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
|
||||||
|
extern pthread_mutex_t port_lock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a socket to a privileged IP port
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
bindresvport(sd, sin)
|
||||||
|
int sd;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
{
|
||||||
|
return bindresvport_sa(sd, (struct sockaddr *)sin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
#define STARTPORT 600
|
||||||
|
#define LOWPORT 512
|
||||||
|
#define ENDPORT (IPPORT_RESERVED - 1)
|
||||||
|
#define NPORTS (ENDPORT - STARTPORT + 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the file /etc/bindresvport.blacklist, so that we don't bind
|
||||||
|
* to these ports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int blacklist_read;
|
||||||
|
static int *list;
|
||||||
|
static int list_size = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_blacklist (void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
int size = 0, ptr = 0;
|
||||||
|
|
||||||
|
blacklist_read = 1;
|
||||||
|
|
||||||
|
fp = fopen ("/etc/bindresvport.blacklist", "r");
|
||||||
|
if (NULL == fp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (!feof (fp))
|
||||||
|
{
|
||||||
|
unsigned long port;
|
||||||
|
char *tmp, *cp;
|
||||||
|
ssize_t n = getline (&buf, &buflen, fp);
|
||||||
|
if (n < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cp = buf;
|
||||||
|
tmp = strchr (cp, '#'); /* remove comments */
|
||||||
|
if (tmp)
|
||||||
|
*tmp = '\0';
|
||||||
|
while (isspace ((int)*cp)) /* remove spaces and tabs */
|
||||||
|
++cp;
|
||||||
|
if (*cp == '\0') /* ignore empty lines */
|
||||||
|
continue;
|
||||||
|
if (cp[strlen (cp) - 1] == '\n')
|
||||||
|
cp[strlen (cp) - 1] = '\0';
|
||||||
|
|
||||||
|
port = strtoul (cp, &tmp, 0);
|
||||||
|
while (isspace(*tmp))
|
||||||
|
++tmp;
|
||||||
|
if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Don't bother with out-of-range ports */
|
||||||
|
if (port < LOWPORT || port > ENDPORT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ptr >= size)
|
||||||
|
{
|
||||||
|
size += 10;
|
||||||
|
list = realloc (list, size * sizeof (int));
|
||||||
|
if (list == NULL)
|
||||||
|
{
|
||||||
|
free (buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list[ptr++] = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (fp);
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
free (buf);
|
||||||
|
|
||||||
|
list_size = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bindresvport_sa(sd, sa)
|
||||||
|
int sd;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
{
|
||||||
|
int res, af;
|
||||||
|
struct sockaddr_storage myaddr;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
u_int16_t *portp;
|
||||||
|
static u_int16_t port;
|
||||||
|
static short startport = STARTPORT;
|
||||||
|
socklen_t salen;
|
||||||
|
int nports;
|
||||||
|
int endport = ENDPORT;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!blacklist_read)
|
||||||
|
load_blacklist();
|
||||||
|
|
||||||
|
mutex_lock(&port_lock);
|
||||||
|
nports = ENDPORT - startport + 1;
|
||||||
|
|
||||||
|
if (sa == NULL) {
|
||||||
|
salen = sizeof(myaddr);
|
||||||
|
sa = (struct sockaddr *)&myaddr;
|
||||||
|
|
||||||
|
if (getsockname(sd, (struct sockaddr *)&myaddr, &salen) == -1) {
|
||||||
|
mutex_unlock(&port_lock);
|
||||||
|
return -1; /* errno is correctly set */
|
||||||
|
}
|
||||||
|
|
||||||
|
af = myaddr.ss_family;
|
||||||
|
} else
|
||||||
|
af = sa->sa_family;
|
||||||
|
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
sin = (struct sockaddr_in *)sa;
|
||||||
|
salen = sizeof(struct sockaddr_in);
|
||||||
|
port = ntohs(sin->sin_port);
|
||||||
|
portp = &sin->sin_port;
|
||||||
|
break;
|
||||||
|
#ifdef INET6
|
||||||
|
case AF_INET6:
|
||||||
|
sin6 = (struct sockaddr_in6 *)sa;
|
||||||
|
salen = sizeof(struct sockaddr_in6);
|
||||||
|
port = ntohs(sin6->sin6_port);
|
||||||
|
portp = &sin6->sin6_port;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EPFNOSUPPORT;
|
||||||
|
mutex_unlock(&port_lock);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
sa->sa_family = af;
|
||||||
|
|
||||||
|
if (port == 0) {
|
||||||
|
port = (getpid() % NPORTS) + STARTPORT;
|
||||||
|
}
|
||||||
|
res = -1;
|
||||||
|
errno = EADDRINUSE;
|
||||||
|
again:
|
||||||
|
for (i = 0; i < nports; ++i) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
/* Check if this port is not blacklisted. */
|
||||||
|
for (j = 0; j < list_size; j++)
|
||||||
|
if (port == list[j])
|
||||||
|
goto try_next_port;
|
||||||
|
|
||||||
|
*portp = htons(port);
|
||||||
|
res = bind(sd, sa, salen);
|
||||||
|
if (res >= 0 || errno != EADDRINUSE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
try_next_port:
|
||||||
|
if (++port > endport)
|
||||||
|
port = startport;
|
||||||
|
}
|
||||||
|
if (i == nports && startport != LOWPORT) {
|
||||||
|
startport = LOWPORT;
|
||||||
|
endport = STARTPORT - 1;
|
||||||
|
nports = STARTPORT - LOWPORT;
|
||||||
|
port = LOWPORT + port % (STARTPORT - LOWPORT);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
mutex_unlock(&port_lock);
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define IP_PORTRANGE 19
|
||||||
|
#define IP_PORTRANGE_LOW 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a socket to a privileged IP port
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
bindresvport_sa(sd, sa)
|
||||||
|
int sd;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
{
|
||||||
|
int old, error, af;
|
||||||
|
struct sockaddr_storage myaddr;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
int proto, portrange, portlow;
|
||||||
|
u_int16_t *portp;
|
||||||
|
socklen_t salen;
|
||||||
|
|
||||||
|
if (sa == NULL) {
|
||||||
|
salen = sizeof(myaddr);
|
||||||
|
sa = (struct sockaddr *)&myaddr;
|
||||||
|
|
||||||
|
if (getsockname(sd, sa, &salen) == -1)
|
||||||
|
return -1; /* errno is correctly set */
|
||||||
|
|
||||||
|
af = sa->sa_family;
|
||||||
|
memset(sa, 0, salen);
|
||||||
|
} else
|
||||||
|
af = sa->sa_family;
|
||||||
|
|
||||||
|
switch (af) {
|
||||||
|
case AF_INET:
|
||||||
|
proto = IPPROTO_IP;
|
||||||
|
portrange = IP_PORTRANGE;
|
||||||
|
portlow = IP_PORTRANGE_LOW;
|
||||||
|
sin = (struct sockaddr_in *)sa;
|
||||||
|
salen = sizeof(struct sockaddr_in);
|
||||||
|
portp = &sin->sin_port;
|
||||||
|
break;
|
||||||
|
#ifdef INET6
|
||||||
|
case AF_INET6:
|
||||||
|
proto = IPPROTO_IPV6;
|
||||||
|
portrange = IPV6_PORTRANGE;
|
||||||
|
portlow = IPV6_PORTRANGE_LOW;
|
||||||
|
sin6 = (struct sockaddr_in6 *)sa;
|
||||||
|
salen = sizeof(struct sockaddr_in6);
|
||||||
|
portp = &sin6->sin6_port;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
errno = EPFNOSUPPORT;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
sa->sa_family = af;
|
||||||
|
|
||||||
|
if (*portp == 0) {
|
||||||
|
socklen_t oldlen = sizeof(old);
|
||||||
|
|
||||||
|
error = getsockopt(sd, proto, portrange, &old, &oldlen);
|
||||||
|
if (error < 0)
|
||||||
|
return (error);
|
||||||
|
|
||||||
|
error = setsockopt(sd, proto, portrange, &portlow,
|
||||||
|
sizeof(portlow));
|
||||||
|
if (error < 0)
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = bind(sd, sa, salen);
|
||||||
|
|
||||||
|
if (*portp == 0) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
if (setsockopt(sd, proto, portrange, &old,
|
||||||
|
sizeof(old)) < 0)
|
||||||
|
errno = saved_errno;
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa != (struct sockaddr *)&myaddr) {
|
||||||
|
/* Hmm, what did the kernel assign? */
|
||||||
|
if (getsockname(sd, sa, &salen) < 0)
|
||||||
|
errno = saved_errno;
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
698
libtirpc-1.3.1/src/clnt_bcast.c
Normal file
698
libtirpc-1.3.1/src/clnt_bcast.c
Normal file
@ -0,0 +1,698 @@
|
|||||||
|
/*
|
||||||
|
* 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-1991 by Sun Microsystems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_bcast.c
|
||||||
|
* Client interface to broadcast service.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1988, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* The following is kludged-up support for simple rpc broadcasts.
|
||||||
|
* Someday a large, complicated system will replace these routines.
|
||||||
|
*/
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#ifdef PORTMAP
|
||||||
|
#include <rpc/pmap_prot.h>
|
||||||
|
#include <rpc/pmap_clnt.h>
|
||||||
|
#include <rpc/pmap_rmt.h>
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
#include <rpc/nettype.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "rpc_com.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define MAXBCAST 20 /* Max no of broadcasting transports */
|
||||||
|
#define INITTIME 4000 /* Time to wait initially */
|
||||||
|
#define WAITTIME 8000 /* Maximum time to wait */
|
||||||
|
|
||||||
|
# define POLLRDNORM 0x040 /* Normal data may be read. */
|
||||||
|
# define POLLRDBAND 0x080 /* Priority data may be read. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If nettype is NULL, it broadcasts on all the available
|
||||||
|
* datagram_n transports. May potentially lead to broadacst storms
|
||||||
|
* and hence should be used with caution, care and courage.
|
||||||
|
*
|
||||||
|
* The current parameter xdr packet size is limited by the max tsdu
|
||||||
|
* size of the transport. If the max tsdu size of any transport is
|
||||||
|
* smaller than the parameter xdr packet, then broadcast is not
|
||||||
|
* sent on that transport.
|
||||||
|
*
|
||||||
|
* Also, the packet size should be less the packet size of
|
||||||
|
* the data link layer (for ethernet it is 1400 bytes). There is
|
||||||
|
* no easy way to find out the max size of the data link layer and
|
||||||
|
* we are assuming that the args would be smaller than that.
|
||||||
|
*
|
||||||
|
* The result size has to be smaller than the transport tsdu size.
|
||||||
|
*
|
||||||
|
* If PORTMAP has been defined, we send two packets for UDP, one for
|
||||||
|
* rpcbind and one for portmap. For those machines which support
|
||||||
|
* both rpcbind and portmap, it will cause them to reply twice, and
|
||||||
|
* also here it will get two responses ... inefficient and clumsy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||||
|
|
||||||
|
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||||
|
|
||||||
|
|
||||||
|
struct broadif {
|
||||||
|
int index;
|
||||||
|
struct sockaddr_storage broadaddr;
|
||||||
|
TAILQ_ENTRY(broadif) link;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TAILQ_HEAD(, broadif) broadlist_t;
|
||||||
|
|
||||||
|
int __rpc_getbroadifs(int, int, int, broadlist_t *);
|
||||||
|
void __rpc_freebroadifs(broadlist_t *);
|
||||||
|
int __rpc_broadenable(int, int, struct broadif *);
|
||||||
|
|
||||||
|
int __rpc_lowvers = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
__rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
struct broadif *bip;
|
||||||
|
struct ifaddrs *ifap, *ifp;
|
||||||
|
#ifdef INET6
|
||||||
|
struct sockaddr_in6 *sin6;
|
||||||
|
#endif
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifp) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
|
||||||
|
hints.ai_family = af;
|
||||||
|
hints.ai_protocol = proto;
|
||||||
|
hints.ai_socktype = socktype;
|
||||||
|
|
||||||
|
if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
|
||||||
|
if (ifap->ifa_addr == NULL || /* happens for eg tuntap devices */
|
||||||
|
ifap->ifa_addr->sa_family != af ||
|
||||||
|
!(ifap->ifa_flags & IFF_UP))
|
||||||
|
continue;
|
||||||
|
bip = (struct broadif *)malloc(sizeof *bip);
|
||||||
|
if (bip == NULL)
|
||||||
|
break;
|
||||||
|
bip->index = if_nametoindex(ifap->ifa_name);
|
||||||
|
if (
|
||||||
|
#ifdef INET6
|
||||||
|
af != AF_INET6 &&
|
||||||
|
#endif
|
||||||
|
(ifap->ifa_flags & IFF_BROADCAST) &&
|
||||||
|
ifap->ifa_broadaddr) {
|
||||||
|
/* memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
|
||||||
|
(size_t)ifap->ifa_broadaddr->sa_len);*/
|
||||||
|
memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
|
||||||
|
sizeof(bip->broadaddr));
|
||||||
|
sin = (struct sockaddr_in *)(void *)&bip->broadaddr;
|
||||||
|
sin->sin_port =
|
||||||
|
((struct sockaddr_in *)
|
||||||
|
(void *)res->ai_addr)->sin_port;
|
||||||
|
} else
|
||||||
|
#ifdef INET6
|
||||||
|
if (af == AF_INET6 && (ifap->ifa_flags & IFF_MULTICAST)) {
|
||||||
|
sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr;
|
||||||
|
inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr);
|
||||||
|
sin6->sin6_family = af;
|
||||||
|
sin6->sin6_port =
|
||||||
|
((struct sockaddr_in6 *)
|
||||||
|
(void *)res->ai_addr)->sin6_port;
|
||||||
|
sin6->sin6_scope_id = bip->index;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
free(bip);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TAILQ_INSERT_TAIL(list, bip, link);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
freeifaddrs(ifp);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__rpc_freebroadifs(broadlist_t *list)
|
||||||
|
{
|
||||||
|
struct broadif *bip, *next;
|
||||||
|
|
||||||
|
bip = TAILQ_FIRST(list);
|
||||||
|
|
||||||
|
while (bip != NULL) {
|
||||||
|
next = TAILQ_NEXT(bip, link);
|
||||||
|
free(bip);
|
||||||
|
bip = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
/*ARGSUSED*/
|
||||||
|
__rpc_broadenable(int af, int s, struct broadif *bip)
|
||||||
|
{
|
||||||
|
int o = 1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (af == AF_INET6) {
|
||||||
|
fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
|
||||||
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
|
||||||
|
sizeof bip->index) < 0)
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some rpcbind implementations use an IPv6 socket to serve both
|
||||||
|
* IPv4 and IPv6 messages, but neglect to check for the caller's
|
||||||
|
* address family when sending broadcast replies. These rpcbind
|
||||||
|
* implementations return an IPv6 address in reply to an IPv4
|
||||||
|
* broadcast. We can either ignore them, or try to patch them up.
|
||||||
|
*/
|
||||||
|
static struct netbuf *
|
||||||
|
__ipv6v4_fixup(struct sockaddr_storage *ss, const char *uaddr)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
struct netbuf *np;
|
||||||
|
|
||||||
|
/* ss is the remote rpcbind server's address */
|
||||||
|
if (ss->ss_family != AF_INET)
|
||||||
|
return NULL;
|
||||||
|
memcpy(&sin, ss, sizeof(sin));
|
||||||
|
|
||||||
|
np = __rpc_uaddr2taddr_af(AF_INET6, uaddr);
|
||||||
|
if (np == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Overwrite the port with that of the service we
|
||||||
|
* wanted to talk to. */
|
||||||
|
sin.sin_port = ((struct sockaddr_in6 *) np)->sin6_port;
|
||||||
|
|
||||||
|
/* We know netbuf holds a sockaddr_in6, so it can easily
|
||||||
|
* hold a sockaddr_in as well. */
|
||||||
|
memcpy(np->buf, &sin, sizeof(sin));
|
||||||
|
np->len = sizeof(sin);
|
||||||
|
|
||||||
|
return np;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||||
|
eachresult, inittime, waittime, nettype)
|
||||||
|
rpcprog_t prog; /* program number */
|
||||||
|
rpcvers_t vers; /* version number */
|
||||||
|
rpcproc_t proc; /* procedure number */
|
||||||
|
xdrproc_t xargs; /* xdr routine for args */
|
||||||
|
caddr_t argsp; /* pointer to args */
|
||||||
|
xdrproc_t xresults; /* xdr routine for results */
|
||||||
|
caddr_t resultsp; /* pointer to results */
|
||||||
|
resultproc_t eachresult; /* call with each result obtained */
|
||||||
|
int inittime; /* how long to wait initially */
|
||||||
|
int waittime; /* maximum time to wait */
|
||||||
|
const char *nettype; /* transport type */
|
||||||
|
{
|
||||||
|
enum clnt_stat stat = RPC_SUCCESS; /* Return status */
|
||||||
|
XDR xdr_stream; /* XDR stream */
|
||||||
|
XDR *xdrs = &xdr_stream;
|
||||||
|
struct rpc_msg msg; /* RPC message */
|
||||||
|
struct timeval t;
|
||||||
|
char *outbuf = NULL; /* Broadcast msg buffer */
|
||||||
|
char *inbuf = NULL; /* Reply buf */
|
||||||
|
int inlen;
|
||||||
|
u_int maxbufsize = 0;
|
||||||
|
AUTH *sys_auth = authunix_create_default();
|
||||||
|
int i;
|
||||||
|
void *handle;
|
||||||
|
char uaddress[1024]; /* A self imposed limit */
|
||||||
|
char *uaddrp = uaddress;
|
||||||
|
int pmap_reply_flag; /* reply recvd from PORTMAP */
|
||||||
|
/* An array of all the suitable broadcast transports */
|
||||||
|
struct {
|
||||||
|
int fd; /* File descriptor */
|
||||||
|
int af;
|
||||||
|
int proto;
|
||||||
|
struct netconfig *nconf; /* Netconfig structure */
|
||||||
|
u_int asize; /* Size of the addr buf */
|
||||||
|
u_int dsize; /* Size of the data buf */
|
||||||
|
struct sockaddr_storage raddr; /* Remote address */
|
||||||
|
broadlist_t nal;
|
||||||
|
} fdlist[MAXBCAST];
|
||||||
|
struct pollfd pfd[MAXBCAST];
|
||||||
|
size_t fdlistno = 0;
|
||||||
|
struct r_rpcb_rmtcallargs barg; /* Remote arguments */
|
||||||
|
struct r_rpcb_rmtcallres bres; /* Remote results */
|
||||||
|
size_t outlen;
|
||||||
|
struct netconfig *nconf;
|
||||||
|
int msec;
|
||||||
|
int pollretval;
|
||||||
|
int fds_found;
|
||||||
|
|
||||||
|
#ifdef PORTMAP
|
||||||
|
size_t outlen_pmap = 0;
|
||||||
|
u_long port; /* Remote port number */
|
||||||
|
int pmap_flag = 0; /* UDP exists ? */
|
||||||
|
char *outbuf_pmap = NULL;
|
||||||
|
struct rmtcallargs barg_pmap; /* Remote arguments */
|
||||||
|
struct rmtcallres bres_pmap; /* Remote results */
|
||||||
|
u_int udpbufsz = 0;
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
|
||||||
|
if (sys_auth == NULL) {
|
||||||
|
return (RPC_SYSTEMERROR);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* initialization: create a fd, a broadcast address, and send the
|
||||||
|
* request on the broadcast transport.
|
||||||
|
* Listen on all of them and on replies, call the user supplied
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (nettype == NULL)
|
||||||
|
nettype = "datagram_n";
|
||||||
|
if ((handle = __rpc_setconf(nettype)) == NULL) {
|
||||||
|
AUTH_DESTROY(sys_auth);
|
||||||
|
return (RPC_UNKNOWNPROTO);
|
||||||
|
}
|
||||||
|
while ((nconf = __rpc_getconf(handle)) != NULL) {
|
||||||
|
int fd;
|
||||||
|
struct __rpc_sockinfo si;
|
||||||
|
|
||||||
|
if (nconf->nc_semantics != NC_TPI_CLTS)
|
||||||
|
continue;
|
||||||
|
if (fdlistno >= MAXBCAST)
|
||||||
|
break; /* No more slots available */
|
||||||
|
if (!__rpc_nconf2sockinfo(nconf, &si))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TAILQ_INIT(&fdlist[fdlistno].nal);
|
||||||
|
if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype,
|
||||||
|
&fdlist[fdlistno].nal) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fd = socket(si.si_af, si.si_socktype, si.si_proto);
|
||||||
|
if (fd < 0) {
|
||||||
|
stat = RPC_CANTSEND;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fdlist[fdlistno].af = si.si_af;
|
||||||
|
fdlist[fdlistno].proto = si.si_proto;
|
||||||
|
fdlist[fdlistno].fd = fd;
|
||||||
|
fdlist[fdlistno].nconf = nconf;
|
||||||
|
fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
|
||||||
|
pfd[fdlistno].events = POLLIN | POLLPRI |
|
||||||
|
POLLRDNORM | POLLRDBAND;
|
||||||
|
pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
|
||||||
|
fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (maxbufsize <= fdlist[fdlistno].dsize)
|
||||||
|
maxbufsize = fdlist[fdlistno].dsize;
|
||||||
|
|
||||||
|
#ifdef PORTMAP
|
||||||
|
if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
|
||||||
|
udpbufsz = fdlist[fdlistno].dsize;
|
||||||
|
if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
|
||||||
|
close(fd);
|
||||||
|
stat = RPC_SYSTEMERROR;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
pmap_flag = 1;
|
||||||
|
}
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
fdlistno++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdlistno == 0) {
|
||||||
|
if (stat == RPC_SUCCESS)
|
||||||
|
stat = RPC_UNKNOWNPROTO;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
if (maxbufsize == 0) {
|
||||||
|
if (stat == RPC_SUCCESS)
|
||||||
|
stat = RPC_CANTSEND;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
inbuf = malloc(maxbufsize);
|
||||||
|
outbuf = malloc(maxbufsize);
|
||||||
|
if ((inbuf == NULL) || (outbuf == NULL)) {
|
||||||
|
stat = RPC_SYSTEMERROR;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Serialize all the arguments which have to be sent */
|
||||||
|
(void) gettimeofday(&t, NULL);
|
||||||
|
msg.rm_xid = __RPC_GETXID(&t);
|
||||||
|
msg.rm_direction = CALL;
|
||||||
|
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||||
|
msg.rm_call.cb_prog = RPCBPROG;
|
||||||
|
msg.rm_call.cb_vers = RPCBVERS;
|
||||||
|
msg.rm_call.cb_proc = RPCBPROC_CALLIT;
|
||||||
|
barg.prog = prog;
|
||||||
|
barg.vers = vers;
|
||||||
|
barg.proc = proc;
|
||||||
|
barg.args.args_val = argsp;
|
||||||
|
barg.xdr_args = xargs;
|
||||||
|
bres.addr = uaddrp;
|
||||||
|
bres.results.results_val = resultsp;
|
||||||
|
bres.xdr_res = xresults;
|
||||||
|
msg.rm_call.cb_cred = sys_auth->ah_cred;
|
||||||
|
msg.rm_call.cb_verf = sys_auth->ah_verf;
|
||||||
|
xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
|
||||||
|
if ((!xdr_callmsg(xdrs, &msg)) ||
|
||||||
|
(!xdr_rpcb_rmtcallargs(xdrs,
|
||||||
|
(struct rpcb_rmtcallargs *)(void *)&barg))) {
|
||||||
|
stat = RPC_CANTENCODEARGS;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
outlen = xdr_getpos(xdrs);
|
||||||
|
xdr_destroy(xdrs);
|
||||||
|
|
||||||
|
#ifdef PORTMAP
|
||||||
|
/* Prepare the packet for version 2 PORTMAP */
|
||||||
|
if (pmap_flag) {
|
||||||
|
msg.rm_xid++; /* One way to distinguish */
|
||||||
|
msg.rm_call.cb_prog = PMAPPROG;
|
||||||
|
msg.rm_call.cb_vers = PMAPVERS;
|
||||||
|
msg.rm_call.cb_proc = PMAPPROC_CALLIT;
|
||||||
|
barg_pmap.prog = prog;
|
||||||
|
barg_pmap.vers = vers;
|
||||||
|
barg_pmap.proc = proc;
|
||||||
|
barg_pmap.args_ptr = argsp;
|
||||||
|
barg_pmap.xdr_args = xargs;
|
||||||
|
bres_pmap.port_ptr = &port;
|
||||||
|
bres_pmap.xdr_results = xresults;
|
||||||
|
bres_pmap.results_ptr = resultsp;
|
||||||
|
xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
|
||||||
|
if ((! xdr_callmsg(xdrs, &msg)) ||
|
||||||
|
(! xdr_rmtcall_args(xdrs, &barg_pmap))) {
|
||||||
|
stat = RPC_CANTENCODEARGS;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
outlen_pmap = xdr_getpos(xdrs);
|
||||||
|
xdr_destroy(xdrs);
|
||||||
|
}
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic loop: broadcast the packets to transports which
|
||||||
|
* support data packets of size such that one can encode
|
||||||
|
* all the arguments.
|
||||||
|
* Wait a while for response(s).
|
||||||
|
* The response timeout grows larger per iteration.
|
||||||
|
*/
|
||||||
|
for (msec = inittime; msec <= waittime; msec += msec) {
|
||||||
|
struct broadif *bip;
|
||||||
|
|
||||||
|
/* Broadcast all the packets now */
|
||||||
|
for (i = 0; i < fdlistno; i++) {
|
||||||
|
if (fdlist[i].dsize < outlen) {
|
||||||
|
stat = RPC_CANTSEND;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
|
||||||
|
bip = TAILQ_NEXT(bip, link)) {
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
addr = &bip->broadaddr;
|
||||||
|
|
||||||
|
__rpc_broadenable(fdlist[i].af, fdlist[i].fd,
|
||||||
|
bip);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only use version 3 if lowvers is not set
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!__rpc_lowvers)
|
||||||
|
if (sendto(fdlist[i].fd, outbuf,
|
||||||
|
outlen, 0, (struct sockaddr*)addr,
|
||||||
|
(size_t)fdlist[i].asize) !=
|
||||||
|
outlen) {
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("rpc_broadcast_exp: sendto failed: errno %d", errno));
|
||||||
|
warnx("rpc_broadcast_exp: cannot send broadcast packet");
|
||||||
|
stat = RPC_CANTSEND;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if (!__rpc_lowvers)
|
||||||
|
LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: Broadcast packet sent for %s\n",
|
||||||
|
fdlist[i].nconf->nc_netid));
|
||||||
|
#ifdef PORTMAP
|
||||||
|
/*
|
||||||
|
* Send the version 2 packet also
|
||||||
|
* for UDP/IP
|
||||||
|
*/
|
||||||
|
if (pmap_flag &&
|
||||||
|
fdlist[i].proto == IPPROTO_UDP) {
|
||||||
|
if (sendto(fdlist[i].fd, outbuf_pmap,
|
||||||
|
outlen_pmap, 0, addr,
|
||||||
|
(size_t)fdlist[i].asize) !=
|
||||||
|
outlen_pmap) {
|
||||||
|
warnx("clnt_bcast: "
|
||||||
|
"Cannot send broadcast packet");
|
||||||
|
stat = RPC_CANTSEND;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: PMAP Broadcast packet sent for %s\n",
|
||||||
|
fdlist[i].nconf->nc_netid));
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
}
|
||||||
|
/* End for sending all packets on this transport */
|
||||||
|
} /* End for sending on all transports */
|
||||||
|
|
||||||
|
if (eachresult == NULL) {
|
||||||
|
stat = RPC_SUCCESS;
|
||||||
|
goto done_broad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get all the replies from these broadcast requests
|
||||||
|
*/
|
||||||
|
recv_again:
|
||||||
|
|
||||||
|
switch (pollretval = poll(pfd, fdlistno, msec)) {
|
||||||
|
case 0: /* timed out */
|
||||||
|
stat = RPC_TIMEDOUT;
|
||||||
|
continue;
|
||||||
|
case -1: /* some kind of error - we ignore it */
|
||||||
|
goto recv_again;
|
||||||
|
} /* end of poll results switch */
|
||||||
|
|
||||||
|
for (i = fds_found = 0;
|
||||||
|
i < fdlistno && fds_found < pollretval; i++) {
|
||||||
|
bool_t done = FALSE;
|
||||||
|
|
||||||
|
if (pfd[i].revents == 0)
|
||||||
|
continue;
|
||||||
|
else if (pfd[i].revents & POLLNVAL) {
|
||||||
|
/*
|
||||||
|
* Something bad has happened to this descri-
|
||||||
|
* ptor. We can cause _poll() to ignore
|
||||||
|
* it simply by using a negative fd. We do that
|
||||||
|
* rather than compacting the pfd[] and fdlist[]
|
||||||
|
* arrays.
|
||||||
|
*/
|
||||||
|
pfd[i].fd = -1;
|
||||||
|
fds_found++;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
fds_found++;
|
||||||
|
LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: response for %s\n",
|
||||||
|
fdlist[i].nconf->nc_netid));
|
||||||
|
try_again:
|
||||||
|
inlen = recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
|
||||||
|
0, (struct sockaddr *)(void *)&fdlist[i].raddr,
|
||||||
|
&fdlist[i].asize);
|
||||||
|
if (inlen < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
goto try_again;
|
||||||
|
warnx("clnt_bcast: Cannot receive reply to "
|
||||||
|
"broadcast");
|
||||||
|
stat = RPC_CANTRECV;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inlen < sizeof (u_int32_t))
|
||||||
|
continue; /* Drop that and go ahead */
|
||||||
|
/*
|
||||||
|
* see if reply transaction id matches sent id.
|
||||||
|
* If so, decode the results. If return id is xid + 1
|
||||||
|
* it was a PORTMAP reply
|
||||||
|
*/
|
||||||
|
if (*((u_int32_t *)(void *)(inbuf)) ==
|
||||||
|
*((u_int32_t *)(void *)(outbuf))) {
|
||||||
|
pmap_reply_flag = 0;
|
||||||
|
msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
msg.acpted_rply.ar_results.where =
|
||||||
|
(caddr_t)(void *)&bres;
|
||||||
|
msg.acpted_rply.ar_results.proc =
|
||||||
|
(xdrproc_t)xdr_rpcb_rmtcallres;
|
||||||
|
#ifdef PORTMAP
|
||||||
|
} else if (pmap_flag &&
|
||||||
|
*((u_int32_t *)(void *)(inbuf)) ==
|
||||||
|
*((u_int32_t *)(void *)(outbuf_pmap))) {
|
||||||
|
pmap_reply_flag = 1;
|
||||||
|
msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
msg.acpted_rply.ar_results.where =
|
||||||
|
(caddr_t)(void *)&bres_pmap;
|
||||||
|
msg.acpted_rply.ar_results.proc =
|
||||||
|
(xdrproc_t)xdr_rmtcallres;
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
|
||||||
|
if (xdr_replymsg(xdrs, &msg)) {
|
||||||
|
if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
|
||||||
|
(msg.acpted_rply.ar_stat == SUCCESS)) {
|
||||||
|
struct netbuf *np;
|
||||||
|
#ifdef PORTMAP
|
||||||
|
struct netbuf taddr;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
if (pmap_flag && pmap_reply_flag) {
|
||||||
|
memcpy(&sin, &fdlist[i].raddr, sizeof(sin));
|
||||||
|
sin.sin_port = htons((u_short)port);
|
||||||
|
memcpy(&fdlist[i].raddr, &sin, sizeof(sin));
|
||||||
|
taddr.len = taddr.maxlen =
|
||||||
|
sizeof(fdlist[i].raddr);
|
||||||
|
taddr.buf = &fdlist[i].raddr;
|
||||||
|
done = (*eachresult)(resultsp,
|
||||||
|
&taddr, fdlist[i].nconf);
|
||||||
|
} else {
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
LIBTIRPC_DEBUG(3, ("rpc_broadcast_exp: uaddr %s\n", uaddrp));
|
||||||
|
np = uaddr2taddr(
|
||||||
|
fdlist[i].nconf, uaddrp);
|
||||||
|
/* Some misguided rpcbind implemenations
|
||||||
|
* seem to return an IPv6 uaddr in IPv4
|
||||||
|
* responses. */
|
||||||
|
if (np == NULL)
|
||||||
|
np = __ipv6v4_fixup(
|
||||||
|
&fdlist[i].raddr,
|
||||||
|
uaddrp);
|
||||||
|
if (np != NULL) {
|
||||||
|
done = (*eachresult)(resultsp,
|
||||||
|
np, fdlist[i].nconf);
|
||||||
|
free(np);
|
||||||
|
}
|
||||||
|
#ifdef PORTMAP
|
||||||
|
}
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
}
|
||||||
|
/* otherwise, we just ignore the errors ... */
|
||||||
|
}
|
||||||
|
/* else some kind of deserialization problem ... */
|
||||||
|
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
|
||||||
|
(void) xdr_replymsg(xdrs, &msg);
|
||||||
|
(void) (*xresults)(xdrs, resultsp);
|
||||||
|
XDR_DESTROY(xdrs);
|
||||||
|
if (done) {
|
||||||
|
stat = RPC_SUCCESS;
|
||||||
|
goto done_broad;
|
||||||
|
} else {
|
||||||
|
goto recv_again;
|
||||||
|
}
|
||||||
|
} /* The recv for loop */
|
||||||
|
} /* The giant for loop */
|
||||||
|
|
||||||
|
done_broad:
|
||||||
|
if (inbuf)
|
||||||
|
(void) free(inbuf);
|
||||||
|
if (outbuf)
|
||||||
|
(void) free(outbuf);
|
||||||
|
#ifdef PORTMAP
|
||||||
|
if (outbuf_pmap)
|
||||||
|
(void) free(outbuf_pmap);
|
||||||
|
#endif /* PORTMAP */
|
||||||
|
for (i = 0; i < fdlistno; i++) {
|
||||||
|
(void)close(fdlist[i].fd);
|
||||||
|
__rpc_freebroadifs(&fdlist[i].nal);
|
||||||
|
}
|
||||||
|
AUTH_DESTROY(sys_auth);
|
||||||
|
(void) __rpc_endconf(handle);
|
||||||
|
|
||||||
|
return (stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum clnt_stat
|
||||||
|
rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||||
|
eachresult, nettype)
|
||||||
|
rpcprog_t prog; /* program number */
|
||||||
|
rpcvers_t vers; /* version number */
|
||||||
|
rpcproc_t proc; /* procedure number */
|
||||||
|
xdrproc_t xargs; /* xdr routine for args */
|
||||||
|
caddr_t argsp; /* pointer to args */
|
||||||
|
xdrproc_t xresults; /* xdr routine for results */
|
||||||
|
caddr_t resultsp; /* pointer to results */
|
||||||
|
resultproc_t eachresult; /* call with each result obtained */
|
||||||
|
const char *nettype; /* transport type */
|
||||||
|
{
|
||||||
|
enum clnt_stat dummy;
|
||||||
|
|
||||||
|
dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp,
|
||||||
|
xresults, resultsp, eachresult,
|
||||||
|
INITTIME, WAITTIME, nettype);
|
||||||
|
return (dummy);
|
||||||
|
}
|
||||||
788
libtirpc-1.3.1/src/clnt_dg.c
Normal file
788
libtirpc-1.3.1/src/clnt_dg.c
Normal file
@ -0,0 +1,788 @@
|
|||||||
|
/*
|
||||||
|
* 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-1991 by Sun Microsystems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implements a connectionless client side RPC.
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
#include "clnt_fd_locks.h"
|
||||||
|
|
||||||
|
#ifdef IP_RECVERR
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <linux/errqueue.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_DEFAULT_FDS 20000
|
||||||
|
|
||||||
|
static struct clnt_ops *clnt_dg_ops(void);
|
||||||
|
static bool_t time_not_ok(struct timeval *);
|
||||||
|
static enum clnt_stat clnt_dg_call(CLIENT *, rpcproc_t, xdrproc_t, void *,
|
||||||
|
xdrproc_t, void *, struct timeval);
|
||||||
|
static void clnt_dg_geterr(CLIENT *, struct rpc_err *);
|
||||||
|
static bool_t clnt_dg_freeres(CLIENT *, xdrproc_t, void *);
|
||||||
|
static void clnt_dg_abort(CLIENT *);
|
||||||
|
static bool_t clnt_dg_control(CLIENT *, u_int, void *);
|
||||||
|
static void clnt_dg_destroy(CLIENT *);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This machinery implements per-fd locks for MT-safety. It is not
|
||||||
|
* sufficient to do per-CLIENT handle locks for MT-safety because a
|
||||||
|
* user may create more than one CLIENT handle with the same fd behind
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* We keep track of a list of per-fd locks, protected by the clnt_fd_lock
|
||||||
|
* mutex. Each per-fd lock consists of a predicate indicating whether is
|
||||||
|
* active or not: fd_lock->active == TRUE => a call is active on some
|
||||||
|
* CLIENT handle created for that fd. Each fd predicate is guarded by a
|
||||||
|
* condition variable so that the global mutex can be unlocked while
|
||||||
|
* waiting for the predicate to change.
|
||||||
|
*
|
||||||
|
* The current implementation holds locks across the entire RPC and reply,
|
||||||
|
* including retransmissions. Yes, this is silly, and as soon as this
|
||||||
|
* code is proven to work, this should be the first thing fixed. One step
|
||||||
|
* at a time.
|
||||||
|
*/
|
||||||
|
static fd_locks_t *dg_fd_locks;
|
||||||
|
extern mutex_t clnt_fd_lock;
|
||||||
|
#define release_fd_lock(fd_lock, mask) { \
|
||||||
|
mutex_lock(&clnt_fd_lock); \
|
||||||
|
fd_lock->active = FALSE; \
|
||||||
|
mutex_unlock(&clnt_fd_lock); \
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL); \
|
||||||
|
cond_signal(&fd_lock->cv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory";
|
||||||
|
|
||||||
|
/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private data kept per client handle
|
||||||
|
*/
|
||||||
|
struct cu_data {
|
||||||
|
int cu_fd; /* connections fd */
|
||||||
|
fd_lock_t *cu_fd_lock;
|
||||||
|
bool_t cu_closeit; /* opened by library */
|
||||||
|
struct sockaddr_storage cu_raddr; /* remote address */
|
||||||
|
int cu_rlen;
|
||||||
|
struct timeval cu_wait; /* retransmit interval */
|
||||||
|
struct timeval cu_total; /* total time for the call */
|
||||||
|
struct rpc_err cu_error;
|
||||||
|
XDR cu_outxdrs;
|
||||||
|
u_int cu_xdrpos;
|
||||||
|
u_int cu_sendsz; /* send size */
|
||||||
|
char *cu_outbuf;
|
||||||
|
u_int cu_recvsz; /* recv size */
|
||||||
|
int cu_async;
|
||||||
|
int cu_connect; /* Use connect(). */
|
||||||
|
int cu_connected; /* Have done connect(). */
|
||||||
|
char cu_inbuf[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connection less client creation returns with client handle parameters.
|
||||||
|
* Default options are set, which the user can change using clnt_control().
|
||||||
|
* fd should be open and bound.
|
||||||
|
* NB: The rpch->cl_auth is initialized to null authentication.
|
||||||
|
* Caller may wish to set this something more useful.
|
||||||
|
*
|
||||||
|
* sendsz and recvsz are the maximum allowable packet sizes that can be
|
||||||
|
* sent and received. Normally they are the same, but they can be
|
||||||
|
* changed to improve the program efficiency and buffer allocation.
|
||||||
|
* If they are 0, use the transport default.
|
||||||
|
*
|
||||||
|
* If svcaddr is NULL, returns NULL.
|
||||||
|
*/
|
||||||
|
CLIENT *
|
||||||
|
clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz)
|
||||||
|
int fd; /* open file descriptor */
|
||||||
|
const struct netbuf *svcaddr; /* servers address */
|
||||||
|
rpcprog_t program; /* program number */
|
||||||
|
rpcvers_t version; /* version number */
|
||||||
|
u_int sendsz; /* buffer recv size */
|
||||||
|
u_int recvsz; /* buffer send size */
|
||||||
|
{
|
||||||
|
CLIENT *cl = NULL; /* client handle */
|
||||||
|
struct cu_data *cu = NULL; /* private data */
|
||||||
|
struct timeval now;
|
||||||
|
struct rpc_msg call_msg;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
struct __rpc_sockinfo si;
|
||||||
|
int one = 1;
|
||||||
|
fd_lock_t *fd_lock;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
if (dg_fd_locks == (fd_locks_t *) NULL) {
|
||||||
|
dg_fd_locks = fd_locks_init();
|
||||||
|
if (dg_fd_locks == (fd_locks_t *) NULL) {
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fd_lock = fd_lock_create(fd, dg_fd_locks);
|
||||||
|
if (fd_lock == (fd_lock_t *) NULL)
|
||||||
|
goto err1;
|
||||||
|
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
|
||||||
|
if (svcaddr == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!__rpc_fd2sockinfo(fd, &si)) {
|
||||||
|
rpc_createerr.cf_stat = RPC_TLIERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = 0;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Find the receive and the send size
|
||||||
|
*/
|
||||||
|
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
|
||||||
|
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
|
||||||
|
if ((sendsz == 0) || (recvsz == 0)) {
|
||||||
|
rpc_createerr.cf_stat = RPC_TLIERROR; /* XXX */
|
||||||
|
rpc_createerr.cf_error.re_errno = 0;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cl = mem_alloc(sizeof (CLIENT))) == NULL)
|
||||||
|
goto err1;
|
||||||
|
/*
|
||||||
|
* Should be multiple of 4 for XDR.
|
||||||
|
*/
|
||||||
|
sendsz = ((sendsz + 3) / 4) * 4;
|
||||||
|
recvsz = ((recvsz + 3) / 4) * 4;
|
||||||
|
cu = mem_alloc(sizeof (*cu) + sendsz + recvsz);
|
||||||
|
if (cu == NULL)
|
||||||
|
goto err1;
|
||||||
|
(void) memcpy(&cu->cu_raddr, svcaddr->buf, (size_t)svcaddr->len);
|
||||||
|
cu->cu_rlen = svcaddr->len;
|
||||||
|
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
|
||||||
|
/* Other values can also be set through clnt_control() */
|
||||||
|
cu->cu_wait.tv_sec = 15; /* heuristically chosen */
|
||||||
|
cu->cu_wait.tv_usec = 0;
|
||||||
|
cu->cu_total.tv_sec = -1;
|
||||||
|
cu->cu_total.tv_usec = -1;
|
||||||
|
cu->cu_sendsz = sendsz;
|
||||||
|
cu->cu_recvsz = recvsz;
|
||||||
|
cu->cu_async = FALSE;
|
||||||
|
cu->cu_connect = FALSE;
|
||||||
|
cu->cu_connected = FALSE;
|
||||||
|
(void) gettimeofday(&now, NULL);
|
||||||
|
call_msg.rm_xid = __RPC_GETXID(&now);
|
||||||
|
call_msg.rm_call.cb_prog = program;
|
||||||
|
call_msg.rm_call.cb_vers = version;
|
||||||
|
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
|
||||||
|
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
|
||||||
|
rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */
|
||||||
|
rpc_createerr.cf_error.re_errno = 0;
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
|
||||||
|
|
||||||
|
/* XXX fvdl - do we still want this? */
|
||||||
|
#if 0
|
||||||
|
(void)bindresvport_sa(fd, (struct sockaddr *)svcaddr->buf);
|
||||||
|
#endif
|
||||||
|
#ifdef IP_RECVERR
|
||||||
|
{
|
||||||
|
int on = 1;
|
||||||
|
setsockopt(fd, SOL_IP, IP_RECVERR, &on, sizeof(on));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ioctl(fd, FIONBIO, (char *)(void *)&one);
|
||||||
|
/*
|
||||||
|
* By default, closeit is always FALSE. It is users responsibility
|
||||||
|
* to do a close on it, else the user may use clnt_control
|
||||||
|
* to let clnt_destroy do it for him/her.
|
||||||
|
*/
|
||||||
|
cu->cu_closeit = FALSE;
|
||||||
|
cu->cu_fd = fd;
|
||||||
|
cu->cu_fd_lock = fd_lock;
|
||||||
|
cl->cl_ops = clnt_dg_ops();
|
||||||
|
cl->cl_private = (caddr_t)(void *)cu;
|
||||||
|
cl->cl_auth = authnone_create();
|
||||||
|
cl->cl_tp = NULL;
|
||||||
|
cl->cl_netid = NULL;
|
||||||
|
|
||||||
|
return (cl);
|
||||||
|
err1:
|
||||||
|
warnx(mem_err_clnt_dg);
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = errno;
|
||||||
|
err2:
|
||||||
|
if (cl) {
|
||||||
|
mem_free(cl, sizeof (CLIENT));
|
||||||
|
if (cu)
|
||||||
|
mem_free(cu, sizeof (*cu) + sendsz + recvsz);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum clnt_stat
|
||||||
|
clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
|
||||||
|
CLIENT *cl; /* client handle */
|
||||||
|
rpcproc_t proc; /* procedure number */
|
||||||
|
xdrproc_t xargs; /* xdr routine for args */
|
||||||
|
void *argsp; /* pointer to args */
|
||||||
|
xdrproc_t xresults; /* xdr routine for results */
|
||||||
|
void *resultsp; /* pointer to results */
|
||||||
|
struct timeval utimeout; /* seconds to wait before giving up */
|
||||||
|
{
|
||||||
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||||
|
XDR *xdrs;
|
||||||
|
size_t outlen = 0;
|
||||||
|
struct rpc_msg reply_msg;
|
||||||
|
XDR reply_xdrs;
|
||||||
|
bool_t ok;
|
||||||
|
int nrefreshes = 2; /* number of times to refresh cred */
|
||||||
|
struct timeval timeout;
|
||||||
|
struct pollfd fd;
|
||||||
|
int total_time, nextsend_time, tv=0;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
socklen_t salen;
|
||||||
|
ssize_t recvlen = 0;
|
||||||
|
u_int32_t xid, inval, outval;
|
||||||
|
|
||||||
|
outlen = 0;
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (cu->cu_fd_lock->active)
|
||||||
|
cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
cu->cu_fd_lock->active = TRUE;
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
if (cu->cu_total.tv_usec == -1) {
|
||||||
|
timeout = utimeout; /* use supplied timeout */
|
||||||
|
} else {
|
||||||
|
timeout = cu->cu_total; /* use default timeout */
|
||||||
|
}
|
||||||
|
total_time = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
|
||||||
|
nextsend_time = cu->cu_wait.tv_sec * 1000 + cu->cu_wait.tv_usec / 1000;
|
||||||
|
|
||||||
|
if (cu->cu_connect && !cu->cu_connected) {
|
||||||
|
if (connect(cu->cu_fd, (struct sockaddr *)&cu->cu_raddr,
|
||||||
|
cu->cu_rlen) < 0) {
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
cu->cu_error.re_status = RPC_CANTSEND;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cu->cu_connected = 1;
|
||||||
|
}
|
||||||
|
if (cu->cu_connected) {
|
||||||
|
sa = NULL;
|
||||||
|
salen = 0;
|
||||||
|
} else {
|
||||||
|
sa = (struct sockaddr *)&cu->cu_raddr;
|
||||||
|
salen = cu->cu_rlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up in case the last call ended in a longjmp(3) call. */
|
||||||
|
call_again:
|
||||||
|
xdrs = &(cu->cu_outxdrs);
|
||||||
|
if (cu->cu_async == TRUE && xargs == NULL)
|
||||||
|
goto get_reply;
|
||||||
|
xdrs->x_op = XDR_ENCODE;
|
||||||
|
XDR_SETPOS(xdrs, cu->cu_xdrpos);
|
||||||
|
/*
|
||||||
|
* the transaction is the first thing in the out buffer
|
||||||
|
* XXX Yes, and it's in network byte order, so we should to
|
||||||
|
* be careful when we increment it, shouldn't we.
|
||||||
|
*/
|
||||||
|
xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf));
|
||||||
|
xid++;
|
||||||
|
*(u_int32_t *)(void *)(cu->cu_outbuf) = htonl(xid);
|
||||||
|
|
||||||
|
if ((! XDR_PUTINT32(xdrs, (int32_t *)&proc)) ||
|
||||||
|
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
|
||||||
|
(! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp))) {
|
||||||
|
cu->cu_error.re_status = RPC_CANTENCODEARGS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
outlen = (size_t)XDR_GETPOS(xdrs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hack to provide rpc-based message passing
|
||||||
|
*/
|
||||||
|
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||||
|
cu->cu_error.re_status = RPC_TIMEDOUT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_again:
|
||||||
|
if (total_time <= 0) {
|
||||||
|
cu->cu_error.re_status = RPC_TIMEDOUT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
nextsend_time = cu->cu_wait.tv_sec * 1000 + cu->cu_wait.tv_usec / 1000;
|
||||||
|
if (sendto(cu->cu_fd, cu->cu_outbuf, outlen, 0, sa, salen) != outlen) {
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
cu->cu_error.re_status = RPC_CANTSEND;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_reply:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sub-optimal code appears here because we have
|
||||||
|
* some clock time to spare while the packets are in flight.
|
||||||
|
* (We assume that this is actually only executed once.)
|
||||||
|
*/
|
||||||
|
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
reply_msg.acpted_rply.ar_results.where = NULL;
|
||||||
|
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
|
||||||
|
|
||||||
|
fd.fd = cu->cu_fd;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
fd.revents = 0;
|
||||||
|
while (total_time > 0) {
|
||||||
|
tv = total_time < nextsend_time ? total_time : nextsend_time;
|
||||||
|
switch (poll(&fd, 1, tv)) {
|
||||||
|
case 0:
|
||||||
|
total_time -= tv;
|
||||||
|
goto send_again;
|
||||||
|
case -1:
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
cu->cu_error.re_status = RPC_CANTRECV;
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef IP_RECVERR
|
||||||
|
if (fd.revents & POLLERR)
|
||||||
|
{
|
||||||
|
struct msghdr msg;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct sock_extended_err *e;
|
||||||
|
struct sockaddr_in err_addr;
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in *)&cu->cu_raddr;
|
||||||
|
struct iovec iov;
|
||||||
|
char *cbuf = (char *) mem_alloc((outlen + 256));
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (cbuf == NULL)
|
||||||
|
{
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||||
|
}
|
||||||
|
iov.iov_base = cbuf + 256;
|
||||||
|
iov.iov_len = outlen;
|
||||||
|
msg.msg_name = (void *) &err_addr;
|
||||||
|
msg.msg_namelen = sizeof (err_addr);
|
||||||
|
msg.msg_iov = &iov;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
msg.msg_control = cbuf;
|
||||||
|
msg.msg_controllen = 256;
|
||||||
|
ret = recvmsg (cu->cu_fd, &msg, MSG_ERRQUEUE);
|
||||||
|
if (ret >= 0
|
||||||
|
&& memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0
|
||||||
|
&& (msg.msg_flags & MSG_ERRQUEUE)
|
||||||
|
&& ((msg.msg_namelen == 0
|
||||||
|
&& ret >= 12)
|
||||||
|
|| (msg.msg_namelen == sizeof (err_addr)
|
||||||
|
&& err_addr.sin_family == AF_INET
|
||||||
|
&& memcmp (&err_addr.sin_addr, &sin->sin_addr,
|
||||||
|
sizeof (err_addr.sin_addr)) == 0
|
||||||
|
&& err_addr.sin_port == sin->sin_port)))
|
||||||
|
for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;
|
||||||
|
cmsg = CMSG_NXTHDR (&msg, cmsg))
|
||||||
|
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
|
||||||
|
{
|
||||||
|
mem_free(cbuf, (outlen + 256));
|
||||||
|
e = (struct sock_extended_err *) CMSG_DATA(cmsg);
|
||||||
|
cu->cu_error.re_errno = e->ee_errno;
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||||
|
}
|
||||||
|
mem_free(cbuf, (outlen + 256));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We have some data now */
|
||||||
|
do {
|
||||||
|
recvlen = recvfrom(cu->cu_fd, cu->cu_inbuf,
|
||||||
|
cu->cu_recvsz, 0, NULL, NULL);
|
||||||
|
} while (recvlen < 0 && errno == EINTR);
|
||||||
|
if (recvlen < 0 && errno != EWOULDBLOCK) {
|
||||||
|
cu->cu_error.re_errno = errno;
|
||||||
|
cu->cu_error.re_status = RPC_CANTRECV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recvlen < sizeof(u_int32_t)) {
|
||||||
|
total_time -= tv;
|
||||||
|
goto send_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cu->cu_async == FALSE) {
|
||||||
|
memcpy(&inval, cu->cu_inbuf, sizeof(u_int32_t));
|
||||||
|
memcpy(&outval, cu->cu_outbuf, sizeof(u_int32_t));
|
||||||
|
if (inval != outval) {
|
||||||
|
total_time -= tv;
|
||||||
|
goto send_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now decode and validate the response
|
||||||
|
*/
|
||||||
|
|
||||||
|
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)recvlen, XDR_DECODE);
|
||||||
|
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
|
||||||
|
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
|
||||||
|
if (ok) {
|
||||||
|
if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
|
||||||
|
(reply_msg.acpted_rply.ar_stat == SUCCESS))
|
||||||
|
cu->cu_error.re_status = RPC_SUCCESS;
|
||||||
|
else
|
||||||
|
_seterr_reply(&reply_msg, &(cu->cu_error));
|
||||||
|
|
||||||
|
if (cu->cu_error.re_status == RPC_SUCCESS) {
|
||||||
|
if (! AUTH_VALIDATE(cl->cl_auth,
|
||||||
|
&reply_msg.acpted_rply.ar_verf)) {
|
||||||
|
cu->cu_error.re_status = RPC_AUTHERROR;
|
||||||
|
cu->cu_error.re_why = AUTH_INVALIDRESP;
|
||||||
|
} else if (! AUTH_UNWRAP(cl->cl_auth, &reply_xdrs,
|
||||||
|
xresults, resultsp)) {
|
||||||
|
if (cu->cu_error.re_status == RPC_SUCCESS)
|
||||||
|
cu->cu_error.re_status = RPC_CANTDECODERES;
|
||||||
|
}
|
||||||
|
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
(void) xdr_opaque_auth(xdrs,
|
||||||
|
&(reply_msg.acpted_rply.ar_verf));
|
||||||
|
}
|
||||||
|
} /* end successful completion */
|
||||||
|
/*
|
||||||
|
* If unsuccesful AND error is an authentication error
|
||||||
|
* then refresh credentials and try again, else break
|
||||||
|
*/
|
||||||
|
else if (cu->cu_error.re_status == RPC_AUTHERROR)
|
||||||
|
/* maybe our credentials need to be refreshed ... */
|
||||||
|
if (nrefreshes > 0 &&
|
||||||
|
AUTH_REFRESH(cl->cl_auth, &reply_msg)) {
|
||||||
|
nrefreshes--;
|
||||||
|
goto call_again;
|
||||||
|
}
|
||||||
|
/* end of unsuccessful completion */
|
||||||
|
} /* end of valid reply message */
|
||||||
|
else {
|
||||||
|
cu->cu_error.re_status = RPC_CANTDECODERES;
|
||||||
|
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (cu->cu_error.re_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clnt_dg_geterr(cl, errp)
|
||||||
|
CLIENT *cl;
|
||||||
|
struct rpc_err *errp;
|
||||||
|
{
|
||||||
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||||
|
|
||||||
|
*errp = cu->cu_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
clnt_dg_freeres(cl, xdr_res, res_ptr)
|
||||||
|
CLIENT *cl;
|
||||||
|
xdrproc_t xdr_res;
|
||||||
|
void *res_ptr;
|
||||||
|
{
|
||||||
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||||
|
XDR *xdrs = &(cu->cu_outxdrs);
|
||||||
|
bool_t dummy;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (cu->cu_fd_lock->active)
|
||||||
|
cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
cu->cu_fd_lock->active = TRUE;
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
dummy = (*xdr_res)(xdrs, res_ptr);
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||||
|
cond_signal(&cu->cu_fd_lock->cv);
|
||||||
|
return (dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
clnt_dg_abort(h)
|
||||||
|
CLIENT *h;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
clnt_dg_control(cl, request, info)
|
||||||
|
CLIENT *cl;
|
||||||
|
u_int request;
|
||||||
|
void *info;
|
||||||
|
{
|
||||||
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||||
|
struct netbuf *addr;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (cu->cu_fd_lock->active)
|
||||||
|
cond_wait(&cu->cu_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
cu->cu_fd_lock->active = TRUE;
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
switch (request) {
|
||||||
|
case CLSET_FD_CLOSE:
|
||||||
|
cu->cu_closeit = TRUE;
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
case CLSET_FD_NCLOSE:
|
||||||
|
cu->cu_closeit = FALSE;
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for other requests which use info */
|
||||||
|
if (info == NULL) {
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
switch (request) {
|
||||||
|
case CLSET_TIMEOUT:
|
||||||
|
if (time_not_ok((struct timeval *)info)) {
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
cu->cu_total = *(struct timeval *)info;
|
||||||
|
break;
|
||||||
|
case CLGET_TIMEOUT:
|
||||||
|
*(struct timeval *)info = cu->cu_total;
|
||||||
|
break;
|
||||||
|
case CLGET_SERVER_ADDR: /* Give him the fd address */
|
||||||
|
/* Now obsolete. Only for backward compatibility */
|
||||||
|
(void) memcpy(info, &cu->cu_raddr, (size_t)cu->cu_rlen);
|
||||||
|
break;
|
||||||
|
case CLSET_RETRY_TIMEOUT:
|
||||||
|
if (time_not_ok((struct timeval *)info)) {
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
cu->cu_wait = *(struct timeval *)info;
|
||||||
|
break;
|
||||||
|
case CLGET_RETRY_TIMEOUT:
|
||||||
|
*(struct timeval *)info = cu->cu_wait;
|
||||||
|
break;
|
||||||
|
case CLGET_FD:
|
||||||
|
*(int *)info = cu->cu_fd;
|
||||||
|
break;
|
||||||
|
case CLGET_SVC_ADDR:
|
||||||
|
addr = (struct netbuf *)info;
|
||||||
|
addr->buf = &cu->cu_raddr;
|
||||||
|
addr->len = cu->cu_rlen;
|
||||||
|
addr->maxlen = sizeof cu->cu_raddr;
|
||||||
|
break;
|
||||||
|
case CLSET_SVC_ADDR: /* set to new address */
|
||||||
|
addr = (struct netbuf *)info;
|
||||||
|
if (addr->len < sizeof cu->cu_raddr) {
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
(void) memcpy(&cu->cu_raddr, addr->buf, addr->len);
|
||||||
|
cu->cu_rlen = addr->len;
|
||||||
|
break;
|
||||||
|
case CLGET_XID:
|
||||||
|
/*
|
||||||
|
* use the knowledge that xid is the
|
||||||
|
* first element in the call structure *.
|
||||||
|
* This will get the xid of the PREVIOUS call
|
||||||
|
*/
|
||||||
|
*(u_int32_t *)info =
|
||||||
|
ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLSET_XID:
|
||||||
|
/* This will set the xid of the NEXT call */
|
||||||
|
*(u_int32_t *)(void *)cu->cu_outbuf =
|
||||||
|
htonl(*(u_int32_t *)info - 1);
|
||||||
|
/* decrement by 1 as clnt_dg_call() increments once */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLGET_VERS:
|
||||||
|
/*
|
||||||
|
* This RELIES on the information that, in the call body,
|
||||||
|
* the version number field is the fifth field from the
|
||||||
|
* begining of the RPC header. MUST be changed if the
|
||||||
|
* call_struct is changed
|
||||||
|
*/
|
||||||
|
*(u_int32_t *)info =
|
||||||
|
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
|
||||||
|
4 * BYTES_PER_XDR_UNIT));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLSET_VERS:
|
||||||
|
*(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
|
||||||
|
= htonl(*(u_int32_t *)info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLGET_PROG:
|
||||||
|
/*
|
||||||
|
* This RELIES on the information that, in the call body,
|
||||||
|
* the program number field is the fourth field from the
|
||||||
|
* begining of the RPC header. MUST be changed if the
|
||||||
|
* call_struct is changed
|
||||||
|
*/
|
||||||
|
*(u_int32_t *)info =
|
||||||
|
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
|
||||||
|
3 * BYTES_PER_XDR_UNIT));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLSET_PROG:
|
||||||
|
*(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
|
||||||
|
= htonl(*(u_int32_t *)info);
|
||||||
|
break;
|
||||||
|
case CLSET_ASYNC:
|
||||||
|
cu->cu_async = *(int *)info;
|
||||||
|
break;
|
||||||
|
case CLSET_CONNECT:
|
||||||
|
cu->cu_connect = *(int *)info;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
release_fd_lock(cu->cu_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clnt_dg_destroy(cl)
|
||||||
|
CLIENT *cl;
|
||||||
|
{
|
||||||
|
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||||
|
int cu_fd = cu->cu_fd;
|
||||||
|
fd_lock_t *cu_fd_lock = cu->cu_fd_lock;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (cu_fd_lock->active)
|
||||||
|
cond_wait(&cu_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
if (cu->cu_closeit)
|
||||||
|
(void)close(cu_fd);
|
||||||
|
XDR_DESTROY(&(cu->cu_outxdrs));
|
||||||
|
mem_free(cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
|
||||||
|
if (cl->cl_netid && cl->cl_netid[0])
|
||||||
|
mem_free(cl->cl_netid, strlen(cl->cl_netid) +1);
|
||||||
|
if (cl->cl_tp && cl->cl_tp[0])
|
||||||
|
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
|
||||||
|
mem_free(cl, sizeof (CLIENT));
|
||||||
|
cond_signal(&cu_fd_lock->cv);
|
||||||
|
fd_lock_destroy(cu_fd, cu_fd_lock, dg_fd_locks);
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clnt_ops *
|
||||||
|
clnt_dg_ops()
|
||||||
|
{
|
||||||
|
static struct clnt_ops ops;
|
||||||
|
extern mutex_t ops_lock;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&ops_lock);
|
||||||
|
if (ops.cl_call == NULL) {
|
||||||
|
ops.cl_call = clnt_dg_call;
|
||||||
|
ops.cl_abort = clnt_dg_abort;
|
||||||
|
ops.cl_geterr = clnt_dg_geterr;
|
||||||
|
ops.cl_freeres = clnt_dg_freeres;
|
||||||
|
ops.cl_destroy = clnt_dg_destroy;
|
||||||
|
ops.cl_control = clnt_dg_control;
|
||||||
|
}
|
||||||
|
mutex_unlock(&ops_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||||
|
return (&ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that the time is not garbage. -1 value is allowed.
|
||||||
|
*/
|
||||||
|
static bool_t
|
||||||
|
time_not_ok(t)
|
||||||
|
struct timeval *t;
|
||||||
|
{
|
||||||
|
return (t->tv_sec < -1 || t->tv_sec > 100000000 ||
|
||||||
|
t->tv_usec < -1 || t->tv_usec > 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
207
libtirpc-1.3.1/src/clnt_fd_locks.h
Normal file
207
libtirpc-1.3.1/src/clnt_fd_locks.h
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* debug.h -- debugging routines for libtirpc
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CLNT_FD_LOCKS_H
|
||||||
|
#define _CLNT_FD_LOCKS_H
|
||||||
|
|
||||||
|
#include <sys/queue.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <rpc/xdr.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This utility manages a list of per-fd locks for the clients.
|
||||||
|
*
|
||||||
|
* If MAX_FDLOCKS_PREALLOC is defined, a number of pre-fd locks will be
|
||||||
|
* pre-allocated. This number is the minimum of MAX_FDLOCKS_PREALLOC or
|
||||||
|
* the process soft limit of allowed fds.
|
||||||
|
*/
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
static unsigned int fd_locks_prealloc = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* per-fd lock */
|
||||||
|
struct fd_lock_t {
|
||||||
|
bool_t active;
|
||||||
|
cond_t cv;
|
||||||
|
};
|
||||||
|
typedef struct fd_lock_t fd_lock_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* internal type to store per-fd locks in a list */
|
||||||
|
struct fd_lock_item_t {
|
||||||
|
/* fd_lock_t first so we can cast to fd_lock_item_t */
|
||||||
|
fd_lock_t fd_lock;
|
||||||
|
int fd;
|
||||||
|
unsigned int refs;
|
||||||
|
TAILQ_ENTRY(fd_lock_item_t) link;
|
||||||
|
};
|
||||||
|
typedef struct fd_lock_item_t fd_lock_item_t;
|
||||||
|
#define to_fd_lock_item(fdlock_t_ptr) ((fd_lock_item_t*) fdlock_t_ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/* internal list of per-fd locks */
|
||||||
|
typedef TAILQ_HEAD(,fd_lock_item_t) fd_lock_list_t;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
|
||||||
|
/* With pre-allocation, keep track of both an array and a list */
|
||||||
|
struct fd_locks_t {
|
||||||
|
fd_lock_list_t fd_lock_list;
|
||||||
|
fd_lock_t *fd_lock_array;
|
||||||
|
};
|
||||||
|
typedef struct fd_locks_t fd_locks_t;
|
||||||
|
#define to_fd_lock_list(fd_locks_t_ptr) (&fd_locks_t_ptr->fd_lock_list)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* With no pre-allocation, just keep track of a list */
|
||||||
|
typedef fd_lock_list_t fd_locks_t;
|
||||||
|
#define to_fd_lock_list(fd_locks_t_ptr) ((fd_lock_list_t *) fd_locks_t_ptr)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* allocate fd locks */
|
||||||
|
static inline
|
||||||
|
fd_locks_t* fd_locks_init() {
|
||||||
|
fd_locks_t *fd_locks;
|
||||||
|
|
||||||
|
fd_locks = (fd_locks_t *) mem_alloc(sizeof(fd_locks_t));
|
||||||
|
if (fd_locks == (fd_locks_t *) NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
TAILQ_INIT(to_fd_lock_list(fd_locks));
|
||||||
|
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
size_t fd_lock_arraysz;
|
||||||
|
|
||||||
|
if (fd_locks_prealloc == 0) {
|
||||||
|
unsigned int dtbsize = __rpc_dtbsize();
|
||||||
|
if (0 < dtbsize && dtbsize < MAX_FDLOCKS_PREALLOC)
|
||||||
|
fd_locks_prealloc = dtbsize;
|
||||||
|
else
|
||||||
|
fd_locks_prealloc = MAX_FDLOCKS_PREALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (size_t) fd_locks_prealloc > SIZE_MAX/sizeof(fd_lock_t)) {
|
||||||
|
mem_free(fd_locks, sizeof (*fd_locks));
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_lock_arraysz = fd_locks_prealloc * sizeof (fd_lock_t);
|
||||||
|
fd_locks->fd_lock_array = (fd_lock_t *) mem_alloc(fd_lock_arraysz);
|
||||||
|
if (fd_locks->fd_lock_array == (fd_lock_t *) NULL) {
|
||||||
|
mem_free(fd_locks, sizeof (*fd_locks));
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < fd_locks_prealloc; i++) {
|
||||||
|
fd_locks->fd_lock_array[i].active = FALSE;
|
||||||
|
cond_init(&fd_locks->fd_lock_array[i].cv, 0, (void *) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fd_locks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* de-allocate fd locks */
|
||||||
|
static inline
|
||||||
|
void fd_locks_destroy(fd_locks_t *fd_locks) {
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
fd_lock_t *array = fd_locks->fd_lock_array;
|
||||||
|
mem_free(array, fd_locks_prealloc * sizeof (fd_lock_t));
|
||||||
|
#endif
|
||||||
|
fd_lock_item_t *item;
|
||||||
|
fd_lock_list_t *list = to_fd_lock_list(fd_locks);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(item, list, link) {
|
||||||
|
cond_destroy(&item->fd_lock.cv);
|
||||||
|
mem_free(item, sizeof (*item));
|
||||||
|
}
|
||||||
|
mem_free(fd_locks, sizeof (*fd_locks));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate per-fd lock */
|
||||||
|
static inline
|
||||||
|
fd_lock_t* fd_lock_create(int fd, fd_locks_t *fd_locks) {
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
if (fd < fd_locks_prealloc) {
|
||||||
|
return &fd_locks->fd_lock_array[fd];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
fd_lock_item_t *item;
|
||||||
|
fd_lock_list_t *list = to_fd_lock_list(fd_locks);
|
||||||
|
|
||||||
|
for (item = TAILQ_FIRST(list);
|
||||||
|
item != (fd_lock_item_t *) NULL && item->fd != fd;
|
||||||
|
item = TAILQ_NEXT(item, link));
|
||||||
|
|
||||||
|
if (item == (fd_lock_item_t *) NULL) {
|
||||||
|
item = (fd_lock_item_t *) mem_alloc(sizeof(fd_lock_item_t));
|
||||||
|
if (item == (fd_lock_item_t *) NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
item->fd = fd;
|
||||||
|
item->refs = 1;
|
||||||
|
item->fd_lock.active = FALSE;
|
||||||
|
cond_init(&item->fd_lock.cv, 0, (void *) 0);
|
||||||
|
TAILQ_INSERT_HEAD(list, item, link);
|
||||||
|
} else {
|
||||||
|
item->refs++;
|
||||||
|
}
|
||||||
|
return &item->fd_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* de-allocate per-fd lock */
|
||||||
|
static inline
|
||||||
|
void fd_lock_destroy(int fd, fd_lock_t *fd_lock, fd_locks_t *fd_locks) {
|
||||||
|
#ifdef MAX_FDLOCKS_PREALLOC
|
||||||
|
if (fd < fd_locks_prealloc)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
fd_lock_item_t* item = to_fd_lock_item(fd_lock);
|
||||||
|
item->refs--;
|
||||||
|
if (item->refs <= 0) {
|
||||||
|
TAILQ_REMOVE(to_fd_lock_list(fd_locks), item, link);
|
||||||
|
cond_destroy(&item->fd_lock.cv);
|
||||||
|
mem_free(item, sizeof (*item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _CLNT_FD_LOCKS_H */
|
||||||
434
libtirpc-1.3.1/src/clnt_generic.c
Normal file
434
libtirpc-1.3.1/src/clnt_generic.c
Normal file
@ -0,0 +1,434 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Oracle America, 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 the "Oracle America, 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 <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/nettype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
|
||||||
|
extern bool_t __rpc_is_local_host(const char *);
|
||||||
|
int __rpc_raise_fd(int);
|
||||||
|
|
||||||
|
#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, rpcprog_t prog, rpcvers_t *vers_out,
|
||||||
|
rpcvers_t vers_low, 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, rpcprog_t prog,
|
||||||
|
rpcvers_t *vers_out, rpcvers_t vers_low, rpcvers_t vers_high,
|
||||||
|
const char *nettype, const struct timeval *tp)
|
||||||
|
{
|
||||||
|
CLIENT *clnt;
|
||||||
|
struct timeval to;
|
||||||
|
enum clnt_stat rpc_stat;
|
||||||
|
struct rpc_err rpcerr;
|
||||||
|
|
||||||
|
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, rpcprog_t prog, 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, rpcprog_t prog, 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, rpcprog_t prog, 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, rpcprog_t prog, 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);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(int fd, const struct netconfig *nconf,
|
||||||
|
struct netbuf *svcaddr, rpcprog_t prog, rpcvers_t vers,
|
||||||
|
uint sendsz, uint recvsz)
|
||||||
|
{
|
||||||
|
CLIENT *cl; /* client handle */
|
||||||
|
bool_t madefd = FALSE; /* whether fd opened here */
|
||||||
|
long servtype;
|
||||||
|
int one = 1;
|
||||||
|
struct __rpc_sockinfo si;
|
||||||
|
extern int __rpc_minfd;
|
||||||
|
|
||||||
|
if (fd == RPC_ANYFD) {
|
||||||
|
if (nconf == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = __rpc_nconf2fd(nconf);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
goto err;
|
||||||
|
if (fd < __rpc_minfd)
|
||||||
|
fd = __rpc_raise_fd(fd);
|
||||||
|
madefd = TRUE;
|
||||||
|
servtype = nconf->nc_semantics;
|
||||||
|
if (!__rpc_fd2sockinfo(fd, &si))
|
||||||
|
goto err;
|
||||||
|
bindresvport(fd, NULL);
|
||||||
|
} 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);
|
||||||
|
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, &one,
|
||||||
|
sizeof (one));
|
||||||
|
}
|
||||||
|
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
|
||||||
|
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)close(fd);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
close(nfd);
|
||||||
|
return (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close(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);
|
||||||
|
}
|
||||||
335
libtirpc-1.3.1/src/clnt_perror.c
Normal file
335
libtirpc-1.3.1/src/clnt_perror.c
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_perror.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
|
||||||
|
static char *buf;
|
||||||
|
|
||||||
|
static char *_buf(void);
|
||||||
|
static char *auth_errmsg(enum auth_stat);
|
||||||
|
#define CLNT_PERROR_BUFLEN 256
|
||||||
|
|
||||||
|
static char *
|
||||||
|
_buf()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (buf == 0)
|
||||||
|
buf = (char *)malloc(CLNT_PERROR_BUFLEN);
|
||||||
|
return (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print reply error info
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
clnt_sperror(rpch, s)
|
||||||
|
CLIENT *rpch;
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
struct rpc_err e;
|
||||||
|
char *err;
|
||||||
|
char *str;
|
||||||
|
char *strstart;
|
||||||
|
size_t len, i;
|
||||||
|
|
||||||
|
if (rpch == NULL || s == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
|
||||||
|
if (str == 0)
|
||||||
|
return (0);
|
||||||
|
len = CLNT_PERROR_BUFLEN;
|
||||||
|
strstart = str;
|
||||||
|
CLNT_GETERR(rpch, &e);
|
||||||
|
|
||||||
|
if (snprintf(str, len, "%s: ", s) > 0) {
|
||||||
|
i = strlen(str);
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
|
||||||
|
i = strlen(str);
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
|
||||||
|
switch (e.re_status) {
|
||||||
|
case RPC_SUCCESS:
|
||||||
|
case RPC_CANTENCODEARGS:
|
||||||
|
case RPC_CANTDECODERES:
|
||||||
|
case RPC_TIMEDOUT:
|
||||||
|
case RPC_PROGUNAVAIL:
|
||||||
|
case RPC_PROCUNAVAIL:
|
||||||
|
case RPC_CANTDECODEARGS:
|
||||||
|
case RPC_SYSTEMERROR:
|
||||||
|
case RPC_UNKNOWNHOST:
|
||||||
|
case RPC_UNKNOWNPROTO:
|
||||||
|
case RPC_PMAPFAILURE:
|
||||||
|
case RPC_PROGNOTREGISTERED:
|
||||||
|
case RPC_FAILED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_CANTSEND:
|
||||||
|
case RPC_CANTRECV:
|
||||||
|
snprintf(str, len, "; errno = %s", strerror(e.re_errno));
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_VERSMISMATCH:
|
||||||
|
snprintf(str, len, "; low version = %u, high version = %u",
|
||||||
|
e.re_vers.low, e.re_vers.high);
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_AUTHERROR:
|
||||||
|
err = auth_errmsg(e.re_why);
|
||||||
|
snprintf(str, len, "; why = ");
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
if (err != NULL) {
|
||||||
|
snprintf(str, len, "%s",err);
|
||||||
|
} else {
|
||||||
|
snprintf(str, len,
|
||||||
|
"(unknown authentication error - %d)",
|
||||||
|
(int) e.re_why);
|
||||||
|
}
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_PROGVERSMISMATCH:
|
||||||
|
snprintf(str, len, "; low version = %u, high version = %u",
|
||||||
|
e.re_vers.low, e.re_vers.high);
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* unknown */
|
||||||
|
snprintf(str, len, "; s1 = %u, s2 = %u",
|
||||||
|
e.re_lb.s1, e.re_lb.s2);
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0) {
|
||||||
|
str += i;
|
||||||
|
len -= i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strstart[CLNT_PERROR_BUFLEN-1] = '\0';
|
||||||
|
return(strstart) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clnt_perror(rpch, s)
|
||||||
|
CLIENT *rpch;
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (rpch == NULL || s == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *const rpc_errlist[] = {
|
||||||
|
"RPC: Success", /* 0 - RPC_SUCCESS */
|
||||||
|
"RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */
|
||||||
|
"RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */
|
||||||
|
"RPC: Unable to send", /* 3 - RPC_CANTSEND */
|
||||||
|
"RPC: Unable to receive", /* 4 - RPC_CANTRECV */
|
||||||
|
"RPC: Timed out", /* 5 - RPC_TIMEDOUT */
|
||||||
|
"RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */
|
||||||
|
"RPC: Authentication error", /* 7 - RPC_AUTHERROR */
|
||||||
|
"RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */
|
||||||
|
"RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */
|
||||||
|
"RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */
|
||||||
|
"RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */
|
||||||
|
"RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */
|
||||||
|
"RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */
|
||||||
|
"RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */
|
||||||
|
"RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */
|
||||||
|
"RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */
|
||||||
|
"RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This interface for use by clntrpc
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
clnt_sperrno(stat)
|
||||||
|
enum clnt_stat stat;
|
||||||
|
{
|
||||||
|
unsigned int errnum = stat;
|
||||||
|
|
||||||
|
if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
|
||||||
|
/* LINTED interface problem */
|
||||||
|
return (char *)rpc_errlist[errnum];
|
||||||
|
|
||||||
|
return ("RPC: (unknown error code)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clnt_perrno(num)
|
||||||
|
enum clnt_stat num;
|
||||||
|
{
|
||||||
|
(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
clnt_spcreateerror(s)
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
char *str, *err;
|
||||||
|
size_t len, i;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
|
||||||
|
if (str == 0)
|
||||||
|
return(0);
|
||||||
|
len = CLNT_PERROR_BUFLEN;
|
||||||
|
snprintf(str, len, "%s: ", s);
|
||||||
|
i = strlen(str);
|
||||||
|
if (i > 0)
|
||||||
|
len -= i;
|
||||||
|
(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
|
||||||
|
switch (rpc_createerr.cf_stat) {
|
||||||
|
case RPC_PMAPFAILURE:
|
||||||
|
(void) strncat(str, " - ", len - 1);
|
||||||
|
err = clnt_sperrno(rpc_createerr.cf_error.re_status);
|
||||||
|
if (err)
|
||||||
|
(void) strncat(str, err+5, len-5);
|
||||||
|
switch(rpc_createerr.cf_error.re_status) {
|
||||||
|
case RPC_CANTSEND:
|
||||||
|
case RPC_CANTRECV:
|
||||||
|
i = strlen(str);
|
||||||
|
len -= i;
|
||||||
|
snprintf(str+i, len, ": errno %d (%s)",
|
||||||
|
rpc_createerr.cf_error.re_errno,
|
||||||
|
strerror(rpc_createerr.cf_error.re_errno));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_SYSTEMERROR:
|
||||||
|
(void)strncat(str, " - ", len - 1);
|
||||||
|
(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
|
||||||
|
len - 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RPC_CANTSEND:
|
||||||
|
case RPC_CANTDECODERES:
|
||||||
|
case RPC_CANTENCODEARGS:
|
||||||
|
case RPC_SUCCESS:
|
||||||
|
case RPC_UNKNOWNPROTO:
|
||||||
|
case RPC_PROGNOTREGISTERED:
|
||||||
|
case RPC_FAILED:
|
||||||
|
case RPC_UNKNOWNHOST:
|
||||||
|
case RPC_CANTDECODEARGS:
|
||||||
|
case RPC_PROCUNAVAIL:
|
||||||
|
case RPC_PROGVERSMISMATCH:
|
||||||
|
case RPC_PROGUNAVAIL:
|
||||||
|
case RPC_AUTHERROR:
|
||||||
|
case RPC_VERSMISMATCH:
|
||||||
|
case RPC_TIMEDOUT:
|
||||||
|
case RPC_CANTRECV:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str[CLNT_PERROR_BUFLEN-1] = '\0';
|
||||||
|
return (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clnt_pcreateerror(s)
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *const auth_errlist[] = {
|
||||||
|
"Authentication OK", /* 0 - AUTH_OK */
|
||||||
|
"Invalid client credential", /* 1 - AUTH_BADCRED */
|
||||||
|
"Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
|
||||||
|
"Invalid client verifier", /* 3 - AUTH_BADVERF */
|
||||||
|
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
|
||||||
|
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
|
||||||
|
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
|
||||||
|
"Failed (unspecified error)" /* 7 - AUTH_FAILED */
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *
|
||||||
|
auth_errmsg(stat)
|
||||||
|
enum auth_stat stat;
|
||||||
|
{
|
||||||
|
unsigned int errnum = stat;
|
||||||
|
|
||||||
|
if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
|
||||||
|
/* LINTED interface problem */
|
||||||
|
return (char *)auth_errlist[errnum];
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
305
libtirpc-1.3.1/src/clnt_raw.c
Normal file
305
libtirpc-1.3.1/src/clnt_raw.c
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_raw.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* Memory based rpc for simple testing and timing.
|
||||||
|
* Interface to create an rpc client and server in the same process.
|
||||||
|
* This lets us similate rpc and get round trip overhead, without
|
||||||
|
* any interference from the kernel.
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/raw.h>
|
||||||
|
|
||||||
|
extern mutex_t clntraw_lock;
|
||||||
|
|
||||||
|
#define MCALL_MSG_SIZE 24
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the "network" we will be moving stuff over.
|
||||||
|
*/
|
||||||
|
static struct clntraw_private {
|
||||||
|
CLIENT client_object;
|
||||||
|
XDR xdr_stream;
|
||||||
|
char *_raw_buf;
|
||||||
|
union {
|
||||||
|
struct rpc_msg mashl_rpcmsg;
|
||||||
|
char mashl_callmsg[MCALL_MSG_SIZE];
|
||||||
|
} u;
|
||||||
|
u_int mcnt;
|
||||||
|
} *clntraw_private;
|
||||||
|
|
||||||
|
static enum clnt_stat clnt_raw_call(CLIENT *, rpcproc_t, xdrproc_t, void *,
|
||||||
|
xdrproc_t, void *, struct timeval);
|
||||||
|
static void clnt_raw_geterr(CLIENT *, struct rpc_err *);
|
||||||
|
static bool_t clnt_raw_freeres(CLIENT *, xdrproc_t, void *);
|
||||||
|
static void clnt_raw_abort(CLIENT *);
|
||||||
|
static bool_t clnt_raw_control(CLIENT *, u_int, void *);
|
||||||
|
static void clnt_raw_destroy(CLIENT *);
|
||||||
|
static struct clnt_ops *clnt_raw_ops(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a client handle for memory based rpc.
|
||||||
|
*/
|
||||||
|
CLIENT *
|
||||||
|
clnt_raw_create(prog, vers)
|
||||||
|
rpcprog_t prog;
|
||||||
|
rpcvers_t vers;
|
||||||
|
{
|
||||||
|
struct clntraw_private *clp;
|
||||||
|
struct rpc_msg call_msg;
|
||||||
|
XDR *xdrs;
|
||||||
|
CLIENT *client;
|
||||||
|
|
||||||
|
mutex_lock(&clntraw_lock);
|
||||||
|
clp = clntraw_private;
|
||||||
|
if (clp == NULL) {
|
||||||
|
clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
|
||||||
|
if (clp == NULL) {
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (__rpc_rawcombuf == NULL)
|
||||||
|
__rpc_rawcombuf =
|
||||||
|
(char *)calloc(UDPMSGSIZE, sizeof (char));
|
||||||
|
clp->_raw_buf = __rpc_rawcombuf;
|
||||||
|
clntraw_private = clp;
|
||||||
|
}
|
||||||
|
xdrs = &clp->xdr_stream;
|
||||||
|
client = &clp->client_object;
|
||||||
|
/*
|
||||||
|
* pre-serialize the static part of the call msg and stash it away
|
||||||
|
*/
|
||||||
|
call_msg.rm_direction = CALL;
|
||||||
|
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||||
|
/* XXX: prog and vers have been long historically :-( */
|
||||||
|
call_msg.rm_call.cb_prog = (u_int32_t)prog;
|
||||||
|
call_msg.rm_call.cb_vers = (u_int32_t)vers;
|
||||||
|
xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
|
||||||
|
if (! xdr_callhdr(xdrs, &call_msg))
|
||||||
|
warnx("clntraw_create - Fatal header serialization error.");
|
||||||
|
clp->mcnt = XDR_GETPOS(xdrs);
|
||||||
|
XDR_DESTROY(xdrs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set xdrmem for client/server shared buffer
|
||||||
|
*/
|
||||||
|
xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create client handle
|
||||||
|
*/
|
||||||
|
client->cl_ops = clnt_raw_ops();
|
||||||
|
client->cl_auth = authnone_create();
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
return (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static enum clnt_stat
|
||||||
|
clnt_raw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||||
|
CLIENT *h;
|
||||||
|
rpcproc_t proc;
|
||||||
|
xdrproc_t xargs;
|
||||||
|
void *argsp;
|
||||||
|
xdrproc_t xresults;
|
||||||
|
void *resultsp;
|
||||||
|
struct timeval timeout;
|
||||||
|
{
|
||||||
|
struct clntraw_private *clp = clntraw_private;
|
||||||
|
XDR *xdrs = &clp->xdr_stream;
|
||||||
|
struct rpc_msg msg;
|
||||||
|
enum clnt_stat status;
|
||||||
|
struct rpc_err error;
|
||||||
|
|
||||||
|
assert(h != NULL);
|
||||||
|
|
||||||
|
mutex_lock(&clntraw_lock);
|
||||||
|
if (clp == NULL) {
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
return (RPC_FAILED);
|
||||||
|
}
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
|
||||||
|
call_again:
|
||||||
|
/*
|
||||||
|
* send request
|
||||||
|
*/
|
||||||
|
xdrs->x_op = XDR_ENCODE;
|
||||||
|
XDR_SETPOS(xdrs, 0);
|
||||||
|
clp->u.mashl_rpcmsg.rm_xid ++ ;
|
||||||
|
if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
|
||||||
|
(! XDR_PUTINT32(xdrs, (int32_t *)&proc)) ||
|
||||||
|
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
|
||||||
|
(! (*xargs)(xdrs, argsp))) {
|
||||||
|
return (RPC_CANTENCODEARGS);
|
||||||
|
}
|
||||||
|
(void)XDR_GETPOS(xdrs); /* called just to cause overhead */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to call server input routine here because this is
|
||||||
|
* all going on in one process. Yuk.
|
||||||
|
*/
|
||||||
|
svc_getreq_common(FD_SETSIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get results
|
||||||
|
*/
|
||||||
|
xdrs->x_op = XDR_DECODE;
|
||||||
|
XDR_SETPOS(xdrs, 0);
|
||||||
|
msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
msg.acpted_rply.ar_results.where = resultsp;
|
||||||
|
msg.acpted_rply.ar_results.proc = xresults;
|
||||||
|
if (! xdr_replymsg(xdrs, &msg)) {
|
||||||
|
/*
|
||||||
|
* It's possible for xdr_replymsg() to fail partway
|
||||||
|
* through its attempt to decode the result from the
|
||||||
|
* server. If this happens, it will leave the reply
|
||||||
|
* structure partially populated with dynamically
|
||||||
|
* allocated memory. (This can happen if someone uses
|
||||||
|
* clntudp_bufcreate() to create a CLIENT handle and
|
||||||
|
* specifies a receive buffer size that is too small.)
|
||||||
|
* This memory must be free()ed to avoid a leak.
|
||||||
|
*/
|
||||||
|
int op = xdrs->x_op;
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
xdr_replymsg(xdrs, &msg);
|
||||||
|
xdrs->x_op = op;
|
||||||
|
return (RPC_CANTDECODERES);
|
||||||
|
}
|
||||||
|
_seterr_reply(&msg, &error);
|
||||||
|
status = error.re_status;
|
||||||
|
|
||||||
|
if (status == RPC_SUCCESS) {
|
||||||
|
if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
|
||||||
|
status = RPC_AUTHERROR;
|
||||||
|
}
|
||||||
|
} /* end successful completion */
|
||||||
|
else {
|
||||||
|
if (AUTH_REFRESH(h->cl_auth, &msg))
|
||||||
|
goto call_again;
|
||||||
|
} /* end of unsuccessful completion */
|
||||||
|
|
||||||
|
if (status == RPC_SUCCESS) {
|
||||||
|
if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
|
||||||
|
status = RPC_AUTHERROR;
|
||||||
|
}
|
||||||
|
if (msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
clnt_raw_geterr(cl, err)
|
||||||
|
CLIENT *cl;
|
||||||
|
struct rpc_err *err;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static bool_t
|
||||||
|
clnt_raw_freeres(cl, xdr_res, res_ptr)
|
||||||
|
CLIENT *cl;
|
||||||
|
xdrproc_t xdr_res;
|
||||||
|
void *res_ptr;
|
||||||
|
{
|
||||||
|
struct clntraw_private *clp = clntraw_private;
|
||||||
|
XDR *xdrs = &clp->xdr_stream;
|
||||||
|
bool_t rval;
|
||||||
|
|
||||||
|
mutex_lock(&clntraw_lock);
|
||||||
|
if (clp == NULL) {
|
||||||
|
rval = (bool_t) RPC_FAILED;
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
return (rval);
|
||||||
|
}
|
||||||
|
mutex_unlock(&clntraw_lock);
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
return ((*xdr_res)(xdrs, res_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
clnt_raw_abort(cl)
|
||||||
|
CLIENT *cl;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static bool_t
|
||||||
|
clnt_raw_control(cl, ui, str)
|
||||||
|
CLIENT *cl;
|
||||||
|
u_int ui;
|
||||||
|
void *str;
|
||||||
|
{
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
clnt_raw_destroy(cl)
|
||||||
|
CLIENT *cl;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clnt_ops *
|
||||||
|
clnt_raw_ops()
|
||||||
|
{
|
||||||
|
static struct clnt_ops ops;
|
||||||
|
extern mutex_t ops_lock;
|
||||||
|
|
||||||
|
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||||
|
|
||||||
|
mutex_lock(&ops_lock);
|
||||||
|
if (ops.cl_call == NULL) {
|
||||||
|
ops.cl_call = clnt_raw_call;
|
||||||
|
ops.cl_abort = clnt_raw_abort;
|
||||||
|
ops.cl_geterr = clnt_raw_geterr;
|
||||||
|
ops.cl_freeres = clnt_raw_freeres;
|
||||||
|
ops.cl_destroy = clnt_raw_destroy;
|
||||||
|
ops.cl_control = clnt_raw_control;
|
||||||
|
}
|
||||||
|
mutex_unlock(&ops_lock);
|
||||||
|
return (&ops);
|
||||||
|
}
|
||||||
178
libtirpc-1.3.1/src/clnt_simple.c
Normal file
178
libtirpc-1.3.1/src/clnt_simple.c
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* 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-1991 by Sun Microsystems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_simple.c
|
||||||
|
* Simplified front end to client rpc.
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <rpc/clnt.h>
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NETIDLEN
|
||||||
|
#define NETIDLEN 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct rpc_call_private {
|
||||||
|
int valid; /* Is this entry valid ? */
|
||||||
|
CLIENT *client; /* Client handle */
|
||||||
|
pid_t pid; /* process-id at moment of creation */
|
||||||
|
rpcprog_t prognum; /* Program */
|
||||||
|
rpcvers_t versnum; /* Version */
|
||||||
|
char host[MAXHOSTNAMELEN]; /* Servers host */
|
||||||
|
char nettype[NETIDLEN]; /* Network type */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rpc_call_destroy(void *);
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_call_destroy(void *vp)
|
||||||
|
{
|
||||||
|
struct rpc_call_private *rcp = (struct rpc_call_private *)vp;
|
||||||
|
|
||||||
|
if (rcp) {
|
||||||
|
if (rcp->client)
|
||||||
|
CLNT_DESTROY(rcp->client);
|
||||||
|
free(rcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the simplified interface to the client rpc layer.
|
||||||
|
* The client handle is not destroyed here and is reused for
|
||||||
|
* the future calls to same prog, vers, host and nettype combination.
|
||||||
|
*
|
||||||
|
* The total time available is 25 seconds.
|
||||||
|
*/
|
||||||
|
enum clnt_stat
|
||||||
|
rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
|
||||||
|
const char *host; /* host name */
|
||||||
|
rpcprog_t prognum; /* program number */
|
||||||
|
rpcvers_t versnum; /* version number */
|
||||||
|
rpcproc_t procnum; /* procedure number */
|
||||||
|
xdrproc_t inproc, outproc; /* in/out XDR procedures */
|
||||||
|
const char *in;
|
||||||
|
char *out; /* recv/send data */
|
||||||
|
const char *nettype; /* nettype */
|
||||||
|
{
|
||||||
|
struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
|
||||||
|
enum clnt_stat clnt_stat;
|
||||||
|
struct timeval timeout, tottimeout;
|
||||||
|
extern thread_key_t rpc_call_key;
|
||||||
|
extern mutex_t tsd_lock;
|
||||||
|
|
||||||
|
if (rpc_call_key == KEY_INITIALIZER) {
|
||||||
|
mutex_lock(&tsd_lock);
|
||||||
|
if (rpc_call_key == KEY_INITIALIZER)
|
||||||
|
thr_keycreate(&rpc_call_key, rpc_call_destroy);
|
||||||
|
mutex_unlock(&tsd_lock);
|
||||||
|
}
|
||||||
|
rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
|
||||||
|
if (rcp == NULL) {
|
||||||
|
rcp = malloc(sizeof (*rcp));
|
||||||
|
if (rcp == NULL) {
|
||||||
|
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||||
|
rpc_createerr.cf_error.re_errno = errno;
|
||||||
|
return (rpc_createerr.cf_stat);
|
||||||
|
}
|
||||||
|
thr_setspecific(rpc_call_key, (void *) rcp);
|
||||||
|
rcp->valid = 0;
|
||||||
|
rcp->client = NULL;
|
||||||
|
}
|
||||||
|
if ((nettype == NULL) || (nettype[0] == 0))
|
||||||
|
nettype = "netpath";
|
||||||
|
if (!(rcp->valid && rcp->pid == getpid() &&
|
||||||
|
(rcp->prognum == prognum) &&
|
||||||
|
(rcp->versnum == versnum) &&
|
||||||
|
(!strcmp(rcp->host, host)) &&
|
||||||
|
(!strcmp(rcp->nettype, nettype)))) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
rcp->valid = 0;
|
||||||
|
if (rcp->client)
|
||||||
|
CLNT_DESTROY(rcp->client);
|
||||||
|
/*
|
||||||
|
* Using the first successful transport for that type
|
||||||
|
*/
|
||||||
|
rcp->client = clnt_create(host, prognum, versnum, nettype);
|
||||||
|
rcp->pid = getpid();
|
||||||
|
if (rcp->client == NULL) {
|
||||||
|
return (rpc_createerr.cf_stat);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Set time outs for connectionless case. Do it
|
||||||
|
* unconditionally. Faster than doing a t_getinfo()
|
||||||
|
* and then doing the right thing.
|
||||||
|
*/
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
timeout.tv_sec = 5;
|
||||||
|
(void) CLNT_CONTROL(rcp->client,
|
||||||
|
CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout);
|
||||||
|
if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd))
|
||||||
|
fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
|
||||||
|
rcp->prognum = prognum;
|
||||||
|
rcp->versnum = versnum;
|
||||||
|
if ((strlen(host) < (size_t)MAXHOSTNAMELEN) &&
|
||||||
|
(strlen(nettype) < (size_t)NETIDLEN)) {
|
||||||
|
(void) strcpy(rcp->host, host);
|
||||||
|
(void) strcpy(rcp->nettype, nettype);
|
||||||
|
rcp->valid = 1;
|
||||||
|
} else {
|
||||||
|
rcp->valid = 0;
|
||||||
|
}
|
||||||
|
} /* else reuse old client */
|
||||||
|
tottimeout.tv_sec = 25;
|
||||||
|
tottimeout.tv_usec = 0;
|
||||||
|
|
||||||
|
/* LINTED const castaway */
|
||||||
|
clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in,
|
||||||
|
outproc, out, tottimeout);
|
||||||
|
/*
|
||||||
|
* if call failed, empty cache
|
||||||
|
*/
|
||||||
|
if (clnt_stat != RPC_SUCCESS)
|
||||||
|
rcp->valid = 0;
|
||||||
|
return (clnt_stat);
|
||||||
|
}
|
||||||
777
libtirpc-1.3.1/src/clnt_vc.c
Normal file
777
libtirpc-1.3.1/src/clnt_vc.c
Normal file
@ -0,0 +1,777 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||||
|
*
|
||||||
|
* TCP based RPC supports 'batched calls'.
|
||||||
|
* A sequence of calls may be batched-up in a send buffer. The rpc call
|
||||||
|
* return immediately to the client even though the call was not necessarily
|
||||||
|
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
|
||||||
|
* the rpc timeout value is zero (see clnt.h, rpc).
|
||||||
|
*
|
||||||
|
* Clients should NOT casually batch calls that in fact return results; that is,
|
||||||
|
* the server side should be aware that a call is batched and not produce any
|
||||||
|
* return message. Batched calls that produce many result messages can
|
||||||
|
* deadlock (netlock) the client and the server....
|
||||||
|
*
|
||||||
|
* Now go hang yourself.
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <sys/syslog.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
#include "clnt_fd_locks.h"
|
||||||
|
|
||||||
|
#define MCALL_MSG_SIZE 24
|
||||||
|
|
||||||
|
#define CMGROUP_MAX 16
|
||||||
|
#define SCM_CREDS 0x03 /* process creds (struct cmsgcred) */
|
||||||
|
|
||||||
|
#undef rpc_createerr /* make it clear it is a thread safe variable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Credentials structure, used to verify the identity of a peer
|
||||||
|
* process that has sent us a message. This is allocated by the
|
||||||
|
* peer process but filled in by the kernel. This prevents the
|
||||||
|
* peer from lying about its identity. (Note that cmcred_groups[0]
|
||||||
|
* is the effective GID.)
|
||||||
|
*/
|
||||||
|
struct cmsgcred {
|
||||||
|
pid_t cmcred_pid; /* PID of sending process */
|
||||||
|
uid_t cmcred_uid; /* real UID of sending process */
|
||||||
|
uid_t cmcred_euid; /* effective UID of sending process */
|
||||||
|
gid_t cmcred_gid; /* real GID of sending process */
|
||||||
|
short cmcred_ngroups; /* number or groups */
|
||||||
|
gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cmessage {
|
||||||
|
struct cmsghdr cmsg;
|
||||||
|
struct cmsgcred cmcred;
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum clnt_stat clnt_vc_call(CLIENT *, rpcproc_t, xdrproc_t, void *,
|
||||||
|
xdrproc_t, void *, struct timeval);
|
||||||
|
static void clnt_vc_geterr(CLIENT *, struct rpc_err *);
|
||||||
|
static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *);
|
||||||
|
static void clnt_vc_abort(CLIENT *);
|
||||||
|
static bool_t clnt_vc_control(CLIENT *, u_int, void *);
|
||||||
|
static void clnt_vc_destroy(CLIENT *);
|
||||||
|
static struct clnt_ops *clnt_vc_ops(void);
|
||||||
|
static bool_t time_not_ok(struct timeval *);
|
||||||
|
static int read_vc(void *, void *, int);
|
||||||
|
static int write_vc(void *, void *, int);
|
||||||
|
|
||||||
|
struct ct_data {
|
||||||
|
int ct_fd; /* connection's fd */
|
||||||
|
fd_lock_t *ct_fd_lock;
|
||||||
|
bool_t ct_closeit; /* close it on destroy */
|
||||||
|
struct timeval ct_wait; /* wait interval in milliseconds */
|
||||||
|
bool_t ct_waitset; /* wait set by clnt_control? */
|
||||||
|
struct netbuf ct_addr; /* remote addr */
|
||||||
|
struct rpc_err ct_error;
|
||||||
|
union {
|
||||||
|
char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
|
||||||
|
u_int32_t ct_mcalli;
|
||||||
|
} ct_u;
|
||||||
|
u_int ct_mpos; /* pos after marshal */
|
||||||
|
XDR ct_xdrs; /* XDR stream */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This machinery implements per-fd locks for MT-safety. It is not
|
||||||
|
* sufficient to do per-CLIENT handle locks for MT-safety because a
|
||||||
|
* user may create more than one CLIENT handle with the same fd behind
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* We keep track of a list of per-fd locks, protected by the clnt_fd_lock
|
||||||
|
* mutex. Each per-fd lock consists of a predicate indicating whether is
|
||||||
|
* active or not: fd_lock->active == TRUE => a call is active on some
|
||||||
|
* CLIENT handle created for that fd. Each fd predicate is guarded by a
|
||||||
|
* condition variable so that the global mutex can be unlocked while
|
||||||
|
* waiting for the predicate to change.
|
||||||
|
*
|
||||||
|
* The current implementation holds locks across the entire RPC and reply,
|
||||||
|
* including retransmissions. Yes, this is silly, and as soon as this
|
||||||
|
* code is proven to work, this should be the first thing fixed. One step
|
||||||
|
* at a time.
|
||||||
|
*/
|
||||||
|
static fd_locks_t *vc_fd_locks;
|
||||||
|
extern pthread_mutex_t disrupt_lock;
|
||||||
|
extern mutex_t clnt_fd_lock;
|
||||||
|
#define release_fd_lock(fd_lock, mask) { \
|
||||||
|
mutex_lock(&clnt_fd_lock); \
|
||||||
|
fd_lock->active = FALSE; \
|
||||||
|
mutex_unlock(&clnt_fd_lock); \
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
|
||||||
|
cond_signal(&fd_lock->cv); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char clnt_vc_errstr[] = "%s : %s";
|
||||||
|
static const char clnt_vc_str[] = "clnt_vc_create";
|
||||||
|
static const char __no_mem_str[] = "out of memory";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a client handle for a connection.
|
||||||
|
* Default options are set, which the user can change using clnt_control()'s.
|
||||||
|
* The rpc/vc package does buffering similar to stdio, so the client
|
||||||
|
* must pick send and receive buffer sizes, 0 => use the default.
|
||||||
|
* NB: fd is copied into a private area.
|
||||||
|
* NB: The rpch->cl_auth is set null authentication. Caller may wish to
|
||||||
|
* set this something more useful.
|
||||||
|
*
|
||||||
|
* fd should be an open socket
|
||||||
|
*/
|
||||||
|
CLIENT *
|
||||||
|
clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
|
||||||
|
int fd; /* open file descriptor */
|
||||||
|
const struct netbuf *raddr; /* servers address */
|
||||||
|
const rpcprog_t prog; /* program number */
|
||||||
|
const rpcvers_t vers; /* version number */
|
||||||
|
u_int sendsz; /* buffer recv size */
|
||||||
|
u_int recvsz; /* buffer send size */
|
||||||
|
{
|
||||||
|
CLIENT *cl; /* client handle */
|
||||||
|
struct ct_data *ct = NULL; /* client handle */
|
||||||
|
struct timeval now;
|
||||||
|
struct rpc_msg call_msg;
|
||||||
|
static u_int32_t disrupt;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
socklen_t slen;
|
||||||
|
struct __rpc_sockinfo si;
|
||||||
|
fd_lock_t *fd_lock;
|
||||||
|
|
||||||
|
mutex_lock(&disrupt_lock);
|
||||||
|
if (disrupt == 0)
|
||||||
|
disrupt = (u_int32_t)(long)raddr;
|
||||||
|
mutex_unlock(&disrupt_lock);
|
||||||
|
|
||||||
|
cl = (CLIENT *)mem_alloc(sizeof (*cl));
|
||||||
|
ct = (struct ct_data *)mem_alloc(sizeof (*ct));
|
||||||
|
if ((cl == (CLIENT *)NULL) || (ct == (struct ct_data *)NULL)) {
|
||||||
|
struct rpc_createerr *ce = &get_rpc_createerr();
|
||||||
|
ce->cf_stat = RPC_SYSTEMERROR;
|
||||||
|
ce->cf_error.re_errno = errno;
|
||||||
|
(void) syslog(LOG_ERR, clnt_vc_errstr,
|
||||||
|
clnt_vc_str, __no_mem_str);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ct->ct_addr.buf = NULL;
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
if (vc_fd_locks == (fd_locks_t *) NULL) {
|
||||||
|
vc_fd_locks = fd_locks_init();
|
||||||
|
if (vc_fd_locks == (fd_locks_t *) NULL) {
|
||||||
|
struct rpc_createerr *ce = &get_rpc_createerr();
|
||||||
|
ce->cf_stat = RPC_SYSTEMERROR;
|
||||||
|
ce->cf_error.re_errno = errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fd_lock = fd_lock_create(fd, vc_fd_locks);
|
||||||
|
if (fd_lock == (fd_lock_t *) NULL) {
|
||||||
|
struct rpc_createerr *ce = &get_rpc_createerr();
|
||||||
|
ce->cf_stat = RPC_SYSTEMERROR;
|
||||||
|
ce->cf_error.re_errno = errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not hold mutex during connect
|
||||||
|
*/
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
|
||||||
|
slen = sizeof ss;
|
||||||
|
if (getpeername(fd, (struct sockaddr *)&ss, &slen) < 0) {
|
||||||
|
if (errno != ENOTCONN) {
|
||||||
|
struct rpc_createerr *ce = &get_rpc_createerr();
|
||||||
|
ce->cf_stat = RPC_SYSTEMERROR;
|
||||||
|
ce->cf_error.re_errno = errno;
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (connect(fd, (struct sockaddr *)raddr->buf, raddr->len) < 0){
|
||||||
|
if (errno != EISCONN) {
|
||||||
|
struct rpc_createerr *ce = &get_rpc_createerr();
|
||||||
|
ce->cf_stat = RPC_SYSTEMERROR;
|
||||||
|
ce->cf_error.re_errno = errno;
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!__rpc_fd2sockinfo(fd, &si))
|
||||||
|
goto err;
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
|
||||||
|
ct->ct_closeit = FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up private data struct
|
||||||
|
*/
|
||||||
|
ct->ct_fd = fd;
|
||||||
|
ct->ct_fd_lock = fd_lock;
|
||||||
|
ct->ct_wait.tv_usec = 0;
|
||||||
|
ct->ct_waitset = FALSE;
|
||||||
|
ct->ct_addr.buf = malloc(raddr->maxlen);
|
||||||
|
if (ct->ct_addr.buf == NULL)
|
||||||
|
goto err;
|
||||||
|
memcpy(ct->ct_addr.buf, raddr->buf, raddr->len);
|
||||||
|
ct->ct_addr.len = raddr->len;
|
||||||
|
ct->ct_addr.maxlen = raddr->maxlen;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize call message
|
||||||
|
*/
|
||||||
|
(void)gettimeofday(&now, NULL);
|
||||||
|
mutex_lock(&disrupt_lock);
|
||||||
|
call_msg.rm_xid = ((u_int32_t)++disrupt) ^ __RPC_GETXID(&now);
|
||||||
|
mutex_unlock(&disrupt_lock);
|
||||||
|
call_msg.rm_direction = CALL;
|
||||||
|
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||||
|
call_msg.rm_call.cb_prog = (u_int32_t)prog;
|
||||||
|
call_msg.rm_call.cb_vers = (u_int32_t)vers;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pre-serialize the static part of the call msg and stash it away
|
||||||
|
*/
|
||||||
|
xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE,
|
||||||
|
XDR_ENCODE);
|
||||||
|
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
|
||||||
|
if (ct->ct_closeit) {
|
||||||
|
(void)close(fd);
|
||||||
|
}
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
|
||||||
|
XDR_DESTROY(&(ct->ct_xdrs));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a client handle which uses xdrrec for serialization
|
||||||
|
* and authnone for authentication.
|
||||||
|
*/
|
||||||
|
cl->cl_ops = clnt_vc_ops();
|
||||||
|
cl->cl_private = ct;
|
||||||
|
cl->cl_auth = authnone_create();
|
||||||
|
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
|
||||||
|
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
|
||||||
|
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
|
||||||
|
cl->cl_private, read_vc, write_vc);
|
||||||
|
return (cl);
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (cl) {
|
||||||
|
if (ct) {
|
||||||
|
if (ct->ct_addr.len)
|
||||||
|
mem_free(ct->ct_addr.buf, ct->ct_addr.len);
|
||||||
|
mem_free(ct, sizeof (struct ct_data));
|
||||||
|
}
|
||||||
|
mem_free(cl, sizeof (CLIENT));
|
||||||
|
} else if (ct) {
|
||||||
|
if (ct->ct_addr.len)
|
||||||
|
mem_free(ct->ct_addr.buf, ct->ct_addr.len);
|
||||||
|
mem_free(ct, sizeof (struct ct_data));
|
||||||
|
}
|
||||||
|
return ((CLIENT *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum clnt_stat
|
||||||
|
clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
|
||||||
|
CLIENT *cl;
|
||||||
|
rpcproc_t proc;
|
||||||
|
xdrproc_t xdr_args;
|
||||||
|
void *args_ptr;
|
||||||
|
xdrproc_t xdr_results;
|
||||||
|
void *results_ptr;
|
||||||
|
struct timeval timeout;
|
||||||
|
{
|
||||||
|
struct ct_data *ct = (struct ct_data *) cl->cl_private;
|
||||||
|
XDR *xdrs = &(ct->ct_xdrs);
|
||||||
|
struct rpc_msg reply_msg;
|
||||||
|
u_int32_t x_id;
|
||||||
|
u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */
|
||||||
|
bool_t shipnow;
|
||||||
|
int refreshes = 2;
|
||||||
|
sigset_t mask, newmask;
|
||||||
|
|
||||||
|
assert(cl != NULL);
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (ct->ct_fd_lock->active)
|
||||||
|
cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
ct->ct_fd_lock->active = TRUE;
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
if (!ct->ct_waitset) {
|
||||||
|
/* If time is not within limits, we ignore it. */
|
||||||
|
if (time_not_ok(&timeout) == FALSE)
|
||||||
|
ct->ct_wait = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
shipnow =
|
||||||
|
(xdr_results == NULL && timeout.tv_sec == 0
|
||||||
|
&& timeout.tv_usec == 0) ? FALSE : TRUE;
|
||||||
|
|
||||||
|
call_again:
|
||||||
|
xdrs->x_op = XDR_ENCODE;
|
||||||
|
ct->ct_error.re_status = RPC_SUCCESS;
|
||||||
|
x_id = ntohl(--(*msg_x_id));
|
||||||
|
|
||||||
|
if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
|
||||||
|
(! XDR_PUTINT32(xdrs, (int32_t *)&proc)) ||
|
||||||
|
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
|
||||||
|
(! AUTH_WRAP(cl->cl_auth, xdrs, xdr_args, args_ptr))) {
|
||||||
|
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||||
|
ct->ct_error.re_status = RPC_CANTENCODEARGS;
|
||||||
|
(void)xdrrec_endofrecord(xdrs, TRUE);
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (ct->ct_error.re_status);
|
||||||
|
}
|
||||||
|
if (! xdrrec_endofrecord(xdrs, shipnow)) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (ct->ct_error.re_status = RPC_CANTSEND);
|
||||||
|
}
|
||||||
|
if (! shipnow) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (RPC_SUCCESS);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Hack to provide rpc-based message passing
|
||||||
|
*/
|
||||||
|
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return(ct->ct_error.re_status = RPC_TIMEDOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep receiving until we get a valid transaction id
|
||||||
|
*/
|
||||||
|
xdrs->x_op = XDR_DECODE;
|
||||||
|
while (TRUE) {
|
||||||
|
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||||
|
reply_msg.acpted_rply.ar_results.where = NULL;
|
||||||
|
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
|
||||||
|
if (! xdrrec_skiprecord(xdrs)) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (ct->ct_error.re_status);
|
||||||
|
}
|
||||||
|
/* now decode and validate the response header */
|
||||||
|
if (! xdr_replymsg(xdrs, &reply_msg)) {
|
||||||
|
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||||
|
continue;
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (ct->ct_error.re_status);
|
||||||
|
}
|
||||||
|
if (reply_msg.rm_xid == x_id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process header
|
||||||
|
*/
|
||||||
|
_seterr_reply(&reply_msg, &(ct->ct_error));
|
||||||
|
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
||||||
|
if (! AUTH_VALIDATE(cl->cl_auth,
|
||||||
|
&reply_msg.acpted_rply.ar_verf)) {
|
||||||
|
ct->ct_error.re_status = RPC_AUTHERROR;
|
||||||
|
ct->ct_error.re_why = AUTH_INVALIDRESP;
|
||||||
|
} else if (! AUTH_UNWRAP(cl->cl_auth, xdrs,
|
||||||
|
xdr_results, results_ptr)) {
|
||||||
|
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||||
|
ct->ct_error.re_status = RPC_CANTDECODERES;
|
||||||
|
}
|
||||||
|
/* free verifier ... */
|
||||||
|
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
(void)xdr_opaque_auth(xdrs,
|
||||||
|
&(reply_msg.acpted_rply.ar_verf));
|
||||||
|
}
|
||||||
|
} /* end successful completion */
|
||||||
|
else {
|
||||||
|
/* maybe our credentials need to be refreshed ... */
|
||||||
|
if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg))
|
||||||
|
goto call_again;
|
||||||
|
} /* end of unsuccessful completion */
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (ct->ct_error.re_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clnt_vc_geterr(cl, errp)
|
||||||
|
CLIENT *cl;
|
||||||
|
struct rpc_err *errp;
|
||||||
|
{
|
||||||
|
struct ct_data *ct;
|
||||||
|
|
||||||
|
assert(cl != NULL);
|
||||||
|
assert(errp != NULL);
|
||||||
|
|
||||||
|
ct = (struct ct_data *) cl->cl_private;
|
||||||
|
*errp = ct->ct_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
clnt_vc_freeres(cl, xdr_res, res_ptr)
|
||||||
|
CLIENT *cl;
|
||||||
|
xdrproc_t xdr_res;
|
||||||
|
void *res_ptr;
|
||||||
|
{
|
||||||
|
struct ct_data *ct;
|
||||||
|
XDR *xdrs;
|
||||||
|
bool_t dummy;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
assert(cl != NULL);
|
||||||
|
|
||||||
|
ct = (struct ct_data *)cl->cl_private;
|
||||||
|
xdrs = &(ct->ct_xdrs);
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (ct->ct_fd_lock->active)
|
||||||
|
cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
xdrs->x_op = XDR_FREE;
|
||||||
|
dummy = (*xdr_res)(xdrs, res_ptr);
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
cond_signal(&ct->ct_fd_lock->cv);
|
||||||
|
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static void
|
||||||
|
clnt_vc_abort(cl)
|
||||||
|
CLIENT *cl;
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t
|
||||||
|
clnt_vc_control(cl, request, info)
|
||||||
|
CLIENT *cl;
|
||||||
|
u_int request;
|
||||||
|
void *info;
|
||||||
|
{
|
||||||
|
struct ct_data *ct;
|
||||||
|
void *infop = info;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
u_int32_t tmp;
|
||||||
|
u_int32_t ltmp;
|
||||||
|
|
||||||
|
assert(cl != NULL);
|
||||||
|
|
||||||
|
ct = (struct ct_data *)cl->cl_private;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (ct->ct_fd_lock->active)
|
||||||
|
cond_wait(&ct->ct_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
ct->ct_fd_lock->active = TRUE;
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
|
||||||
|
switch (request) {
|
||||||
|
case CLSET_FD_CLOSE:
|
||||||
|
ct->ct_closeit = TRUE;
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
case CLSET_FD_NCLOSE:
|
||||||
|
ct->ct_closeit = FALSE;
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for other requests which use info */
|
||||||
|
if (info == NULL) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
switch (request) {
|
||||||
|
case CLSET_TIMEOUT:
|
||||||
|
if (time_not_ok((struct timeval *)info)) {
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
ct->ct_wait = *(struct timeval *)infop;
|
||||||
|
ct->ct_waitset = TRUE;
|
||||||
|
break;
|
||||||
|
case CLGET_TIMEOUT:
|
||||||
|
*(struct timeval *)infop = ct->ct_wait;
|
||||||
|
break;
|
||||||
|
case CLGET_SERVER_ADDR:
|
||||||
|
(void) memcpy(info, ct->ct_addr.buf, (size_t)ct->ct_addr.len);
|
||||||
|
break;
|
||||||
|
case CLGET_FD:
|
||||||
|
*(int *)info = ct->ct_fd;
|
||||||
|
break;
|
||||||
|
case CLGET_SVC_ADDR:
|
||||||
|
/* The caller should not free this memory area */
|
||||||
|
*(struct netbuf *)info = ct->ct_addr;
|
||||||
|
break;
|
||||||
|
case CLSET_SVC_ADDR: /* set to new address */
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
case CLGET_XID:
|
||||||
|
/*
|
||||||
|
* use the knowledge that xid is the
|
||||||
|
* first element in the call structure
|
||||||
|
* This will get the xid of the PREVIOUS call
|
||||||
|
*/
|
||||||
|
*(u_int32_t *)info =
|
||||||
|
ntohl(*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli);
|
||||||
|
break;
|
||||||
|
case CLSET_XID:
|
||||||
|
/* This will set the xid of the NEXT call */
|
||||||
|
*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli =
|
||||||
|
htonl(*((u_int32_t *)info) + 1);
|
||||||
|
/* increment by 1 as clnt_vc_call() decrements once */
|
||||||
|
break;
|
||||||
|
case CLGET_VERS:
|
||||||
|
/*
|
||||||
|
* This RELIES on the information that, in the call body,
|
||||||
|
* the version number field is the fifth field from the
|
||||||
|
* begining of the RPC header. MUST be changed if the
|
||||||
|
* call_struct is changed
|
||||||
|
*/
|
||||||
|
memcpy(&tmp, ct->ct_u.ct_mcallc + 4 * BYTES_PER_XDR_UNIT, sizeof (tmp));
|
||||||
|
ltmp = ntohl(tmp);
|
||||||
|
memcpy(info, <mp, sizeof (ltmp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLSET_VERS:
|
||||||
|
memcpy(<mp, info, sizeof (ltmp));
|
||||||
|
tmp = htonl(ltmp);
|
||||||
|
memcpy(ct->ct_u.ct_mcallc + 4 * BYTES_PER_XDR_UNIT, &tmp, sizeof(tmp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLGET_PROG:
|
||||||
|
/*
|
||||||
|
* This RELIES on the information that, in the call body,
|
||||||
|
* the program number field is the fourth field from the
|
||||||
|
* begining of the RPC header. MUST be changed if the
|
||||||
|
* call_struct is changed
|
||||||
|
*/
|
||||||
|
memcpy(&tmp, ct->ct_u.ct_mcallc + 3 * BYTES_PER_XDR_UNIT, sizeof (tmp));
|
||||||
|
ltmp = ntohl (tmp);
|
||||||
|
memcpy(info, <mp, sizeof (ltmp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLSET_PROG:
|
||||||
|
memcpy(<mp, info, sizeof (ltmp));
|
||||||
|
tmp = htonl(ltmp);
|
||||||
|
memcpy(ct->ct_u.ct_mcallc + 3 * BYTES_PER_XDR_UNIT, &tmp, sizeof(tmp));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
release_fd_lock(ct->ct_fd_lock, mask);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
clnt_vc_destroy(cl)
|
||||||
|
CLIENT *cl;
|
||||||
|
{
|
||||||
|
assert(cl != NULL);
|
||||||
|
struct ct_data *ct = (struct ct_data *) cl->cl_private;
|
||||||
|
int ct_fd = ct->ct_fd;
|
||||||
|
fd_lock_t *ct_fd_lock = ct->ct_fd_lock;
|
||||||
|
sigset_t mask;
|
||||||
|
sigset_t newmask;
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&clnt_fd_lock);
|
||||||
|
while (ct_fd_lock->active)
|
||||||
|
cond_wait(&ct_fd_lock->cv, &clnt_fd_lock);
|
||||||
|
if (ct->ct_closeit && ct->ct_fd != -1) {
|
||||||
|
(void)close(ct->ct_fd);
|
||||||
|
}
|
||||||
|
XDR_DESTROY(&(ct->ct_xdrs));
|
||||||
|
if (ct->ct_addr.buf)
|
||||||
|
free(ct->ct_addr.buf);
|
||||||
|
mem_free(ct, sizeof(struct ct_data));
|
||||||
|
if (cl->cl_netid && cl->cl_netid[0])
|
||||||
|
mem_free(cl->cl_netid, strlen(cl->cl_netid) +1);
|
||||||
|
if (cl->cl_tp && cl->cl_tp[0])
|
||||||
|
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
|
||||||
|
mem_free(cl, sizeof(CLIENT));
|
||||||
|
cond_signal(&ct_fd_lock->cv);
|
||||||
|
fd_lock_destroy(ct_fd, ct_fd_lock, vc_fd_locks);
|
||||||
|
mutex_unlock(&clnt_fd_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface between xdr serializer and tcp connection.
|
||||||
|
* Behaves like the system calls, read & write, but keeps some error state
|
||||||
|
* around for the rpc level.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
read_vc(ctp, buf, len)
|
||||||
|
void *ctp;
|
||||||
|
void *buf;
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
struct sockaddr sa;
|
||||||
|
socklen_t sal;
|
||||||
|
*/
|
||||||
|
struct ct_data *ct = (struct ct_data *)ctp;
|
||||||
|
struct pollfd fd;
|
||||||
|
int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) +
|
||||||
|
(ct->ct_wait.tv_usec / 1000));
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return (0);
|
||||||
|
fd.fd = ct->ct_fd;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
for (;;) {
|
||||||
|
switch (poll(&fd, 1, milliseconds)) {
|
||||||
|
case 0:
|
||||||
|
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
ct->ct_error.re_status = RPC_CANTRECV;
|
||||||
|
ct->ct_error.re_errno = errno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read(ct->ct_fd, buf, (size_t)len);
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 0:
|
||||||
|
/* premature eof */
|
||||||
|
ct->ct_error.re_errno = ECONNRESET;
|
||||||
|
ct->ct_error.re_status = RPC_CANTRECV;
|
||||||
|
len = -1; /* it's really an error */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
ct->ct_error.re_errno = errno;
|
||||||
|
ct->ct_error.re_status = RPC_CANTRECV;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_vc(ctp, buf, len)
|
||||||
|
void *ctp;
|
||||||
|
void *buf;
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
struct ct_data *ct = (struct ct_data *)ctp;
|
||||||
|
int i = 0, cnt;
|
||||||
|
|
||||||
|
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
|
||||||
|
if ((i = write(ct->ct_fd, buf, (size_t)cnt)) == -1) {
|
||||||
|
ct->ct_error.re_errno = errno;
|
||||||
|
ct->ct_error.re_status = RPC_CANTSEND;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clnt_ops *
|
||||||
|
clnt_vc_ops()
|
||||||
|
{
|
||||||
|
static struct clnt_ops ops;
|
||||||
|
extern mutex_t ops_lock;
|
||||||
|
sigset_t mask, newmask;
|
||||||
|
|
||||||
|
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||||
|
|
||||||
|
sigfillset(&newmask);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||||
|
mutex_lock(&ops_lock);
|
||||||
|
if (ops.cl_call == NULL) {
|
||||||
|
ops.cl_call = clnt_vc_call;
|
||||||
|
ops.cl_abort = clnt_vc_abort;
|
||||||
|
ops.cl_geterr = clnt_vc_geterr;
|
||||||
|
ops.cl_freeres = clnt_vc_freeres;
|
||||||
|
ops.cl_destroy = clnt_vc_destroy;
|
||||||
|
ops.cl_control = clnt_vc_control;
|
||||||
|
}
|
||||||
|
mutex_unlock(&ops_lock);
|
||||||
|
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||||
|
return (&ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that the time is not garbage. -1 value is disallowed.
|
||||||
|
* Note this is different from time_not_ok in clnt_dg.c
|
||||||
|
*/
|
||||||
|
static bool_t
|
||||||
|
time_not_ok(t)
|
||||||
|
struct timeval *t;
|
||||||
|
{
|
||||||
|
return (t->tv_sec <= -1 || t->tv_sec > 100000000 ||
|
||||||
|
t->tv_usec <= -1 || t->tv_usec > 1000000);
|
||||||
|
}
|
||||||
99
libtirpc-1.3.1/src/crypt_client.c
Normal file
99
libtirpc-1.3.1/src/crypt_client.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996
|
||||||
|
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by Bill Paul.
|
||||||
|
* 4. Neither the name of the author nor the names of any co-contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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 <err.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <rpc/des_crypt.h>
|
||||||
|
#include <rpc/des.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rpcsvc/crypt.h>
|
||||||
|
|
||||||
|
#include <netconfig.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
_des_crypt_call(buf, len, dparms)
|
||||||
|
char *buf;
|
||||||
|
int len;
|
||||||
|
struct desparams *dparms;
|
||||||
|
{
|
||||||
|
CLIENT *clnt;
|
||||||
|
desresp *result_1;
|
||||||
|
desargs des_crypt_1_arg;
|
||||||
|
struct netconfig *nconf;
|
||||||
|
void *localhandle;
|
||||||
|
int stat;
|
||||||
|
|
||||||
|
nconf = NULL;
|
||||||
|
localhandle = setnetconfig();
|
||||||
|
while ((nconf = getnetconfig(localhandle)) != NULL) {
|
||||||
|
if (nconf->nc_protofmly != NULL &&
|
||||||
|
strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nconf == NULL) {
|
||||||
|
warnx("getnetconfig: %s", nc_sperror());
|
||||||
|
return(DESERR_HWERROR);
|
||||||
|
}
|
||||||
|
clnt = clnt_tp_create(NULL, CRYPT_PROG, CRYPT_VERS, nconf);
|
||||||
|
if (clnt == (CLIENT *) NULL) {
|
||||||
|
endnetconfig(localhandle);
|
||||||
|
return(DESERR_HWERROR);
|
||||||
|
}
|
||||||
|
endnetconfig(localhandle);
|
||||||
|
|
||||||
|
des_crypt_1_arg.desbuf.desbuf_len = len;
|
||||||
|
des_crypt_1_arg.desbuf.desbuf_val = buf;
|
||||||
|
des_crypt_1_arg.des_dir = dparms->des_dir;
|
||||||
|
des_crypt_1_arg.des_mode = dparms->des_mode;
|
||||||
|
memcpy(des_crypt_1_arg.des_ivec, dparms->des_ivec, 8);
|
||||||
|
memcpy(des_crypt_1_arg.des_key, dparms->des_key, 8);
|
||||||
|
|
||||||
|
result_1 = des_crypt_1(&des_crypt_1_arg, clnt);
|
||||||
|
if (result_1 == (desresp *) NULL) {
|
||||||
|
clnt_destroy(clnt);
|
||||||
|
return(DESERR_HWERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
stat = result_1->stat;
|
||||||
|
|
||||||
|
if (result_1->stat == DESERR_NONE ||
|
||||||
|
result_1->stat == DESERR_NOHWDEVICE) {
|
||||||
|
memcpy(buf, result_1->desbuf.desbuf_val, len);
|
||||||
|
memcpy(dparms->des_ivec, result_1->des_ivec, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
clnt_freeres(clnt, (xdrproc_t)xdr_desresp, result_1);
|
||||||
|
clnt_destroy(clnt);
|
||||||
|
|
||||||
|
return(stat);
|
||||||
|
}
|
||||||
73
libtirpc-1.3.1/src/debug.c
Normal file
73
libtirpc-1.3.1/src/debug.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* debug.c -- debugging routines for libtirpc
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Red Hat, Steve Dickson <steved@redhat.com>
|
||||||
|
*
|
||||||
|
* 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/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
/* library global debug level */
|
||||||
|
int libtirpc_debug_level = 0;
|
||||||
|
int log_stderr = 1; /* log to stderr instead of systlog */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the debug level for the entire library.
|
||||||
|
* Different area will used the value to determin
|
||||||
|
* the verbosity of the debugging output.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
libtirpc_set_debug(char *name, int level, int use_stderr)
|
||||||
|
{
|
||||||
|
if (level < 0)
|
||||||
|
level = 0;
|
||||||
|
|
||||||
|
log_stderr = use_stderr;
|
||||||
|
if (!use_stderr)
|
||||||
|
openlog(name, LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
|
libtirpc_debug_level = level;
|
||||||
|
LIBTIRPC_DEBUG(1, ("libtirpc: debug level %d", libtirpc_debug_level));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
libtirpc_log_dbg(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
if (log_stderr) {
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
} else
|
||||||
|
vsyslog(LOG_NOTICE, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
59
libtirpc-1.3.1/src/debug.h
Normal file
59
libtirpc-1.3.1/src/debug.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* debug.h -- debugging routines for libtirpc
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Red Hat, Steve Dickson <steved@redhat.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DEBUG_H
|
||||||
|
#define _DEBUG_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
extern int libtirpc_debug_level;
|
||||||
|
extern int log_stderr;
|
||||||
|
|
||||||
|
void libtirpc_log_dbg(char *format, ...);
|
||||||
|
void libtirpc_set_debug(char *name, int level, int use_stderr);
|
||||||
|
|
||||||
|
#define LIBTIRPC_DEBUG(level, msg) \
|
||||||
|
do { \
|
||||||
|
if (level <= libtirpc_debug_level) \
|
||||||
|
libtirpc_log_dbg msg; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vlibtirpc_log_dbg(int level, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
if (level <= libtirpc_debug_level) {
|
||||||
|
if (log_stderr) {
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
} else
|
||||||
|
vsyslog(LOG_NOTICE, fmt, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* _DEBUG_H */
|
||||||
146
libtirpc-1.3.1/src/des_crypt.c
Normal file
146
libtirpc-1.3.1/src/des_crypt.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* des_crypt.c, DES encryption library routines
|
||||||
|
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <rpc/types.h>
|
||||||
|
#include <rpc/des_crypt.h>
|
||||||
|
#include <rpc/des.h>
|
||||||
|
#if 0
|
||||||
|
#ifndef lint
|
||||||
|
static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int common_crypt( char *, char *, unsigned, unsigned, struct desparams * );
|
||||||
|
/*
|
||||||
|
* Copy 8 bytes
|
||||||
|
*/
|
||||||
|
#define COPY8(src, dst) { \
|
||||||
|
char *a = (char *) dst; \
|
||||||
|
char *b = (char *) src; \
|
||||||
|
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
|
||||||
|
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy multiple of 8 bytes
|
||||||
|
*/
|
||||||
|
#define DESCOPY(src, dst, len) { \
|
||||||
|
char *a = (char *) dst; \
|
||||||
|
char *b = (char *) src; \
|
||||||
|
int i; \
|
||||||
|
for (i = (int) len; i > 0; i -= 8) { \
|
||||||
|
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
|
||||||
|
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CBC mode encryption
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cbc_crypt(key, buf, len, mode, ivec)
|
||||||
|
char *key;
|
||||||
|
char *buf;
|
||||||
|
unsigned len;
|
||||||
|
unsigned mode;
|
||||||
|
char *ivec;
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct desparams dp;
|
||||||
|
|
||||||
|
#ifdef BROKEN_DES
|
||||||
|
dp.UDES.UDES_buf = buf;
|
||||||
|
dp.des_mode = ECB;
|
||||||
|
#else
|
||||||
|
dp.des_mode = CBC;
|
||||||
|
#endif
|
||||||
|
COPY8(ivec, dp.des_ivec);
|
||||||
|
err = common_crypt(key, buf, len, mode, &dp);
|
||||||
|
COPY8(dp.des_ivec, ivec);
|
||||||
|
return(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ECB mode encryption
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ecb_crypt(key, buf, len, mode)
|
||||||
|
char *key;
|
||||||
|
char *buf;
|
||||||
|
unsigned len;
|
||||||
|
unsigned mode;
|
||||||
|
{
|
||||||
|
struct desparams dp;
|
||||||
|
|
||||||
|
#ifdef BROKEN_DES
|
||||||
|
dp.UDES.UDES_buf = buf;
|
||||||
|
dp.des_mode = CBC;
|
||||||
|
#else
|
||||||
|
dp.des_mode = ECB;
|
||||||
|
#endif
|
||||||
|
return(common_crypt(key, buf, len, mode, &dp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common code to cbc_crypt() & ecb_crypt()
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
common_crypt(key, buf, len, mode, desp)
|
||||||
|
char *key;
|
||||||
|
char *buf;
|
||||||
|
unsigned len;
|
||||||
|
unsigned mode;
|
||||||
|
struct desparams *desp;
|
||||||
|
{
|
||||||
|
int desdev;
|
||||||
|
|
||||||
|
if ((len % 8) != 0 || len > DES_MAXDATA) {
|
||||||
|
return(DESERR_BADPARAM);
|
||||||
|
}
|
||||||
|
desp->des_dir =
|
||||||
|
((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
|
||||||
|
|
||||||
|
desdev = mode & DES_DEVMASK;
|
||||||
|
COPY8(key, desp->des_key);
|
||||||
|
/*
|
||||||
|
* software
|
||||||
|
*/
|
||||||
|
if (!_des_crypt(buf, len, desp)) {
|
||||||
|
return (DESERR_HWERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
|
||||||
|
}
|
||||||
594
libtirpc-1.3.1/src/des_impl.c
Normal file
594
libtirpc-1.3.1/src/des_impl.c
Normal file
@ -0,0 +1,594 @@
|
|||||||
|
/* Copyright (C) 1992 Eric Young */
|
||||||
|
/* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
|
||||||
|
/* This file is distributed under the terms of the GNU Lesser General */
|
||||||
|
/* Public License, version 2.1 or later - see the file COPYING.LIB for details.*/
|
||||||
|
/* If you did not receive a copy of the license with this program, please*/
|
||||||
|
/* see <http://www.gnu.org/licenses/> to obtain a copy. */
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <rpc/des.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const uint32_t des_SPtrans[8][64] =
|
||||||
|
{
|
||||||
|
{ /* nibble 0 */
|
||||||
|
0x00820200, 0x00020000, 0x80800000, 0x80820200,
|
||||||
|
0x00800000, 0x80020200, 0x80020000, 0x80800000,
|
||||||
|
0x80020200, 0x00820200, 0x00820000, 0x80000200,
|
||||||
|
0x80800200, 0x00800000, 0x00000000, 0x80020000,
|
||||||
|
0x00020000, 0x80000000, 0x00800200, 0x00020200,
|
||||||
|
0x80820200, 0x00820000, 0x80000200, 0x00800200,
|
||||||
|
0x80000000, 0x00000200, 0x00020200, 0x80820000,
|
||||||
|
0x00000200, 0x80800200, 0x80820000, 0x00000000,
|
||||||
|
0x00000000, 0x80820200, 0x00800200, 0x80020000,
|
||||||
|
0x00820200, 0x00020000, 0x80000200, 0x00800200,
|
||||||
|
0x80820000, 0x00000200, 0x00020200, 0x80800000,
|
||||||
|
0x80020200, 0x80000000, 0x80800000, 0x00820000,
|
||||||
|
0x80820200, 0x00020200, 0x00820000, 0x80800200,
|
||||||
|
0x00800000, 0x80000200, 0x80020000, 0x00000000,
|
||||||
|
0x00020000, 0x00800000, 0x80800200, 0x00820200,
|
||||||
|
0x80000000, 0x80820000, 0x00000200, 0x80020200},
|
||||||
|
|
||||||
|
{ /* nibble 1 */
|
||||||
|
0x10042004, 0x00000000, 0x00042000, 0x10040000,
|
||||||
|
0x10000004, 0x00002004, 0x10002000, 0x00042000,
|
||||||
|
0x00002000, 0x10040004, 0x00000004, 0x10002000,
|
||||||
|
0x00040004, 0x10042000, 0x10040000, 0x00000004,
|
||||||
|
0x00040000, 0x10002004, 0x10040004, 0x00002000,
|
||||||
|
0x00042004, 0x10000000, 0x00000000, 0x00040004,
|
||||||
|
0x10002004, 0x00042004, 0x10042000, 0x10000004,
|
||||||
|
0x10000000, 0x00040000, 0x00002004, 0x10042004,
|
||||||
|
0x00040004, 0x10042000, 0x10002000, 0x00042004,
|
||||||
|
0x10042004, 0x00040004, 0x10000004, 0x00000000,
|
||||||
|
0x10000000, 0x00002004, 0x00040000, 0x10040004,
|
||||||
|
0x00002000, 0x10000000, 0x00042004, 0x10002004,
|
||||||
|
0x10042000, 0x00002000, 0x00000000, 0x10000004,
|
||||||
|
0x00000004, 0x10042004, 0x00042000, 0x10040000,
|
||||||
|
0x10040004, 0x00040000, 0x00002004, 0x10002000,
|
||||||
|
0x10002004, 0x00000004, 0x10040000, 0x00042000},
|
||||||
|
|
||||||
|
{ /* nibble 2 */
|
||||||
|
0x41000000, 0x01010040, 0x00000040, 0x41000040,
|
||||||
|
0x40010000, 0x01000000, 0x41000040, 0x00010040,
|
||||||
|
0x01000040, 0x00010000, 0x01010000, 0x40000000,
|
||||||
|
0x41010040, 0x40000040, 0x40000000, 0x41010000,
|
||||||
|
0x00000000, 0x40010000, 0x01010040, 0x00000040,
|
||||||
|
0x40000040, 0x41010040, 0x00010000, 0x41000000,
|
||||||
|
0x41010000, 0x01000040, 0x40010040, 0x01010000,
|
||||||
|
0x00010040, 0x00000000, 0x01000000, 0x40010040,
|
||||||
|
0x01010040, 0x00000040, 0x40000000, 0x00010000,
|
||||||
|
0x40000040, 0x40010000, 0x01010000, 0x41000040,
|
||||||
|
0x00000000, 0x01010040, 0x00010040, 0x41010000,
|
||||||
|
0x40010000, 0x01000000, 0x41010040, 0x40000000,
|
||||||
|
0x40010040, 0x41000000, 0x01000000, 0x41010040,
|
||||||
|
0x00010000, 0x01000040, 0x41000040, 0x00010040,
|
||||||
|
0x01000040, 0x00000000, 0x41010000, 0x40000040,
|
||||||
|
0x41000000, 0x40010040, 0x00000040, 0x01010000},
|
||||||
|
|
||||||
|
{ /* nibble 3 */
|
||||||
|
0x00100402, 0x04000400, 0x00000002, 0x04100402,
|
||||||
|
0x00000000, 0x04100000, 0x04000402, 0x00100002,
|
||||||
|
0x04100400, 0x04000002, 0x04000000, 0x00000402,
|
||||||
|
0x04000002, 0x00100402, 0x00100000, 0x04000000,
|
||||||
|
0x04100002, 0x00100400, 0x00000400, 0x00000002,
|
||||||
|
0x00100400, 0x04000402, 0x04100000, 0x00000400,
|
||||||
|
0x00000402, 0x00000000, 0x00100002, 0x04100400,
|
||||||
|
0x04000400, 0x04100002, 0x04100402, 0x00100000,
|
||||||
|
0x04100002, 0x00000402, 0x00100000, 0x04000002,
|
||||||
|
0x00100400, 0x04000400, 0x00000002, 0x04100000,
|
||||||
|
0x04000402, 0x00000000, 0x00000400, 0x00100002,
|
||||||
|
0x00000000, 0x04100002, 0x04100400, 0x00000400,
|
||||||
|
0x04000000, 0x04100402, 0x00100402, 0x00100000,
|
||||||
|
0x04100402, 0x00000002, 0x04000400, 0x00100402,
|
||||||
|
0x00100002, 0x00100400, 0x04100000, 0x04000402,
|
||||||
|
0x00000402, 0x04000000, 0x04000002, 0x04100400},
|
||||||
|
|
||||||
|
{ /* nibble 4 */
|
||||||
|
0x02000000, 0x00004000, 0x00000100, 0x02004108,
|
||||||
|
0x02004008, 0x02000100, 0x00004108, 0x02004000,
|
||||||
|
0x00004000, 0x00000008, 0x02000008, 0x00004100,
|
||||||
|
0x02000108, 0x02004008, 0x02004100, 0x00000000,
|
||||||
|
0x00004100, 0x02000000, 0x00004008, 0x00000108,
|
||||||
|
0x02000100, 0x00004108, 0x00000000, 0x02000008,
|
||||||
|
0x00000008, 0x02000108, 0x02004108, 0x00004008,
|
||||||
|
0x02004000, 0x00000100, 0x00000108, 0x02004100,
|
||||||
|
0x02004100, 0x02000108, 0x00004008, 0x02004000,
|
||||||
|
0x00004000, 0x00000008, 0x02000008, 0x02000100,
|
||||||
|
0x02000000, 0x00004100, 0x02004108, 0x00000000,
|
||||||
|
0x00004108, 0x02000000, 0x00000100, 0x00004008,
|
||||||
|
0x02000108, 0x00000100, 0x00000000, 0x02004108,
|
||||||
|
0x02004008, 0x02004100, 0x00000108, 0x00004000,
|
||||||
|
0x00004100, 0x02004008, 0x02000100, 0x00000108,
|
||||||
|
0x00000008, 0x00004108, 0x02004000, 0x02000008},
|
||||||
|
|
||||||
|
{ /* nibble 5 */
|
||||||
|
0x20000010, 0x00080010, 0x00000000, 0x20080800,
|
||||||
|
0x00080010, 0x00000800, 0x20000810, 0x00080000,
|
||||||
|
0x00000810, 0x20080810, 0x00080800, 0x20000000,
|
||||||
|
0x20000800, 0x20000010, 0x20080000, 0x00080810,
|
||||||
|
0x00080000, 0x20000810, 0x20080010, 0x00000000,
|
||||||
|
0x00000800, 0x00000010, 0x20080800, 0x20080010,
|
||||||
|
0x20080810, 0x20080000, 0x20000000, 0x00000810,
|
||||||
|
0x00000010, 0x00080800, 0x00080810, 0x20000800,
|
||||||
|
0x00000810, 0x20000000, 0x20000800, 0x00080810,
|
||||||
|
0x20080800, 0x00080010, 0x00000000, 0x20000800,
|
||||||
|
0x20000000, 0x00000800, 0x20080010, 0x00080000,
|
||||||
|
0x00080010, 0x20080810, 0x00080800, 0x00000010,
|
||||||
|
0x20080810, 0x00080800, 0x00080000, 0x20000810,
|
||||||
|
0x20000010, 0x20080000, 0x00080810, 0x00000000,
|
||||||
|
0x00000800, 0x20000010, 0x20000810, 0x20080800,
|
||||||
|
0x20080000, 0x00000810, 0x00000010, 0x20080010},
|
||||||
|
|
||||||
|
{ /* nibble 6 */
|
||||||
|
0x00001000, 0x00000080, 0x00400080, 0x00400001,
|
||||||
|
0x00401081, 0x00001001, 0x00001080, 0x00000000,
|
||||||
|
0x00400000, 0x00400081, 0x00000081, 0x00401000,
|
||||||
|
0x00000001, 0x00401080, 0x00401000, 0x00000081,
|
||||||
|
0x00400081, 0x00001000, 0x00001001, 0x00401081,
|
||||||
|
0x00000000, 0x00400080, 0x00400001, 0x00001080,
|
||||||
|
0x00401001, 0x00001081, 0x00401080, 0x00000001,
|
||||||
|
0x00001081, 0x00401001, 0x00000080, 0x00400000,
|
||||||
|
0x00001081, 0x00401000, 0x00401001, 0x00000081,
|
||||||
|
0x00001000, 0x00000080, 0x00400000, 0x00401001,
|
||||||
|
0x00400081, 0x00001081, 0x00001080, 0x00000000,
|
||||||
|
0x00000080, 0x00400001, 0x00000001, 0x00400080,
|
||||||
|
0x00000000, 0x00400081, 0x00400080, 0x00001080,
|
||||||
|
0x00000081, 0x00001000, 0x00401081, 0x00400000,
|
||||||
|
0x00401080, 0x00000001, 0x00001001, 0x00401081,
|
||||||
|
0x00400001, 0x00401080, 0x00401000, 0x00001001},
|
||||||
|
|
||||||
|
{ /* nibble 7 */
|
||||||
|
0x08200020, 0x08208000, 0x00008020, 0x00000000,
|
||||||
|
0x08008000, 0x00200020, 0x08200000, 0x08208020,
|
||||||
|
0x00000020, 0x08000000, 0x00208000, 0x00008020,
|
||||||
|
0x00208020, 0x08008020, 0x08000020, 0x08200000,
|
||||||
|
0x00008000, 0x00208020, 0x00200020, 0x08008000,
|
||||||
|
0x08208020, 0x08000020, 0x00000000, 0x00208000,
|
||||||
|
0x08000000, 0x00200000, 0x08008020, 0x08200020,
|
||||||
|
0x00200000, 0x00008000, 0x08208000, 0x00000020,
|
||||||
|
0x00200000, 0x00008000, 0x08000020, 0x08208020,
|
||||||
|
0x00008020, 0x08000000, 0x00000000, 0x00208000,
|
||||||
|
0x08200020, 0x08008020, 0x08008000, 0x00200020,
|
||||||
|
0x08208000, 0x00000020, 0x00200020, 0x08008000,
|
||||||
|
0x08208020, 0x00200000, 0x08200000, 0x08000020,
|
||||||
|
0x00208000, 0x00008020, 0x08008020, 0x08200000,
|
||||||
|
0x00000020, 0x08208000, 0x00208020, 0x00000000,
|
||||||
|
0x08000000, 0x08200020, 0x00008000, 0x00208020}};
|
||||||
|
|
||||||
|
static const uint32_t des_skb[8][64] =
|
||||||
|
{
|
||||||
|
{ /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||||
|
0x00000000, 0x00000010, 0x20000000, 0x20000010,
|
||||||
|
0x00010000, 0x00010010, 0x20010000, 0x20010010,
|
||||||
|
0x00000800, 0x00000810, 0x20000800, 0x20000810,
|
||||||
|
0x00010800, 0x00010810, 0x20010800, 0x20010810,
|
||||||
|
0x00000020, 0x00000030, 0x20000020, 0x20000030,
|
||||||
|
0x00010020, 0x00010030, 0x20010020, 0x20010030,
|
||||||
|
0x00000820, 0x00000830, 0x20000820, 0x20000830,
|
||||||
|
0x00010820, 0x00010830, 0x20010820, 0x20010830,
|
||||||
|
0x00080000, 0x00080010, 0x20080000, 0x20080010,
|
||||||
|
0x00090000, 0x00090010, 0x20090000, 0x20090010,
|
||||||
|
0x00080800, 0x00080810, 0x20080800, 0x20080810,
|
||||||
|
0x00090800, 0x00090810, 0x20090800, 0x20090810,
|
||||||
|
0x00080020, 0x00080030, 0x20080020, 0x20080030,
|
||||||
|
0x00090020, 0x00090030, 0x20090020, 0x20090030,
|
||||||
|
0x00080820, 0x00080830, 0x20080820, 0x20080830,
|
||||||
|
0x00090820, 0x00090830, 0x20090820, 0x20090830},
|
||||||
|
{ /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
|
||||||
|
0x00000000, 0x02000000, 0x00002000, 0x02002000,
|
||||||
|
0x00200000, 0x02200000, 0x00202000, 0x02202000,
|
||||||
|
0x00000004, 0x02000004, 0x00002004, 0x02002004,
|
||||||
|
0x00200004, 0x02200004, 0x00202004, 0x02202004,
|
||||||
|
0x00000400, 0x02000400, 0x00002400, 0x02002400,
|
||||||
|
0x00200400, 0x02200400, 0x00202400, 0x02202400,
|
||||||
|
0x00000404, 0x02000404, 0x00002404, 0x02002404,
|
||||||
|
0x00200404, 0x02200404, 0x00202404, 0x02202404,
|
||||||
|
0x10000000, 0x12000000, 0x10002000, 0x12002000,
|
||||||
|
0x10200000, 0x12200000, 0x10202000, 0x12202000,
|
||||||
|
0x10000004, 0x12000004, 0x10002004, 0x12002004,
|
||||||
|
0x10200004, 0x12200004, 0x10202004, 0x12202004,
|
||||||
|
0x10000400, 0x12000400, 0x10002400, 0x12002400,
|
||||||
|
0x10200400, 0x12200400, 0x10202400, 0x12202400,
|
||||||
|
0x10000404, 0x12000404, 0x10002404, 0x12002404,
|
||||||
|
0x10200404, 0x12200404, 0x10202404, 0x12202404},
|
||||||
|
{ /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
|
||||||
|
0x00000000, 0x00000001, 0x00040000, 0x00040001,
|
||||||
|
0x01000000, 0x01000001, 0x01040000, 0x01040001,
|
||||||
|
0x00000002, 0x00000003, 0x00040002, 0x00040003,
|
||||||
|
0x01000002, 0x01000003, 0x01040002, 0x01040003,
|
||||||
|
0x00000200, 0x00000201, 0x00040200, 0x00040201,
|
||||||
|
0x01000200, 0x01000201, 0x01040200, 0x01040201,
|
||||||
|
0x00000202, 0x00000203, 0x00040202, 0x00040203,
|
||||||
|
0x01000202, 0x01000203, 0x01040202, 0x01040203,
|
||||||
|
0x08000000, 0x08000001, 0x08040000, 0x08040001,
|
||||||
|
0x09000000, 0x09000001, 0x09040000, 0x09040001,
|
||||||
|
0x08000002, 0x08000003, 0x08040002, 0x08040003,
|
||||||
|
0x09000002, 0x09000003, 0x09040002, 0x09040003,
|
||||||
|
0x08000200, 0x08000201, 0x08040200, 0x08040201,
|
||||||
|
0x09000200, 0x09000201, 0x09040200, 0x09040201,
|
||||||
|
0x08000202, 0x08000203, 0x08040202, 0x08040203,
|
||||||
|
0x09000202, 0x09000203, 0x09040202, 0x09040203},
|
||||||
|
{ /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
|
||||||
|
0x00000000, 0x00100000, 0x00000100, 0x00100100,
|
||||||
|
0x00000008, 0x00100008, 0x00000108, 0x00100108,
|
||||||
|
0x00001000, 0x00101000, 0x00001100, 0x00101100,
|
||||||
|
0x00001008, 0x00101008, 0x00001108, 0x00101108,
|
||||||
|
0x04000000, 0x04100000, 0x04000100, 0x04100100,
|
||||||
|
0x04000008, 0x04100008, 0x04000108, 0x04100108,
|
||||||
|
0x04001000, 0x04101000, 0x04001100, 0x04101100,
|
||||||
|
0x04001008, 0x04101008, 0x04001108, 0x04101108,
|
||||||
|
0x00020000, 0x00120000, 0x00020100, 0x00120100,
|
||||||
|
0x00020008, 0x00120008, 0x00020108, 0x00120108,
|
||||||
|
0x00021000, 0x00121000, 0x00021100, 0x00121100,
|
||||||
|
0x00021008, 0x00121008, 0x00021108, 0x00121108,
|
||||||
|
0x04020000, 0x04120000, 0x04020100, 0x04120100,
|
||||||
|
0x04020008, 0x04120008, 0x04020108, 0x04120108,
|
||||||
|
0x04021000, 0x04121000, 0x04021100, 0x04121100,
|
||||||
|
0x04021008, 0x04121008, 0x04021108, 0x04121108},
|
||||||
|
{ /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
||||||
|
0x00000000, 0x10000000, 0x00010000, 0x10010000,
|
||||||
|
0x00000004, 0x10000004, 0x00010004, 0x10010004,
|
||||||
|
0x20000000, 0x30000000, 0x20010000, 0x30010000,
|
||||||
|
0x20000004, 0x30000004, 0x20010004, 0x30010004,
|
||||||
|
0x00100000, 0x10100000, 0x00110000, 0x10110000,
|
||||||
|
0x00100004, 0x10100004, 0x00110004, 0x10110004,
|
||||||
|
0x20100000, 0x30100000, 0x20110000, 0x30110000,
|
||||||
|
0x20100004, 0x30100004, 0x20110004, 0x30110004,
|
||||||
|
0x00001000, 0x10001000, 0x00011000, 0x10011000,
|
||||||
|
0x00001004, 0x10001004, 0x00011004, 0x10011004,
|
||||||
|
0x20001000, 0x30001000, 0x20011000, 0x30011000,
|
||||||
|
0x20001004, 0x30001004, 0x20011004, 0x30011004,
|
||||||
|
0x00101000, 0x10101000, 0x00111000, 0x10111000,
|
||||||
|
0x00101004, 0x10101004, 0x00111004, 0x10111004,
|
||||||
|
0x20101000, 0x30101000, 0x20111000, 0x30111000,
|
||||||
|
0x20101004, 0x30101004, 0x20111004, 0x30111004},
|
||||||
|
{ /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
|
||||||
|
0x00000000, 0x08000000, 0x00000008, 0x08000008,
|
||||||
|
0x00000400, 0x08000400, 0x00000408, 0x08000408,
|
||||||
|
0x00020000, 0x08020000, 0x00020008, 0x08020008,
|
||||||
|
0x00020400, 0x08020400, 0x00020408, 0x08020408,
|
||||||
|
0x00000001, 0x08000001, 0x00000009, 0x08000009,
|
||||||
|
0x00000401, 0x08000401, 0x00000409, 0x08000409,
|
||||||
|
0x00020001, 0x08020001, 0x00020009, 0x08020009,
|
||||||
|
0x00020401, 0x08020401, 0x00020409, 0x08020409,
|
||||||
|
0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
|
||||||
|
0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
|
||||||
|
0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
|
||||||
|
0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
|
||||||
|
0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
|
||||||
|
0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
|
||||||
|
0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
|
||||||
|
0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
|
||||||
|
{ /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
|
||||||
|
0x00000000, 0x00000100, 0x00080000, 0x00080100,
|
||||||
|
0x01000000, 0x01000100, 0x01080000, 0x01080100,
|
||||||
|
0x00000010, 0x00000110, 0x00080010, 0x00080110,
|
||||||
|
0x01000010, 0x01000110, 0x01080010, 0x01080110,
|
||||||
|
0x00200000, 0x00200100, 0x00280000, 0x00280100,
|
||||||
|
0x01200000, 0x01200100, 0x01280000, 0x01280100,
|
||||||
|
0x00200010, 0x00200110, 0x00280010, 0x00280110,
|
||||||
|
0x01200010, 0x01200110, 0x01280010, 0x01280110,
|
||||||
|
0x00000200, 0x00000300, 0x00080200, 0x00080300,
|
||||||
|
0x01000200, 0x01000300, 0x01080200, 0x01080300,
|
||||||
|
0x00000210, 0x00000310, 0x00080210, 0x00080310,
|
||||||
|
0x01000210, 0x01000310, 0x01080210, 0x01080310,
|
||||||
|
0x00200200, 0x00200300, 0x00280200, 0x00280300,
|
||||||
|
0x01200200, 0x01200300, 0x01280200, 0x01280300,
|
||||||
|
0x00200210, 0x00200310, 0x00280210, 0x00280310,
|
||||||
|
0x01200210, 0x01200310, 0x01280210, 0x01280310},
|
||||||
|
{ /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
|
||||||
|
0x00000000, 0x04000000, 0x00040000, 0x04040000,
|
||||||
|
0x00000002, 0x04000002, 0x00040002, 0x04040002,
|
||||||
|
0x00002000, 0x04002000, 0x00042000, 0x04042000,
|
||||||
|
0x00002002, 0x04002002, 0x00042002, 0x04042002,
|
||||||
|
0x00000020, 0x04000020, 0x00040020, 0x04040020,
|
||||||
|
0x00000022, 0x04000022, 0x00040022, 0x04040022,
|
||||||
|
0x00002020, 0x04002020, 0x00042020, 0x04042020,
|
||||||
|
0x00002022, 0x04002022, 0x00042022, 0x04042022,
|
||||||
|
0x00000800, 0x04000800, 0x00040800, 0x04040800,
|
||||||
|
0x00000802, 0x04000802, 0x00040802, 0x04040802,
|
||||||
|
0x00002800, 0x04002800, 0x00042800, 0x04042800,
|
||||||
|
0x00002802, 0x04002802, 0x00042802, 0x04042802,
|
||||||
|
0x00000820, 0x04000820, 0x00040820, 0x04040820,
|
||||||
|
0x00000822, 0x04000822, 0x00040822, 0x04040822,
|
||||||
|
0x00002820, 0x04002820, 0x00042820, 0x04042820,
|
||||||
|
0x00002822, 0x04002822, 0x00042822, 0x04042822},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
|
||||||
|
l|=((unsigned long)(*((c)++)))<< 8, \
|
||||||
|
l|=((unsigned long)(*((c)++)))<<16, \
|
||||||
|
l|=((unsigned long)(*((c)++)))<<24)
|
||||||
|
|
||||||
|
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||||
|
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||||
|
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||||
|
*((c)++)=(unsigned char)(((l)>>24)&0xff))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IP and FP
|
||||||
|
* The problem is more of a geometric problem that random bit fiddling.
|
||||||
|
* 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
|
||||||
|
* 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
|
||||||
|
* 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
|
||||||
|
* 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
|
||||||
|
*
|
||||||
|
* 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
|
||||||
|
* 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
|
||||||
|
* 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
|
||||||
|
* 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
|
||||||
|
*
|
||||||
|
* The output has been subject to swaps of the form
|
||||||
|
* 0 1 -> 3 1 but the odd and even bits have been put into
|
||||||
|
* 2 3 2 0
|
||||||
|
* different words. The main trick is to remember that
|
||||||
|
* t=((l>>size)^r)&(mask);
|
||||||
|
* r^=t;
|
||||||
|
* l^=(t<<size);
|
||||||
|
* can be used to swap and move bits between words.
|
||||||
|
*
|
||||||
|
* So l = 0 1 2 3 r = 16 17 18 19
|
||||||
|
* 4 5 6 7 20 21 22 23
|
||||||
|
* 8 9 10 11 24 25 26 27
|
||||||
|
* 12 13 14 15 28 29 30 31
|
||||||
|
* becomes (for size == 2 and mask == 0x3333)
|
||||||
|
* t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
|
||||||
|
* 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
|
||||||
|
* 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
|
||||||
|
* 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
|
||||||
|
*
|
||||||
|
* Thanks for hints from Richard Outerbridge - he told me IP&FP
|
||||||
|
* could be done in 15 xor, 10 shifts and 5 ands.
|
||||||
|
* When I finally started to think of the problem in 2D
|
||||||
|
* I first got ~42 operations without xors. When I remembered
|
||||||
|
* how to use xors I got it to its final state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
||||||
|
(b)^=(t),\
|
||||||
|
(a)^=((t)<<(n)))
|
||||||
|
|
||||||
|
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
|
||||||
|
(a)=(a)^(t)^(t>>(16-(n))))
|
||||||
|
|
||||||
|
|
||||||
|
#define D_ENCRYPT(L,R,S) \
|
||||||
|
u=(R^s[S ]); \
|
||||||
|
t=R^s[S+1]; \
|
||||||
|
t=((t>>4)+(t<<28)); \
|
||||||
|
L^= des_SPtrans[1][(t )&0x3f]| \
|
||||||
|
des_SPtrans[3][(t>> 8)&0x3f]| \
|
||||||
|
des_SPtrans[5][(t>>16)&0x3f]| \
|
||||||
|
des_SPtrans[7][(t>>24)&0x3f]| \
|
||||||
|
des_SPtrans[0][(u )&0x3f]| \
|
||||||
|
des_SPtrans[2][(u>> 8)&0x3f]| \
|
||||||
|
des_SPtrans[4][(u>>16)&0x3f]| \
|
||||||
|
des_SPtrans[6][(u>>24)&0x3f];
|
||||||
|
|
||||||
|
#define ITERATIONS 16
|
||||||
|
|
||||||
|
static const char shifts2[16] =
|
||||||
|
{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
|
||||||
|
|
||||||
|
static void des_set_key (unsigned char *, unsigned long *);
|
||||||
|
static void des_encrypt (unsigned long *, unsigned long *, int);
|
||||||
|
int _des_crypt (char *, unsigned, struct desparams *);
|
||||||
|
|
||||||
|
static void
|
||||||
|
des_set_key (unsigned char *key, unsigned long *schedule)
|
||||||
|
{
|
||||||
|
register unsigned long c, d, t, s;
|
||||||
|
register unsigned char *in;
|
||||||
|
register unsigned long *k;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
k = (unsigned long *) schedule;
|
||||||
|
in = key;
|
||||||
|
|
||||||
|
c2l (in, c);
|
||||||
|
c2l (in, d);
|
||||||
|
|
||||||
|
/* I now do it in 47 simple operations
|
||||||
|
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
|
||||||
|
* for the inspiration. */
|
||||||
|
PERM_OP (d, c, t, 4, 0x0f0f0f0f);
|
||||||
|
HPERM_OP (c, t, -2, 0xcccc0000);
|
||||||
|
HPERM_OP (d, t, -2, 0xcccc0000);
|
||||||
|
PERM_OP (d, c, t, 1, 0x55555555);
|
||||||
|
PERM_OP (c, d, t, 8, 0x00ff00ff);
|
||||||
|
PERM_OP (d, c, t, 1, 0x55555555);
|
||||||
|
d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
|
||||||
|
((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
|
||||||
|
c &= 0x0fffffff;
|
||||||
|
|
||||||
|
for (i = 0; i < ITERATIONS; i++)
|
||||||
|
{
|
||||||
|
if (shifts2[i])
|
||||||
|
{
|
||||||
|
c = ((c >> 2) | (c << 26));
|
||||||
|
d = ((d >> 2) | (d << 26));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = ((c >> 1) | (c << 27));
|
||||||
|
d = ((d >> 1) | (d << 27));
|
||||||
|
}
|
||||||
|
c &= 0x0fffffff;
|
||||||
|
d &= 0x0fffffff;
|
||||||
|
/* could be a few less shifts but I am to lazy at this
|
||||||
|
* point in time to investigate */
|
||||||
|
s = des_skb[0][(c) & 0x3f] |
|
||||||
|
des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
|
||||||
|
des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
|
||||||
|
des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
|
||||||
|
t = des_skb[4][(d) & 0x3f] |
|
||||||
|
des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
|
||||||
|
des_skb[6][(d >> 15) & 0x3f] |
|
||||||
|
des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
|
||||||
|
|
||||||
|
/* table contained 0213 4657 */
|
||||||
|
*(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
|
||||||
|
s = ((s >> 16) | (t & 0xffff0000));
|
||||||
|
|
||||||
|
s = (s << 4) | (s >> 28);
|
||||||
|
*(k++) = s & 0xffffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
|
||||||
|
{
|
||||||
|
register unsigned long l, r, t, u;
|
||||||
|
register int i;
|
||||||
|
register unsigned long *s;
|
||||||
|
|
||||||
|
l = buf[0];
|
||||||
|
r = buf[1];
|
||||||
|
|
||||||
|
/* do IP */
|
||||||
|
PERM_OP (r, l, t, 4, 0x0f0f0f0f);
|
||||||
|
PERM_OP (l, r, t, 16, 0x0000ffff);
|
||||||
|
PERM_OP (r, l, t, 2, 0x33333333);
|
||||||
|
PERM_OP (l, r, t, 8, 0x00ff00ff);
|
||||||
|
PERM_OP (r, l, t, 1, 0x55555555);
|
||||||
|
/* r and l are reversed - remember that - fix
|
||||||
|
* it in the next step */
|
||||||
|
|
||||||
|
/* Things have been modified so that the initial rotate is
|
||||||
|
* done outside the loop. This required the
|
||||||
|
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
|
||||||
|
* One perl script later and things have a 5% speed up on a sparc2.
|
||||||
|
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
||||||
|
* for pointing this out. */
|
||||||
|
t = (r << 1) | (r >> 31);
|
||||||
|
r = (l << 1) | (l >> 31);
|
||||||
|
l = t;
|
||||||
|
|
||||||
|
/* clear the top bits on machines with 8byte longs */
|
||||||
|
l &= 0xffffffff;
|
||||||
|
r &= 0xffffffff;
|
||||||
|
|
||||||
|
s = (unsigned long *) schedule;
|
||||||
|
/* I don't know if it is worth the effort of loop unrolling the
|
||||||
|
* inner loop */
|
||||||
|
if (encrypt)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 32; i += 4)
|
||||||
|
{
|
||||||
|
D_ENCRYPT (l, r, i + 0); /* 1 */
|
||||||
|
D_ENCRYPT (r, l, i + 2); /* 2 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 30; i > 0; i -= 4)
|
||||||
|
{
|
||||||
|
D_ENCRYPT (l, r, i - 0); /* 16 */
|
||||||
|
D_ENCRYPT (r, l, i - 2); /* 15 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l = (l >> 1) | (l << 31);
|
||||||
|
r = (r >> 1) | (r << 31);
|
||||||
|
/* clear the top bits on machines with 8byte longs */
|
||||||
|
l &= 0xffffffff;
|
||||||
|
r &= 0xffffffff;
|
||||||
|
|
||||||
|
/* swap l and r
|
||||||
|
* we will not do the swap so just remember they are
|
||||||
|
* reversed for the rest of the subroutine
|
||||||
|
* luckily FP fixes this problem */
|
||||||
|
|
||||||
|
PERM_OP (r, l, t, 1, 0x55555555);
|
||||||
|
PERM_OP (l, r, t, 8, 0x00ff00ff);
|
||||||
|
PERM_OP (r, l, t, 2, 0x33333333);
|
||||||
|
PERM_OP (l, r, t, 16, 0x0000ffff);
|
||||||
|
PERM_OP (r, l, t, 4, 0x0f0f0f0f);
|
||||||
|
|
||||||
|
buf[0] = l;
|
||||||
|
buf[1] = r;
|
||||||
|
|
||||||
|
l = r = t = u = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_des_crypt (char *buf, unsigned len, struct desparams *desp)
|
||||||
|
{
|
||||||
|
unsigned long schedule[32];
|
||||||
|
register unsigned long tin0, tin1;
|
||||||
|
register unsigned long tout0, tout1, xor0, xor1;
|
||||||
|
register unsigned char *in, *out;
|
||||||
|
unsigned long tbuf[2];
|
||||||
|
unsigned char *iv, *oiv;
|
||||||
|
int cbc_mode;
|
||||||
|
|
||||||
|
cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
|
||||||
|
|
||||||
|
in = (unsigned char *) buf;
|
||||||
|
out = (unsigned char *) buf;
|
||||||
|
oiv = iv = (unsigned char *) desp->des_ivec;
|
||||||
|
|
||||||
|
des_set_key (desp->des_key, schedule);
|
||||||
|
|
||||||
|
tin0 = tin1 = 0; /* For GCC */
|
||||||
|
if (desp->des_dir == ENCRYPT)
|
||||||
|
{
|
||||||
|
c2l (iv, tout0);
|
||||||
|
c2l (iv, tout1);
|
||||||
|
for (; len > 0; len -= 8)
|
||||||
|
{
|
||||||
|
c2l (in, tin0);
|
||||||
|
c2l (in, tin1);
|
||||||
|
if (cbc_mode)
|
||||||
|
{
|
||||||
|
tin0 ^= tout0;
|
||||||
|
tin1 ^= tout1;
|
||||||
|
}
|
||||||
|
tbuf[0] = tin0;
|
||||||
|
tbuf[1] = tin1;
|
||||||
|
des_encrypt (tbuf, schedule, 1);
|
||||||
|
tout0 = tbuf[0];
|
||||||
|
tout1 = tbuf[1];
|
||||||
|
l2c (tout0, out);
|
||||||
|
l2c (tout1, out);
|
||||||
|
}
|
||||||
|
l2c (tout0, oiv);
|
||||||
|
l2c (tout1, oiv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c2l (iv, xor0);
|
||||||
|
c2l (iv, xor1);
|
||||||
|
for (; len > 0; len -= 8)
|
||||||
|
{
|
||||||
|
c2l (in, tin0);
|
||||||
|
c2l (in, tin1);
|
||||||
|
tbuf[0] = tin0;
|
||||||
|
tbuf[1] = tin1;
|
||||||
|
des_encrypt (tbuf, schedule, 0);
|
||||||
|
if (cbc_mode)
|
||||||
|
{
|
||||||
|
tout0 = tbuf[0] ^ xor0;
|
||||||
|
tout1 = tbuf[1] ^ xor1;
|
||||||
|
xor0 = tin0;
|
||||||
|
xor1 = tin1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tout0 = tbuf[0];
|
||||||
|
tout1 = tbuf[1];
|
||||||
|
}
|
||||||
|
l2c (tout0, out);
|
||||||
|
l2c (tout1, out);
|
||||||
|
}
|
||||||
|
l2c (tin0, oiv);
|
||||||
|
l2c (tin1, oiv);
|
||||||
|
}
|
||||||
|
tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
|
||||||
|
tbuf[0] = tbuf[1] = 0;
|
||||||
|
memset (schedule, 0, sizeof (schedule));
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
65
libtirpc-1.3.1/src/des_soft.c
Normal file
65
libtirpc-1.3.1/src/des_soft.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
//#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Table giving odd parity in the low bit for ASCII characters
|
||||||
|
*/
|
||||||
|
static char partab[128] = {
|
||||||
|
0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
|
||||||
|
0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
|
||||||
|
0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
|
||||||
|
0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
|
||||||
|
0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
|
||||||
|
0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
|
||||||
|
0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
|
||||||
|
0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
|
||||||
|
0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
|
||||||
|
0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
|
||||||
|
0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
|
||||||
|
0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
|
||||||
|
0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
|
||||||
|
0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
|
||||||
|
0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
|
||||||
|
0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add odd parity to low bit of 8 byte key
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
des_setparity(p)
|
||||||
|
char *p;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
*p = partab[*p & 0x7f];
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
libtirpc-1.3.1/src/epoll_sub.c
Normal file
58
libtirpc-1.3.1/src/epoll_sub.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003 Niels Provos <provos@citi.umich.edu>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*Param<61>tres du syscall - Attention sp<73>cifique hardware */
|
||||||
|
#define __NR_epoll_create 254
|
||||||
|
#define __NR_epoll_ctl 255
|
||||||
|
#define __NR_epoll_wait 256
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_create(int size)
|
||||||
|
{
|
||||||
|
return (syscall(__NR_epoll_create, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (syscall(__NR_epoll_ctl, epfd, op, fd, event));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
|
||||||
|
{
|
||||||
|
return (syscall(__NR_epoll_wait, epfd, events, maxevents, timeout));
|
||||||
|
}
|
||||||
721
libtirpc-1.3.1/src/getnetconfig.c
Normal file
721
libtirpc-1.3.1/src/getnetconfig.c
Normal file
@ -0,0 +1,721 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1989 by Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netconfig.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The five library routines in this file provide application access to the
|
||||||
|
* system network configuration database, /etc/netconfig. In addition to the
|
||||||
|
* netconfig database and the routines for accessing it, the environment
|
||||||
|
* variable NETPATH and its corresponding routines in getnetpath.c may also be
|
||||||
|
* used to specify the network transport to be used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* netconfig errors
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NC_NONETCONFIG ENOENT
|
||||||
|
#define NC_NOMEM ENOMEM
|
||||||
|
#define NC_NOTINIT EINVAL /* setnetconfig was not called first */
|
||||||
|
#define NC_BADFILE EBADF /* format for netconfig file is bad */
|
||||||
|
#define NC_NOTFOUND ENOPROTOOPT /* specified netid was not found */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* semantics as strings (should be in netconfig.h)
|
||||||
|
*/
|
||||||
|
#define NC_TPI_CLTS_S "tpi_clts"
|
||||||
|
#define NC_TPI_COTS_S "tpi_cots"
|
||||||
|
#define NC_TPI_COTS_ORD_S "tpi_cots_ord"
|
||||||
|
#define NC_TPI_RAW_S "tpi_raw"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flags as characters (also should be in netconfig.h)
|
||||||
|
*/
|
||||||
|
#define NC_NOFLAG_C '-'
|
||||||
|
#define NC_VISIBLE_C 'v'
|
||||||
|
#define NC_BROADCAST_C 'b'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Character used to indicate there is no name-to-address lookup library
|
||||||
|
*/
|
||||||
|
#define NC_NOLOOKUP "-"
|
||||||
|
|
||||||
|
static const char * const _nc_errors[] = {
|
||||||
|
"Netconfig database not found",
|
||||||
|
"Not enough memory",
|
||||||
|
"Not initialized",
|
||||||
|
"Netconfig database has invalid format",
|
||||||
|
"Netid not found in netconfig database"
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netconfig_info {
|
||||||
|
int eof; /* all entries has been read */
|
||||||
|
int ref; /* # of times setnetconfig() has been called */
|
||||||
|
struct netconfig_list *head; /* head of the list */
|
||||||
|
struct netconfig_list *tail; /* last of the list */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netconfig_list {
|
||||||
|
char *linep; /* hold line read from netconfig */
|
||||||
|
struct netconfig *ncp;
|
||||||
|
struct netconfig_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netconfig_vars {
|
||||||
|
int valid; /* token that indicates a valid netconfig_vars */
|
||||||
|
int flag; /* first time flag */
|
||||||
|
struct netconfig_list *nc_configs; /* pointer to the current netconfig entry */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NC_VALID 0xfeed
|
||||||
|
#define NC_STORAGE 0xf00d
|
||||||
|
#define NC_INVALID 0
|
||||||
|
|
||||||
|
|
||||||
|
static int *__nc_error(void);
|
||||||
|
static int parse_ncp(char *, struct netconfig *);
|
||||||
|
static struct netconfig *dup_ncp(struct netconfig *);
|
||||||
|
|
||||||
|
|
||||||
|
static FILE *nc_file; /* for netconfig db */
|
||||||
|
static struct netconfig_info ni = { 0, 0, NULL, NULL};
|
||||||
|
extern pthread_mutex_t nc_db_lock;
|
||||||
|
|
||||||
|
#define MAXNETCONFIGLINE 1000
|
||||||
|
|
||||||
|
static int *
|
||||||
|
__nc_error()
|
||||||
|
{
|
||||||
|
static pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
extern thread_key_t nc_key;
|
||||||
|
static int nc_error = 0;
|
||||||
|
int error, *nc_addr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the static `nc_error' if we are the main thread
|
||||||
|
* (including non-threaded programs), or if an allocation
|
||||||
|
* fails.
|
||||||
|
*/
|
||||||
|
if (nc_key == KEY_INITIALIZER) {
|
||||||
|
error = 0;
|
||||||
|
mutex_lock(&nc_lock);
|
||||||
|
if (nc_key == KEY_INITIALIZER)
|
||||||
|
error = thr_keycreate(&nc_key, free);
|
||||||
|
mutex_unlock(&nc_lock);
|
||||||
|
if (error)
|
||||||
|
return (&nc_error);
|
||||||
|
}
|
||||||
|
if ((nc_addr = (int *)thr_getspecific(nc_key)) == NULL) {
|
||||||
|
if((nc_addr = (int *)malloc(sizeof (int))) == NULL)
|
||||||
|
return (&nc_error);
|
||||||
|
if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
|
||||||
|
if (nc_addr)
|
||||||
|
free(nc_addr);
|
||||||
|
return (&nc_error);
|
||||||
|
}
|
||||||
|
*nc_addr = 0;
|
||||||
|
}
|
||||||
|
return (nc_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define nc_error (*(__nc_error()))
|
||||||
|
/*
|
||||||
|
* A call to setnetconfig() establishes a /etc/netconfig "session". A session
|
||||||
|
* "handle" is returned on a successful call. At the start of a session (after
|
||||||
|
* a call to setnetconfig()) searches through the /etc/netconfig database will
|
||||||
|
* proceed from the start of the file. The session handle must be passed to
|
||||||
|
* getnetconfig() to parse the file. Each call to getnetconfig() using the
|
||||||
|
* current handle will process one subsequent entry in /etc/netconfig.
|
||||||
|
* setnetconfig() must be called before the first call to getnetconfig().
|
||||||
|
* (Handles are used to allow for nested calls to setnetpath()).
|
||||||
|
*
|
||||||
|
* A new session is established with each call to setnetconfig(), with a new
|
||||||
|
* handle being returned on each call. Previously established sessions remain
|
||||||
|
* active until endnetconfig() is called with that session's handle as an
|
||||||
|
* argument.
|
||||||
|
*
|
||||||
|
* setnetconfig() need *not* be called before a call to getnetconfigent().
|
||||||
|
* setnetconfig() returns a NULL pointer on failure (for example, if
|
||||||
|
* the netconfig database is not present).
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
setnetconfig()
|
||||||
|
{
|
||||||
|
struct netconfig_vars *nc_vars;
|
||||||
|
|
||||||
|
if ((nc_vars = (struct netconfig_vars *)malloc(sizeof
|
||||||
|
(struct netconfig_vars))) == NULL) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For multiple calls, i.e. nc_file is not NULL, we just return the
|
||||||
|
* handle without reopening the netconfig db.
|
||||||
|
*/
|
||||||
|
mutex_lock(&nc_db_lock);
|
||||||
|
ni.ref++;
|
||||||
|
if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) {
|
||||||
|
nc_vars->valid = NC_VALID;
|
||||||
|
nc_vars->flag = 0;
|
||||||
|
nc_vars->nc_configs = ni.head;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return ((void *)nc_vars);
|
||||||
|
}
|
||||||
|
ni.ref--;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
nc_error = NC_NONETCONFIG;
|
||||||
|
free(nc_vars);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When first called, getnetconfig() returns a pointer to the first entry in
|
||||||
|
* the netconfig database, formatted as a struct netconfig. On each subsequent
|
||||||
|
* call, getnetconfig() returns a pointer to the next entry in the database.
|
||||||
|
* getnetconfig() can thus be used to search the entire netconfig file.
|
||||||
|
* getnetconfig() returns NULL at end of file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct netconfig *
|
||||||
|
getnetconfig(handlep)
|
||||||
|
void *handlep;
|
||||||
|
{
|
||||||
|
struct netconfig_vars *ncp = (struct netconfig_vars *)handlep;
|
||||||
|
char *stringp; /* tmp string pointer */
|
||||||
|
struct netconfig_list *list;
|
||||||
|
struct netconfig *np;
|
||||||
|
struct netconfig *result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that handle is valid
|
||||||
|
*/
|
||||||
|
mutex_lock(&nc_db_lock);
|
||||||
|
if (ncp == NULL || nc_file == NULL) {
|
||||||
|
nc_error = NC_NOTINIT;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ncp->valid) {
|
||||||
|
case NC_VALID:
|
||||||
|
/*
|
||||||
|
* If entry has already been read into the list,
|
||||||
|
* we return the entry in the linked list.
|
||||||
|
* If this is the first time call, check if there are any entries in
|
||||||
|
* linked list. If no entries, we need to read the netconfig db.
|
||||||
|
* If we have been here and the next entry is there, we just return
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
if (ncp->flag == 0) { /* first time */
|
||||||
|
ncp->flag = 1;
|
||||||
|
ncp->nc_configs = ni.head;
|
||||||
|
if (ncp->nc_configs != NULL) /* entry already exist */ {
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(ncp->nc_configs->ncp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ncp->nc_configs != NULL && ncp->nc_configs->next != NULL) {
|
||||||
|
ncp->nc_configs = ncp->nc_configs->next;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(ncp->nc_configs->ncp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we cannot find the entry in the list and is end of file,
|
||||||
|
* we give up.
|
||||||
|
*/
|
||||||
|
if (ni.eof == 1) {
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nc_error = NC_NOTINIT;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
stringp = (char *) malloc(MAXNETCONFIGLINE);
|
||||||
|
if (stringp == NULL) {
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MEM_CHK
|
||||||
|
if (malloc_verify() == 0) {
|
||||||
|
fprintf(stderr, "memory heap corrupted in getnetconfig\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a line from netconfig file.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) {
|
||||||
|
free(stringp);
|
||||||
|
ni.eof = 1;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
} while (*stringp == '#');
|
||||||
|
|
||||||
|
list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list));
|
||||||
|
if (list == NULL) {
|
||||||
|
free(stringp);
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
np = (struct netconfig *) malloc(sizeof (struct netconfig));
|
||||||
|
if (np == NULL) {
|
||||||
|
free(stringp);
|
||||||
|
free(list);
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
list->ncp = np;
|
||||||
|
list->next = NULL;
|
||||||
|
list->ncp->nc_lookups = NULL;
|
||||||
|
list->linep = stringp;
|
||||||
|
if (parse_ncp(stringp, list->ncp) == -1) {
|
||||||
|
free(stringp);
|
||||||
|
free(np);
|
||||||
|
free(list);
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* If this is the first entry that's been read, it is the head of
|
||||||
|
* the list. If not, put the entry at the end of the list.
|
||||||
|
* Reposition the current pointer of the handle to the last entry
|
||||||
|
* in the list.
|
||||||
|
*/
|
||||||
|
if (ni.head == NULL) { /* first entry */
|
||||||
|
ni.head = ni.tail = list;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ni.tail->next = list;
|
||||||
|
ni.tail = ni.tail->next;
|
||||||
|
}
|
||||||
|
ncp->nc_configs = ni.tail;
|
||||||
|
result = ni.tail->ncp;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endnetconfig() may be called to "unbind" or "close" the netconfig database
|
||||||
|
* when processing is complete, releasing resources for reuse. endnetconfig()
|
||||||
|
* may not be called before setnetconfig(). endnetconfig() returns 0 on
|
||||||
|
* success and -1 on failure (for example, if setnetconfig() was not called
|
||||||
|
* previously).
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
endnetconfig(handlep)
|
||||||
|
void *handlep;
|
||||||
|
{
|
||||||
|
struct netconfig_vars *nc_handlep = (struct netconfig_vars *)handlep;
|
||||||
|
|
||||||
|
struct netconfig_list *q, *p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify that handle is valid
|
||||||
|
*/
|
||||||
|
if (nc_handlep == NULL || (nc_handlep->valid != NC_VALID &&
|
||||||
|
nc_handlep->valid != NC_STORAGE)) {
|
||||||
|
nc_error = NC_NOTINIT;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0 if anyone still needs it.
|
||||||
|
*/
|
||||||
|
nc_handlep->valid = NC_INVALID;
|
||||||
|
nc_handlep->flag = 0;
|
||||||
|
nc_handlep->nc_configs = NULL;
|
||||||
|
mutex_lock(&nc_db_lock);
|
||||||
|
if (--ni.ref > 0) {
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
free(nc_handlep);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Noone needs these entries anymore, then frees them.
|
||||||
|
* Make sure all info in netconfig_info structure has been reinitialized.
|
||||||
|
*/
|
||||||
|
q = p = ni.head;
|
||||||
|
ni.eof = ni.ref = 0;
|
||||||
|
ni.head = NULL;
|
||||||
|
ni.tail = NULL;
|
||||||
|
while (q) {
|
||||||
|
p = q->next;
|
||||||
|
if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups);
|
||||||
|
free(q->ncp);
|
||||||
|
free(q->linep);
|
||||||
|
free(q);
|
||||||
|
q = p;
|
||||||
|
}
|
||||||
|
free(nc_handlep);
|
||||||
|
if(nc_file != NULL) {
|
||||||
|
fclose(nc_file);
|
||||||
|
}
|
||||||
|
nc_file = NULL;
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getnetconfigent(netid) returns a pointer to the struct netconfig structure
|
||||||
|
* corresponding to netid. It returns NULL if netid is invalid (that is, does
|
||||||
|
* not name an entry in the netconfig database). It returns NULL and sets
|
||||||
|
* errno in case of failure (for example, if the netconfig database cannot be
|
||||||
|
* opened).
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct netconfig *
|
||||||
|
getnetconfigent(netid)
|
||||||
|
const char *netid;
|
||||||
|
{
|
||||||
|
FILE *file; /* NETCONFIG db's file pointer */
|
||||||
|
char *linep; /* holds current netconfig line */
|
||||||
|
char *stringp; /* temporary string pointer */
|
||||||
|
struct netconfig *ncp = NULL; /* returned value */
|
||||||
|
struct netconfig_list *list; /* pointer to cache list */
|
||||||
|
|
||||||
|
nc_error = NC_NOTFOUND; /* default error. */
|
||||||
|
if (netid == NULL || strlen(netid) == 0) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(netid, "unix") == 0) {
|
||||||
|
fprintf(stderr, "The local transport is called \"unix\" ");
|
||||||
|
fprintf(stderr, "in /etc/netconfig.\n");
|
||||||
|
fprintf(stderr, "Please change this to \"local\" manually ");
|
||||||
|
fprintf(stderr, "or run mergemaster(8).\n");
|
||||||
|
fprintf(stderr, "See UPDATING entry 20021216 for details.\n");
|
||||||
|
fprintf(stderr, "Continuing in 10 seconds\n\n");
|
||||||
|
fprintf(stderr, "This warning will be removed 20030301\n");
|
||||||
|
sleep(10);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up table if the entries have already been read and parsed in
|
||||||
|
* getnetconfig(), then copy this entry into a buffer and return it.
|
||||||
|
* If we cannot find the entry in the current list and there are more
|
||||||
|
* entries in the netconfig db that has not been read, we then read the
|
||||||
|
* db and try find the match netid.
|
||||||
|
* If all the netconfig db has been read and placed into the list and
|
||||||
|
* there is no match for the netid, return NULL.
|
||||||
|
*/
|
||||||
|
mutex_lock(&nc_db_lock);
|
||||||
|
if (ni.head != NULL) {
|
||||||
|
for (list = ni.head; list; list = list->next) {
|
||||||
|
if (strcmp(list->ncp->nc_netid, netid) == 0) {
|
||||||
|
ncp = dup_ncp(list->ncp);
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return ncp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ni.eof == 1) { /* that's all the entries */
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&nc_db_lock);
|
||||||
|
|
||||||
|
if ((file = fopen(NETCONFIG, "r")) == NULL) {
|
||||||
|
nc_error = NC_NONETCONFIG;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((linep = malloc(MAXNETCONFIGLINE)) == NULL) {
|
||||||
|
fclose(file);
|
||||||
|
nc_error = NC_NOMEM;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
ptrdiff_t len;
|
||||||
|
char *tmpp; /* tmp string pointer */
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((stringp = fgets(linep, MAXNETCONFIGLINE, file)) == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (*stringp == '#');
|
||||||
|
if (stringp == NULL) { /* eof */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((tmpp = strpbrk(stringp, "\t ")) == NULL) { /* can't parse file */
|
||||||
|
nc_error = NC_BADFILE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strlen(netid) == (size_t) (len = tmpp - stringp) && /* a match */
|
||||||
|
strncmp(stringp, netid, (size_t)len) == 0) {
|
||||||
|
if ((ncp = (struct netconfig *)
|
||||||
|
malloc(sizeof (struct netconfig))) == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ncp->nc_lookups = NULL;
|
||||||
|
if (parse_ncp(linep, ncp) == -1) {
|
||||||
|
free(ncp);
|
||||||
|
ncp = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (stringp != NULL);
|
||||||
|
if (ncp == NULL) {
|
||||||
|
free(linep);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
return(ncp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* freenetconfigent(netconfigp) frees the netconfig structure pointed to by
|
||||||
|
* netconfigp (previously returned by getnetconfigent()).
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
freenetconfigent(netconfigp)
|
||||||
|
struct netconfig *netconfigp;
|
||||||
|
{
|
||||||
|
if (netconfigp != NULL) {
|
||||||
|
free(netconfigp->nc_netid); /* holds all netconfigp's strings */
|
||||||
|
if (netconfigp->nc_lookups != NULL)
|
||||||
|
free(netconfigp->nc_lookups);
|
||||||
|
free(netconfigp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse line and stuff it in a struct netconfig
|
||||||
|
* Typical line might look like:
|
||||||
|
* udp tpi_cots vb inet udp /dev/udp /usr/lib/ip.so,/usr/local/ip.so
|
||||||
|
*
|
||||||
|
* We return -1 if any of the tokens don't parse, or malloc fails.
|
||||||
|
*
|
||||||
|
* Note that we modify stringp (putting NULLs after tokens) and
|
||||||
|
* we set the ncp's string field pointers to point to these tokens within
|
||||||
|
* stringp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_ncp(stringp, ncp)
|
||||||
|
char *stringp; /* string to parse */
|
||||||
|
struct netconfig *ncp; /* where to put results */
|
||||||
|
{
|
||||||
|
char *tokenp; /* for processing tokens */
|
||||||
|
char *lasts;
|
||||||
|
|
||||||
|
nc_error = NC_BADFILE; /* nearly anything that breaks is for this reason */
|
||||||
|
stringp[strlen(stringp)-1] = '\0'; /* get rid of newline */
|
||||||
|
/* netid */
|
||||||
|
if ((ncp->nc_netid = strtok_r(stringp, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* semantics */
|
||||||
|
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (strcmp(tokenp, NC_TPI_COTS_ORD_S) == 0)
|
||||||
|
ncp->nc_semantics = NC_TPI_COTS_ORD;
|
||||||
|
else if (strcmp(tokenp, NC_TPI_COTS_S) == 0)
|
||||||
|
ncp->nc_semantics = NC_TPI_COTS;
|
||||||
|
else if (strcmp(tokenp, NC_TPI_CLTS_S) == 0)
|
||||||
|
ncp->nc_semantics = NC_TPI_CLTS;
|
||||||
|
else if (strcmp(tokenp, NC_TPI_RAW_S) == 0)
|
||||||
|
ncp->nc_semantics = NC_TPI_RAW;
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
for (ncp->nc_flag = NC_NOFLAG; *tokenp != '\0';
|
||||||
|
tokenp++) {
|
||||||
|
switch (*tokenp) {
|
||||||
|
case NC_NOFLAG_C:
|
||||||
|
break;
|
||||||
|
case NC_VISIBLE_C:
|
||||||
|
ncp->nc_flag |= NC_VISIBLE;
|
||||||
|
break;
|
||||||
|
case NC_BROADCAST_C:
|
||||||
|
ncp->nc_flag |= NC_BROADCAST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* protocol family */
|
||||||
|
if ((ncp->nc_protofmly = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* protocol name */
|
||||||
|
if ((ncp->nc_proto = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* network device */
|
||||||
|
if ((ncp->nc_device = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (strcmp(tokenp, NC_NOLOOKUP) == 0) {
|
||||||
|
ncp->nc_nlookups = 0;
|
||||||
|
ncp->nc_lookups = NULL;
|
||||||
|
} else {
|
||||||
|
char *cp; /* tmp string */
|
||||||
|
|
||||||
|
if (ncp->nc_lookups != NULL) /* from last visit */
|
||||||
|
free(ncp->nc_lookups);
|
||||||
|
/* preallocate one string pointer */
|
||||||
|
ncp->nc_lookups = (char **)malloc(sizeof (char *));
|
||||||
|
ncp->nc_nlookups = 0;
|
||||||
|
while ((cp = tokenp) != NULL) {
|
||||||
|
tokenp = _get_next_token(cp, ',');
|
||||||
|
ncp->nc_lookups[(size_t)ncp->nc_nlookups++] = cp;
|
||||||
|
ncp->nc_lookups = (char **)realloc(ncp->nc_lookups,
|
||||||
|
(size_t)(ncp->nc_nlookups+1) *sizeof(char *)); /* for next loop */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string describing the reason for failure.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
nc_sperror()
|
||||||
|
{
|
||||||
|
const char *message;
|
||||||
|
|
||||||
|
switch(nc_error) {
|
||||||
|
case NC_NONETCONFIG:
|
||||||
|
message = _nc_errors[0];
|
||||||
|
break;
|
||||||
|
case NC_NOMEM:
|
||||||
|
message = _nc_errors[1];
|
||||||
|
break;
|
||||||
|
case NC_NOTINIT:
|
||||||
|
message = _nc_errors[2];
|
||||||
|
break;
|
||||||
|
case NC_BADFILE:
|
||||||
|
message = _nc_errors[3];
|
||||||
|
break;
|
||||||
|
case NC_NOTFOUND:
|
||||||
|
message = _nc_errors[4];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = "Unknown network selection error";
|
||||||
|
}
|
||||||
|
/* LINTED const castaway */
|
||||||
|
return ((char *)message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints a message onto standard error describing the reason for failure.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nc_perror(s)
|
||||||
|
const char *s;
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: %s\n", s, nc_sperror());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Duplicates the matched netconfig buffer.
|
||||||
|
*/
|
||||||
|
static struct netconfig *
|
||||||
|
dup_ncp(ncp)
|
||||||
|
struct netconfig *ncp;
|
||||||
|
{
|
||||||
|
struct netconfig *p;
|
||||||
|
char *tmp;
|
||||||
|
char *t;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if ((p=(struct netconfig *)malloc(sizeof(struct netconfig))) == NULL) {
|
||||||
|
free(tmp);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* First we dup all the data from matched netconfig buffer. Then we
|
||||||
|
* adjust some of the member pointer to a pre-allocated buffer where
|
||||||
|
* contains part of the data.
|
||||||
|
* To follow the convention used in parse_ncp(), we store all the
|
||||||
|
* necessary information in the pre-allocated buffer and let each
|
||||||
|
* of the netconfig char pointer member point to the right address
|
||||||
|
* in the buffer.
|
||||||
|
*/
|
||||||
|
*p = *ncp;
|
||||||
|
p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid);
|
||||||
|
t = strchr(tmp, 0) + 1;
|
||||||
|
p->nc_protofmly = (char *)strcpy(t,ncp->nc_protofmly);
|
||||||
|
t = strchr(t, 0) + 1;
|
||||||
|
p->nc_proto = (char *)strcpy(t,ncp->nc_proto);
|
||||||
|
t = strchr(t, 0) + 1;
|
||||||
|
p->nc_device = (char *)strcpy(t,ncp->nc_device);
|
||||||
|
p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *));
|
||||||
|
if (p->nc_lookups == NULL) {
|
||||||
|
free(p);
|
||||||
|
free(tmp);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
for (i=0; i < p->nc_nlookups; i++) {
|
||||||
|
t = strchr(t, 0) + 1;
|
||||||
|
p->nc_lookups[i] = (char *)strcpy(t,ncp->nc_lookups[i]);
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
261
libtirpc-1.3.1/src/getnetpath.c
Normal file
261
libtirpc-1.3.1/src/getnetpath.c
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1989 by Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netconfig.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* internal structure to keep track of a netpath "session"
|
||||||
|
*/
|
||||||
|
struct netpath_chain {
|
||||||
|
struct netconfig *ncp; /* an nconf entry */
|
||||||
|
struct netpath_chain *nchain_next; /* next nconf entry allocated */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct netpath_vars {
|
||||||
|
int valid; /* token that indicates a valid netpath_vars */
|
||||||
|
void *nc_handlep; /* handle for current netconfig "session" */
|
||||||
|
char *netpath; /* pointer to current view-point in NETPATH */
|
||||||
|
char *netpath_start; /* pointer to start of our copy of NETPATH */
|
||||||
|
struct netpath_chain *ncp_list; /* list of nconfs allocated this session*/
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NP_VALID 0xf00d
|
||||||
|
#define NP_INVALID 0
|
||||||
|
|
||||||
|
char *_get_next_token(char *, int);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A call to setnetpath() establishes a NETPATH "session". setnetpath()
|
||||||
|
* must be called before the first call to getnetpath(). A "handle" is
|
||||||
|
* returned to distinguish the session; this handle should be passed
|
||||||
|
* subsequently to getnetpath(). (Handles are used to allow for nested calls
|
||||||
|
* to setnetpath()).
|
||||||
|
* If setnetpath() is unable to establish a session (due to lack of memory
|
||||||
|
* resources, or the absence of the /etc/netconfig file), a NULL pointer is
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
setnetpath()
|
||||||
|
{
|
||||||
|
|
||||||
|
struct netpath_vars *np_sessionp; /* this session's variables */
|
||||||
|
char *npp; /* NETPATH env variable */
|
||||||
|
|
||||||
|
#ifdef MEM_CHK
|
||||||
|
malloc_debug(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((np_sessionp =
|
||||||
|
(struct netpath_vars *)malloc(sizeof (struct netpath_vars))) == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) {
|
||||||
|
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||||
|
free(np_sessionp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
np_sessionp->valid = NP_VALID;
|
||||||
|
np_sessionp->ncp_list = NULL;
|
||||||
|
if ((npp = getenv(NETPATH)) == NULL) {
|
||||||
|
np_sessionp->netpath = NULL;
|
||||||
|
} else {
|
||||||
|
(void) endnetconfig(np_sessionp->nc_handlep);/* won't need nc session*/
|
||||||
|
np_sessionp->nc_handlep = NULL;
|
||||||
|
if ((np_sessionp->netpath = malloc(strlen(npp)+1)) == NULL) {
|
||||||
|
free(np_sessionp);
|
||||||
|
return (NULL);
|
||||||
|
} else {
|
||||||
|
(void) strcpy(np_sessionp->netpath, npp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
np_sessionp->netpath_start = np_sessionp->netpath;
|
||||||
|
return ((void *)np_sessionp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When first called, getnetpath() returns a pointer to the netconfig
|
||||||
|
* database entry corresponding to the first valid NETPATH component. The
|
||||||
|
* netconfig entry is formatted as a struct netconfig.
|
||||||
|
* On each subsequent call, getnetpath returns a pointer to the netconfig
|
||||||
|
* entry that corresponds to the next valid NETPATH component. getnetpath
|
||||||
|
* can thus be used to search the netconfig database for all networks
|
||||||
|
* included in the NETPATH variable.
|
||||||
|
* When NETPATH has been exhausted, getnetpath() returns NULL. It returns
|
||||||
|
* NULL and sets errno in case of an error (e.g., setnetpath was not called
|
||||||
|
* previously).
|
||||||
|
* getnetpath() silently ignores invalid NETPATH components. A NETPATH
|
||||||
|
* compnent is invalid if there is no corresponding entry in the netconfig
|
||||||
|
* database.
|
||||||
|
* If the NETPATH variable is unset, getnetpath() behaves as if NETPATH
|
||||||
|
* were set to the sequence of default or visible networks in the netconfig
|
||||||
|
* database, in the order in which they are listed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct netconfig *
|
||||||
|
getnetpath(handlep)
|
||||||
|
void *handlep;
|
||||||
|
{
|
||||||
|
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
|
||||||
|
struct netconfig *ncp = NULL; /* temp. holds a netconfig session */
|
||||||
|
struct netpath_chain *chainp; /* holds chain of ncp's we alloc */
|
||||||
|
char *npp; /* holds current NETPATH */
|
||||||
|
|
||||||
|
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (np_sessionp->netpath_start == NULL) { /* NETPATH was not set */
|
||||||
|
do { /* select next visible network */
|
||||||
|
if (np_sessionp->nc_handlep == NULL) {
|
||||||
|
np_sessionp->nc_handlep = setnetconfig();
|
||||||
|
if (np_sessionp->nc_handlep == NULL)
|
||||||
|
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||||
|
}
|
||||||
|
if ((ncp = getnetconfig(np_sessionp->nc_handlep)) == NULL) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
} while ((ncp->nc_flag & NC_VISIBLE) == 0);
|
||||||
|
return (ncp);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Find first valid network ID in netpath.
|
||||||
|
*/
|
||||||
|
while ((npp = np_sessionp->netpath) != NULL && strlen(npp) != 0) {
|
||||||
|
np_sessionp->netpath = _get_next_token(npp, ':');
|
||||||
|
/*
|
||||||
|
* npp is a network identifier.
|
||||||
|
*/
|
||||||
|
if ((ncp = getnetconfigent(npp)) != NULL) {
|
||||||
|
chainp = (struct netpath_chain *) /* cobble alloc chain entry */
|
||||||
|
malloc(sizeof (struct netpath_chain));
|
||||||
|
chainp->ncp = ncp;
|
||||||
|
chainp->nchain_next = NULL;
|
||||||
|
if (np_sessionp->ncp_list == NULL) {
|
||||||
|
np_sessionp->ncp_list = chainp;
|
||||||
|
} else {
|
||||||
|
np_sessionp->ncp_list->nchain_next = chainp;
|
||||||
|
}
|
||||||
|
return (ncp);
|
||||||
|
}
|
||||||
|
/* couldn't find this token in the database; go to next one. */
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endnetpath() may be called to unbind NETPATH when processing is complete,
|
||||||
|
* releasing resources for reuse. It returns 0 on success and -1 on failure
|
||||||
|
* (e.g. if setnetpath() was not called previously.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
endnetpath(handlep)
|
||||||
|
void *handlep;
|
||||||
|
{
|
||||||
|
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
|
||||||
|
struct netpath_chain *chainp, *lastp;
|
||||||
|
|
||||||
|
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (np_sessionp->nc_handlep != NULL)
|
||||||
|
endnetconfig(np_sessionp->nc_handlep);
|
||||||
|
if (np_sessionp->netpath_start != NULL)
|
||||||
|
free(np_sessionp->netpath_start);
|
||||||
|
for (chainp = np_sessionp->ncp_list; chainp != NULL;
|
||||||
|
lastp=chainp, chainp=chainp->nchain_next, free(lastp)) {
|
||||||
|
freenetconfigent(chainp->ncp);
|
||||||
|
}
|
||||||
|
free(np_sessionp);
|
||||||
|
#ifdef MEM_CHK
|
||||||
|
if (malloc_verify() == 0) {
|
||||||
|
fprintf(stderr, "memory heap corrupted in endnetpath\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns pointer to the rest-of-the-string after the current token.
|
||||||
|
* The token itself starts at arg, and we null terminate it. We return NULL
|
||||||
|
* if either the arg is empty, or if this is the last token.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
_get_next_token(npp, token)
|
||||||
|
char *npp; /* string */
|
||||||
|
int token; /* char to parse string for */
|
||||||
|
{
|
||||||
|
char *cp; /* char pointer */
|
||||||
|
char *np; /* netpath pointer */
|
||||||
|
char *ep; /* escape pointer */
|
||||||
|
|
||||||
|
if ((cp = strchr(npp, token)) == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* did find a token, but it might be escaped.
|
||||||
|
*/
|
||||||
|
if ((cp > npp) && (cp[-1] == '\\')) {
|
||||||
|
/* if slash was also escaped, carry on, otherwise find next token */
|
||||||
|
if ((cp > npp + 1) && (cp[-2] != '\\')) {
|
||||||
|
/* shift r-o-s onto the escaped token */
|
||||||
|
strcpy(&cp[-1], cp); /* XXX: overlapping string copy */
|
||||||
|
/*
|
||||||
|
* Do a recursive call.
|
||||||
|
* We don't know how many escaped tokens there might be.
|
||||||
|
*/
|
||||||
|
return (_get_next_token(cp, token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*cp++ = '\0'; /* null-terminate token */
|
||||||
|
/* get rid of any backslash escapes */
|
||||||
|
ep = npp;
|
||||||
|
while ((np = strchr(ep, '\\')) != 0) {
|
||||||
|
if (np[1] == '\\')
|
||||||
|
np++;
|
||||||
|
strcpy(np, (ep = &np[1])); /* XXX: overlapping string copy */
|
||||||
|
}
|
||||||
|
return (cp); /* return ptr to r-o-s */
|
||||||
|
}
|
||||||
51
libtirpc-1.3.1/src/getpeereid.c
Normal file
51
libtirpc-1.3.1/src/getpeereid.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Dima Dorfman.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/param.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
getpeereid(int s, uid_t *euid, gid_t *egid)
|
||||||
|
{
|
||||||
|
struct ucred uc;
|
||||||
|
socklen_t uclen;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
uclen = sizeof(uc);
|
||||||
|
error = getsockopt(s, SOL_SOCKET, SO_PEERCRED, &uc, &uclen); /* SCM_CREDENTIALS */
|
||||||
|
if (error != 0)
|
||||||
|
return (error);
|
||||||
|
// if (uc.cr_version != XUCRED_VERSION)
|
||||||
|
// return (EINVAL);
|
||||||
|
*euid = uc.uid;
|
||||||
|
*egid = uc.gid;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
170
libtirpc-1.3.1/src/getpublickey.c
Normal file
170
libtirpc-1.3.1/src/getpublickey.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* publickey.c
|
||||||
|
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public key lookup routines
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/key_prot.h>
|
||||||
|
#ifdef YP
|
||||||
|
#include <rpcsvc/yp_prot.h>
|
||||||
|
#include <rpcsvc/ypclnt.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define PKFILE "/etc/publickey"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hack to let ypserv/rpc.nisd use AUTH_DES.
|
||||||
|
*/
|
||||||
|
int (*__getpublickey_LOCAL)() = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get somebody's public key
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__getpublickey_real(netname, publickey)
|
||||||
|
char *netname;
|
||||||
|
char *publickey;
|
||||||
|
{
|
||||||
|
char lookup[3 * HEXKEYBYTES];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (publickey == NULL)
|
||||||
|
return (0);
|
||||||
|
if (!getpublicandprivatekey(netname, lookup))
|
||||||
|
return (0);
|
||||||
|
p = strchr(lookup, ':');
|
||||||
|
if (p == NULL) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
memcpy(publickey, lookup, HEXKEYBYTES);
|
||||||
|
publickey[HEXKEYBYTES] = '\0';
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reads the file /etc/publickey looking for a + to optionally go to the
|
||||||
|
* yellow pages
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
getpublicandprivatekey(key, ret)
|
||||||
|
char *key;
|
||||||
|
char *ret;
|
||||||
|
{
|
||||||
|
char buf[1024]; /* big enough */
|
||||||
|
char *res;
|
||||||
|
FILE *fd;
|
||||||
|
char *mkey;
|
||||||
|
char *mval;
|
||||||
|
|
||||||
|
fd = fopen(PKFILE, "r");
|
||||||
|
if (fd == NULL)
|
||||||
|
return (0);
|
||||||
|
for (;;) {
|
||||||
|
res = fgets(buf, sizeof(buf), fd);
|
||||||
|
if (res == NULL) {
|
||||||
|
fclose(fd);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (res[0] == '#')
|
||||||
|
continue;
|
||||||
|
else if (res[0] == '+') {
|
||||||
|
#ifdef YP
|
||||||
|
char *PKMAP = "publickey.byname";
|
||||||
|
char *lookup;
|
||||||
|
char *domain;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
err = yp_get_default_domain(&domain);
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lookup = NULL;
|
||||||
|
err = yp_match(domain, PKMAP, key, strlen(key), &lookup, &len);
|
||||||
|
if (err) {
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("getpublicandprivatekey: match failed error %d\n", err));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lookup[len] = 0;
|
||||||
|
strcpy(ret, lookup);
|
||||||
|
fclose(fd);
|
||||||
|
free(lookup);
|
||||||
|
return (2);
|
||||||
|
#else /* YP */
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("Bad record in %s '+' -- NIS not supported in this library copy\n", PKFILE));
|
||||||
|
continue;
|
||||||
|
#endif /* YP */
|
||||||
|
} else {
|
||||||
|
mkey = strsep(&res, "\t ");
|
||||||
|
if (mkey == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Bad record in %s -- %s", PKFILE, buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
mval = strsep(&res, " \t#\n");
|
||||||
|
} while (mval != NULL && !*mval);
|
||||||
|
if (mval == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Bad record in %s val problem - %s", PKFILE, buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(mkey, key) == 0) {
|
||||||
|
strcpy(ret, mval);
|
||||||
|
fclose(fd);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getpublickey(netname, publickey)
|
||||||
|
const char *netname;
|
||||||
|
char *publickey;
|
||||||
|
{
|
||||||
|
if (__getpublickey_LOCAL != NULL)
|
||||||
|
return(__getpublickey_LOCAL(netname, publickey));
|
||||||
|
else
|
||||||
|
return(__getpublickey_real(netname, publickey));
|
||||||
|
}
|
||||||
332
libtirpc-1.3.1/src/getrpcent.c
Normal file
332
libtirpc-1.3.1/src/getrpcent.c
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1984 by Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#ifdef YP
|
||||||
|
#include <rpcsvc/yp_prot.h>
|
||||||
|
#include <rpcsvc/ypclnt.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
|
#include <libc_private.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GETRPCBYNAME || !HAVE_GETRPCBYNUMBER || \
|
||||||
|
!HAVE_SETRPCENT || !HAVE_ENDRPCENT || !HAVE_GETRPCENT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internet version.
|
||||||
|
*/
|
||||||
|
static struct rpcdata {
|
||||||
|
FILE *rpcf;
|
||||||
|
int stayopen;
|
||||||
|
#define MAXALIASES 35
|
||||||
|
char *rpc_aliases[MAXALIASES];
|
||||||
|
struct rpcent rpc;
|
||||||
|
char line[BUFSIZ+1];
|
||||||
|
#ifdef YP
|
||||||
|
char *domain;
|
||||||
|
char *current;
|
||||||
|
int currentlen;
|
||||||
|
#endif
|
||||||
|
} *rpcdata;
|
||||||
|
|
||||||
|
static struct rpcent *interpret(char *val, size_t len);
|
||||||
|
|
||||||
|
#ifdef YP
|
||||||
|
static int __yp_nomap = 0;
|
||||||
|
#endif /* YP */
|
||||||
|
|
||||||
|
#define RPCDB "/etc/rpc"
|
||||||
|
|
||||||
|
static struct rpcdata *_rpcdata(void);
|
||||||
|
|
||||||
|
static struct rpcdata *
|
||||||
|
_rpcdata()
|
||||||
|
{
|
||||||
|
struct rpcdata *d = rpcdata;
|
||||||
|
|
||||||
|
if (d == 0) {
|
||||||
|
d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
|
||||||
|
rpcdata = d;
|
||||||
|
}
|
||||||
|
return (d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !HAVE_GETRPCBYNUMBER
|
||||||
|
struct rpcent *
|
||||||
|
getrpcbynumber(number)
|
||||||
|
int number;
|
||||||
|
{
|
||||||
|
#ifdef YP
|
||||||
|
int reason;
|
||||||
|
char adrstr[16];
|
||||||
|
#endif
|
||||||
|
struct rpcent *p;
|
||||||
|
struct rpcdata *d = _rpcdata();
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
return (0);
|
||||||
|
#ifdef YP
|
||||||
|
if (!__yp_nomap && __yp_check(&d->domain)) {
|
||||||
|
sprintf(adrstr, "%d", number);
|
||||||
|
reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
|
||||||
|
&d->current, &d->currentlen);
|
||||||
|
switch(reason) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case YPERR_MAP:
|
||||||
|
__yp_nomap = 1;
|
||||||
|
goto no_yp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d->current[d->currentlen] = '\0';
|
||||||
|
p = interpret(d->current, d->currentlen);
|
||||||
|
(void) free(d->current);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
no_yp:
|
||||||
|
#endif /* YP */
|
||||||
|
|
||||||
|
setrpcent(0);
|
||||||
|
while ((p = getrpcent()) != NULL) {
|
||||||
|
if (p->r_number == number)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
endrpcent();
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_GETRPCBYNUMBER */
|
||||||
|
|
||||||
|
#if !HAVE_GETRPCBYNAME
|
||||||
|
struct rpcent *
|
||||||
|
getrpcbyname(name)
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
struct rpcent *rpc = NULL;
|
||||||
|
char **rp;
|
||||||
|
|
||||||
|
assert(name != NULL);
|
||||||
|
|
||||||
|
setrpcent(0);
|
||||||
|
while ((rpc = getrpcent()) != NULL) {
|
||||||
|
if (strcmp(rpc->r_name, name) == 0)
|
||||||
|
goto done;
|
||||||
|
for (rp = rpc->r_aliases; *rp != NULL; rp++) {
|
||||||
|
if (strcmp(*rp, name) == 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
endrpcent();
|
||||||
|
return (rpc);
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_GETRPCBYNAME */
|
||||||
|
|
||||||
|
#if !HAVE_SETRPCENT
|
||||||
|
void
|
||||||
|
setrpcent(f)
|
||||||
|
int f;
|
||||||
|
{
|
||||||
|
struct rpcdata *d = _rpcdata();
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
return;
|
||||||
|
#ifdef YP
|
||||||
|
if (!__yp_nomap && __yp_check(NULL)) {
|
||||||
|
if (d->current)
|
||||||
|
free(d->current);
|
||||||
|
d->current = NULL;
|
||||||
|
d->currentlen = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__yp_nomap = 0;
|
||||||
|
#endif /* YP */
|
||||||
|
if (d->rpcf == NULL)
|
||||||
|
d->rpcf = fopen(RPCDB, "r");
|
||||||
|
else
|
||||||
|
rewind(d->rpcf);
|
||||||
|
d->stayopen |= f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_ENDRPCENT
|
||||||
|
void
|
||||||
|
endrpcent()
|
||||||
|
{
|
||||||
|
struct rpcdata *d = _rpcdata();
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
return;
|
||||||
|
#ifdef YP
|
||||||
|
if (!__yp_nomap && __yp_check(NULL)) {
|
||||||
|
if (d->current && !d->stayopen)
|
||||||
|
free(d->current);
|
||||||
|
d->current = NULL;
|
||||||
|
d->currentlen = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__yp_nomap = 0;
|
||||||
|
#endif /* YP */
|
||||||
|
if (d->rpcf && !d->stayopen) {
|
||||||
|
fclose(d->rpcf);
|
||||||
|
d->rpcf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GETRPCENT
|
||||||
|
struct rpcent *
|
||||||
|
getrpcent()
|
||||||
|
{
|
||||||
|
struct rpcdata *d = _rpcdata();
|
||||||
|
#ifdef YP
|
||||||
|
struct rpcent *hp;
|
||||||
|
int reason;
|
||||||
|
char *val = NULL;
|
||||||
|
int vallen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
return(NULL);
|
||||||
|
#ifdef YP
|
||||||
|
if (!__yp_nomap && __yp_check(&d->domain)) {
|
||||||
|
if (d->current == NULL && d->currentlen == 0) {
|
||||||
|
reason = yp_first(d->domain, "rpc.bynumber",
|
||||||
|
&d->current, &d->currentlen,
|
||||||
|
&val, &vallen);
|
||||||
|
} else {
|
||||||
|
reason = yp_next(d->domain, "rpc.bynumber",
|
||||||
|
d->current, d->currentlen,
|
||||||
|
&d->current, &d->currentlen,
|
||||||
|
&val, &vallen);
|
||||||
|
}
|
||||||
|
switch(reason) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case YPERR_MAP:
|
||||||
|
__yp_nomap = 1;
|
||||||
|
goto no_yp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
val[vallen] = '\0';
|
||||||
|
hp = interpret(val, vallen);
|
||||||
|
(void) free(val);
|
||||||
|
return hp;
|
||||||
|
}
|
||||||
|
no_yp:
|
||||||
|
#endif /* YP */
|
||||||
|
if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
/* -1 so there is room to append a \n below */
|
||||||
|
if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
return (interpret(d->line, strlen(d->line)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct rpcent *
|
||||||
|
interpret(val, len)
|
||||||
|
char *val;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
struct rpcdata *d = _rpcdata();
|
||||||
|
char *p;
|
||||||
|
char *cp, **q;
|
||||||
|
|
||||||
|
assert(val != NULL);
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
return (0);
|
||||||
|
(void) strncpy(d->line, val, BUFSIZ);
|
||||||
|
d->line[BUFSIZ] = '\0';
|
||||||
|
p = d->line;
|
||||||
|
p[len] = '\n';
|
||||||
|
if (*p == '#')
|
||||||
|
return (getrpcent());
|
||||||
|
cp = strpbrk(p, "#\n");
|
||||||
|
if (cp == NULL)
|
||||||
|
return (getrpcent());
|
||||||
|
*cp = '\0';
|
||||||
|
cp = strpbrk(p, " \t");
|
||||||
|
if (cp == NULL)
|
||||||
|
return (getrpcent());
|
||||||
|
*cp++ = '\0';
|
||||||
|
/* THIS STUFF IS INTERNET SPECIFIC */
|
||||||
|
d->rpc.r_name = d->line;
|
||||||
|
while (*cp == ' ' || *cp == '\t')
|
||||||
|
cp++;
|
||||||
|
d->rpc.r_number = atoi(cp);
|
||||||
|
q = d->rpc.r_aliases = d->rpc_aliases;
|
||||||
|
cp = strpbrk(cp, " \t");
|
||||||
|
if (cp != NULL)
|
||||||
|
*cp++ = '\0';
|
||||||
|
while (cp && *cp) {
|
||||||
|
if (*cp == ' ' || *cp == '\t') {
|
||||||
|
cp++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (q < &(d->rpc_aliases[MAXALIASES - 1]))
|
||||||
|
*q++ = cp;
|
||||||
|
cp = strpbrk(cp, " \t");
|
||||||
|
if (cp != NULL)
|
||||||
|
*cp++ = '\0';
|
||||||
|
}
|
||||||
|
*q = NULL;
|
||||||
|
return (&d->rpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
66
libtirpc-1.3.1/src/getrpcport.c
Normal file
66
libtirpc-1.3.1/src/getrpcport.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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) 1985 by Sun Microsystems, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/pmap_clnt.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
getrpcport(host, prognum, versnum, proto)
|
||||||
|
char *host;
|
||||||
|
int prognum, versnum, proto;
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
struct hostent *hp;
|
||||||
|
|
||||||
|
assert(host != NULL);
|
||||||
|
|
||||||
|
if ((hp = gethostbyname(host)) == NULL)
|
||||||
|
return (0);
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = 0;
|
||||||
|
if (hp->h_length > sizeof(addr.sin_addr.s_addr))
|
||||||
|
hp->h_length = sizeof(addr.sin_addr.s_addr);
|
||||||
|
memcpy(&addr.sin_addr.s_addr, hp->h_addr, (size_t)hp->h_length);
|
||||||
|
/* Inconsistent interfaces need casts! :-( */
|
||||||
|
return (pmap_getport(&addr, (u_long)prognum, (u_long)versnum,
|
||||||
|
(u_int)proto));
|
||||||
|
}
|
||||||
446
libtirpc-1.3.1/src/key_call.c
Normal file
446
libtirpc-1.3.1/src/key_call.c
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
/*
|
||||||
|
* 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-1991 by Sun Microsystems Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* key_call.c, Interface to keyserver
|
||||||
|
*
|
||||||
|
* setsecretkey(key) - set your secret key
|
||||||
|
* encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
|
||||||
|
* decryptsessionkey(agent, deskey) - decrypt ditto
|
||||||
|
* gendeskey(deskey) - generate a secure des key
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <rpc/auth.h>
|
||||||
|
#include <rpc/auth_unix.h>
|
||||||
|
#include <rpc/key_prot.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netconfig.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
|
||||||
|
#define KEY_NRETRY 12 /* number of retries */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hack to allow the keyserver to use AUTH_DES (for authenticated
|
||||||
|
* NIS+ calls, for example). The only functions that get called
|
||||||
|
* are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
|
||||||
|
*
|
||||||
|
* The approach is to have the keyserver fill in pointers to local
|
||||||
|
* implementations of these functions, and to call those in key_call().
|
||||||
|
*/
|
||||||
|
|
||||||
|
cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;
|
||||||
|
cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;
|
||||||
|
des_block *(*__key_gendes_LOCAL)() = 0;
|
||||||
|
|
||||||
|
static int key_call( u_long, xdrproc_t, void *, xdrproc_t, void *);
|
||||||
|
|
||||||
|
int
|
||||||
|
key_setsecret(secretkey)
|
||||||
|
const char *secretkey;
|
||||||
|
{
|
||||||
|
keystatus status;
|
||||||
|
|
||||||
|
if (!key_call((u_long) KEY_SET, (xdrproc_t)xdr_keybuf,
|
||||||
|
(void *)secretkey,
|
||||||
|
(xdrproc_t)xdr_keystatus, &status)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_setsecret: set status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
|
||||||
|
* stored for the caller's effective uid; it returns 0 otherwise
|
||||||
|
*
|
||||||
|
* N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
|
||||||
|
* be using it, because it allows them to get the user's secret key.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
key_secretkey_is_set(void)
|
||||||
|
{
|
||||||
|
struct key_netstres kres;
|
||||||
|
|
||||||
|
memset((void*)&kres, 0, sizeof (kres));
|
||||||
|
if (key_call((u_long) KEY_NET_GET, (xdrproc_t)xdr_void, NULL,
|
||||||
|
(xdrproc_t)xdr_key_netstres, &kres) &&
|
||||||
|
(kres.status == KEY_SUCCESS) &&
|
||||||
|
(kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
|
||||||
|
/* avoid leaving secret key in memory */
|
||||||
|
memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_encryptsession_pk(remotename, remotekey, deskey)
|
||||||
|
char *remotename;
|
||||||
|
netobj *remotekey;
|
||||||
|
des_block *deskey;
|
||||||
|
{
|
||||||
|
cryptkeyarg2 arg;
|
||||||
|
cryptkeyres res;
|
||||||
|
|
||||||
|
arg.remotename = remotename;
|
||||||
|
arg.remotekey = *remotekey;
|
||||||
|
arg.deskey = *deskey;
|
||||||
|
if (!key_call((u_long)KEY_ENCRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg,
|
||||||
|
(xdrproc_t)xdr_cryptkeyres, &res)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (res.status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_encryptsession_pk: encrypt status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*deskey = res.cryptkeyres_u.deskey;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_decryptsession_pk(remotename, remotekey, deskey)
|
||||||
|
char *remotename;
|
||||||
|
netobj *remotekey;
|
||||||
|
des_block *deskey;
|
||||||
|
{
|
||||||
|
cryptkeyarg2 arg;
|
||||||
|
cryptkeyres res;
|
||||||
|
|
||||||
|
arg.remotename = remotename;
|
||||||
|
arg.remotekey = *remotekey;
|
||||||
|
arg.deskey = *deskey;
|
||||||
|
if (!key_call((u_long)KEY_DECRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg,
|
||||||
|
(xdrproc_t)xdr_cryptkeyres, &res)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (res.status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_decryptsession_pk: decrypt status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*deskey = res.cryptkeyres_u.deskey;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_encryptsession(remotename, deskey)
|
||||||
|
const char *remotename;
|
||||||
|
des_block *deskey;
|
||||||
|
{
|
||||||
|
cryptkeyarg arg;
|
||||||
|
cryptkeyres res;
|
||||||
|
|
||||||
|
arg.remotename = (char *) remotename;
|
||||||
|
arg.deskey = *deskey;
|
||||||
|
if (!key_call((u_long)KEY_ENCRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg,
|
||||||
|
(xdrproc_t)xdr_cryptkeyres, &res)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (res.status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_encryptsession: encrypt status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*deskey = res.cryptkeyres_u.deskey;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_decryptsession(remotename, deskey)
|
||||||
|
const char *remotename;
|
||||||
|
des_block *deskey;
|
||||||
|
{
|
||||||
|
cryptkeyarg arg;
|
||||||
|
cryptkeyres res;
|
||||||
|
|
||||||
|
arg.remotename = (char *) remotename;
|
||||||
|
arg.deskey = *deskey;
|
||||||
|
if (!key_call((u_long)KEY_DECRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg,
|
||||||
|
(xdrproc_t)xdr_cryptkeyres, &res)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (res.status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_decryptsession: decrypt status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*deskey = res.cryptkeyres_u.deskey;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_gendes(key)
|
||||||
|
des_block *key;
|
||||||
|
{
|
||||||
|
if (!key_call((u_long)KEY_GEN, (xdrproc_t)xdr_void, NULL,
|
||||||
|
(xdrproc_t)xdr_des_block, key)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
key_setnet(arg)
|
||||||
|
struct key_netstarg *arg;
|
||||||
|
{
|
||||||
|
keystatus status;
|
||||||
|
|
||||||
|
|
||||||
|
if (!key_call((u_long) KEY_NET_PUT, (xdrproc_t)xdr_key_netstarg, arg,
|
||||||
|
(xdrproc_t)xdr_keystatus, &status)){
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_setnet: key_setnet status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
key_get_conv(pkey, deskey)
|
||||||
|
char *pkey;
|
||||||
|
des_block *deskey;
|
||||||
|
{
|
||||||
|
cryptkeyres res;
|
||||||
|
|
||||||
|
if (!key_call((u_long) KEY_GET_CONV, (xdrproc_t)xdr_keybuf, pkey,
|
||||||
|
(xdrproc_t)xdr_cryptkeyres, &res)) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (res.status != KEY_SUCCESS) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("key_get_conv: get_conv status is nonzero"));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*deskey = res.cryptkeyres_u.deskey;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct key_call_private {
|
||||||
|
CLIENT *client; /* Client handle */
|
||||||
|
pid_t pid; /* process-id at moment of creation */
|
||||||
|
uid_t uid; /* user-id at last authorization */
|
||||||
|
};
|
||||||
|
static struct key_call_private *key_call_private_main = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
key_call_destroy(void *vp)
|
||||||
|
{
|
||||||
|
struct key_call_private *kcp = (struct key_call_private *)vp;
|
||||||
|
|
||||||
|
if (kcp) {
|
||||||
|
if (kcp->client)
|
||||||
|
clnt_destroy(kcp->client);
|
||||||
|
free(kcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep the handle cached. This call may be made quite often.
|
||||||
|
*/
|
||||||
|
static CLIENT *
|
||||||
|
getkeyserv_handle(vers)
|
||||||
|
int vers;
|
||||||
|
{
|
||||||
|
void *localhandle;
|
||||||
|
struct netconfig *nconf;
|
||||||
|
struct netconfig *tpconf;
|
||||||
|
struct key_call_private *kcp = key_call_private_main;
|
||||||
|
struct timeval wait_time;
|
||||||
|
struct utsname u;
|
||||||
|
int fd;
|
||||||
|
extern thread_key_t key_call_key;
|
||||||
|
extern mutex_t tsd_lock;
|
||||||
|
|
||||||
|
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
|
||||||
|
#define TOTAL_TRIES 5 /* Number of tries */
|
||||||
|
|
||||||
|
if (key_call_key == -1) {
|
||||||
|
mutex_lock(&tsd_lock);
|
||||||
|
if (key_call_key == -1)
|
||||||
|
thr_keycreate(&key_call_key, key_call_destroy);
|
||||||
|
mutex_unlock(&tsd_lock);
|
||||||
|
}
|
||||||
|
kcp = (struct key_call_private *)thr_getspecific(key_call_key);
|
||||||
|
if (kcp == (struct key_call_private *)NULL) {
|
||||||
|
kcp = (struct key_call_private *)malloc(sizeof (*kcp));
|
||||||
|
if (kcp == (struct key_call_private *)NULL) {
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
thr_setspecific(key_call_key, (void *) kcp);
|
||||||
|
kcp->client = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if pid has changed, destroy client and rebuild */
|
||||||
|
if (kcp->client != NULL && kcp->pid != getpid()) {
|
||||||
|
clnt_destroy(kcp->client);
|
||||||
|
kcp->client = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kcp->client != NULL) {
|
||||||
|
/* if uid has changed, build client handle again */
|
||||||
|
if (kcp->uid != geteuid()) {
|
||||||
|
kcp->uid = geteuid();
|
||||||
|
auth_destroy(kcp->client->cl_auth);
|
||||||
|
kcp->client->cl_auth =
|
||||||
|
authsys_create("", kcp->uid, 0, 0, NULL);
|
||||||
|
if (kcp->client->cl_auth == NULL) {
|
||||||
|
clnt_destroy(kcp->client);
|
||||||
|
kcp->client = NULL;
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Change the version number to the new one */
|
||||||
|
clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
|
||||||
|
return (kcp->client);
|
||||||
|
}
|
||||||
|
if (!(localhandle = setnetconfig())) {
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
tpconf = NULL;
|
||||||
|
if (uname(&u) == -1) {
|
||||||
|
endnetconfig(localhandle);
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
while ((nconf = getnetconfig(localhandle)) != NULL) {
|
||||||
|
if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
|
||||||
|
/*
|
||||||
|
* We use COTS_ORD here so that the caller can
|
||||||
|
* find out immediately if the server is dead.
|
||||||
|
*/
|
||||||
|
if (nconf->nc_semantics == NC_TPI_COTS_ORD) {
|
||||||
|
kcp->client = clnt_tp_create(u.nodename,
|
||||||
|
KEY_PROG, vers, nconf);
|
||||||
|
if (kcp->client)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
tpconf = nconf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((kcp->client == (CLIENT *) NULL) && (tpconf))
|
||||||
|
/* Now, try the CLTS or COTS loopback transport */
|
||||||
|
kcp->client = clnt_tp_create(u.nodename,
|
||||||
|
KEY_PROG, vers, tpconf);
|
||||||
|
endnetconfig(localhandle);
|
||||||
|
|
||||||
|
if (kcp->client == (CLIENT *) NULL) {
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
kcp->uid = geteuid();
|
||||||
|
kcp->pid = getpid();
|
||||||
|
kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
|
||||||
|
if (kcp->client->cl_auth == NULL) {
|
||||||
|
clnt_destroy(kcp->client);
|
||||||
|
kcp->client = NULL;
|
||||||
|
return ((CLIENT *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
|
||||||
|
wait_time.tv_usec = 0;
|
||||||
|
(void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,
|
||||||
|
(char *)&wait_time);
|
||||||
|
if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))
|
||||||
|
fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
|
||||||
|
|
||||||
|
return (kcp->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns 0 on failure, 1 on success */
|
||||||
|
|
||||||
|
static int
|
||||||
|
key_call(proc, xdr_arg, arg, xdr_rslt, rslt)
|
||||||
|
u_long proc;
|
||||||
|
xdrproc_t xdr_arg;
|
||||||
|
void *arg;
|
||||||
|
xdrproc_t xdr_rslt;
|
||||||
|
void *rslt;
|
||||||
|
{
|
||||||
|
CLIENT *clnt;
|
||||||
|
struct timeval wait_time;
|
||||||
|
|
||||||
|
if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
|
||||||
|
cryptkeyres *res;
|
||||||
|
res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);
|
||||||
|
*(cryptkeyres*)rslt = *res;
|
||||||
|
return (1);
|
||||||
|
} else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
|
||||||
|
cryptkeyres *res;
|
||||||
|
res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);
|
||||||
|
*(cryptkeyres*)rslt = *res;
|
||||||
|
return (1);
|
||||||
|
} else if (proc == KEY_GEN && __key_gendes_LOCAL) {
|
||||||
|
des_block *res;
|
||||||
|
res = (*__key_gendes_LOCAL)(geteuid(), 0);
|
||||||
|
*(des_block*)rslt = *res;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
|
||||||
|
(proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
|
||||||
|
(proc == KEY_GET_CONV))
|
||||||
|
clnt = getkeyserv_handle(2); /* talk to version 2 */
|
||||||
|
else
|
||||||
|
clnt = getkeyserv_handle(1); /* talk to version 1 */
|
||||||
|
|
||||||
|
if (clnt == NULL) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_time.tv_sec = TOTAL_TIMEOUT;
|
||||||
|
wait_time.tv_usec = 0;
|
||||||
|
|
||||||
|
if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
|
||||||
|
wait_time) == RPC_SUCCESS) {
|
||||||
|
return (1);
|
||||||
|
} else {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
170
libtirpc-1.3.1/src/key_prot_xdr.c
Normal file
170
libtirpc-1.3.1/src/key_prot_xdr.c
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Please do not edit this file.
|
||||||
|
* It was generated using rpcgen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rpc/key_prot.h>
|
||||||
|
/*
|
||||||
|
* 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) 1990, 1991 Sun Microsystems, Inc. */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compiled from key_prot.x using rpcgen.
|
||||||
|
* DO NOT EDIT THIS FILE!
|
||||||
|
* This is NOT source code!
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_keystatus(register XDR *xdrs, keystatus *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_enum(xdrs, (enum_t *)objp))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_keybuf(register XDR *xdrs, keybuf objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_opaque(xdrs, objp, HEXKEYBYTES))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_netnamestr(register XDR *xdrs, netnamestr *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_string(xdrs, objp, MAXNETNAMELEN))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_cryptkeyarg(register XDR *xdrs, cryptkeyarg *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_netnamestr(xdrs, &objp->remotename))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_des_block(xdrs, &objp->deskey))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_cryptkeyarg2(register XDR *xdrs, cryptkeyarg2 *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_netnamestr(xdrs, &objp->remotename))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_netobj(xdrs, &objp->remotekey))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_des_block(xdrs, &objp->deskey))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_cryptkeyres(register XDR *xdrs, cryptkeyres *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_keystatus(xdrs, &objp->status))
|
||||||
|
return (FALSE);
|
||||||
|
switch (objp->status) {
|
||||||
|
case KEY_SUCCESS:
|
||||||
|
if (!xdr_des_block(xdrs, &objp->cryptkeyres_u.deskey))
|
||||||
|
return (FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_unixcred(register XDR *xdrs, unixcred *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_u_int(xdrs, &objp->uid))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_u_int(xdrs, &objp->gid))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_array(xdrs, (char **)&objp->gids.gids_val, (u_int *) &objp->gids.gids_len, MAXGIDS,
|
||||||
|
sizeof (u_int), (xdrproc_t) xdr_u_int))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_getcredres(register XDR *xdrs, getcredres *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_keystatus(xdrs, &objp->status))
|
||||||
|
return (FALSE);
|
||||||
|
switch (objp->status) {
|
||||||
|
case KEY_SUCCESS:
|
||||||
|
if (!xdr_unixcred(xdrs, &objp->getcredres_u.cred))
|
||||||
|
return (FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_key_netstarg(register XDR *xdrs, key_netstarg *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_keybuf(xdrs, objp->st_priv_key))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_keybuf(xdrs, objp->st_pub_key))
|
||||||
|
return (FALSE);
|
||||||
|
if (!xdr_netnamestr(xdrs, &objp->st_netname))
|
||||||
|
return (FALSE);
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t
|
||||||
|
xdr_key_netstres(register XDR *xdrs, key_netstres *objp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!xdr_keystatus(xdrs, &objp->status))
|
||||||
|
return (FALSE);
|
||||||
|
switch (objp->status) {
|
||||||
|
case KEY_SUCCESS:
|
||||||
|
if (!xdr_key_netstarg(xdrs, &objp->key_netstres_u.knet))
|
||||||
|
return (FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
335
libtirpc-1.3.1/src/libtirpc.map
Normal file
335
libtirpc-1.3.1/src/libtirpc.map
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
TIRPC_0.3.0 {
|
||||||
|
global:
|
||||||
|
# __*
|
||||||
|
__rpc_createerr;
|
||||||
|
__rpc_dtbsize;
|
||||||
|
__rpc_endconf;
|
||||||
|
__rpc_fd2sockinfo;
|
||||||
|
__rpc_fixup_addr;
|
||||||
|
__rpc_get_a_size;
|
||||||
|
__rpc_get_local_uid;
|
||||||
|
__rpc_get_t_size;
|
||||||
|
__rpc_getconf;
|
||||||
|
__rpc_getconfip;
|
||||||
|
__rpc_nconf2fd;
|
||||||
|
__rpc_nconf2fd_flags;
|
||||||
|
__rpc_nconf2sockinfo;
|
||||||
|
__rpc_rawcombuf;
|
||||||
|
__rpc_seman2socktype;
|
||||||
|
__rpc_setconf;
|
||||||
|
__rpc_sockinfo2netid;
|
||||||
|
__rpc_sockisbound;
|
||||||
|
__rpc_socktype2seman;
|
||||||
|
__rpc_taddr2uaddr_af;
|
||||||
|
__rpc_uaddr2taddr_af;
|
||||||
|
__rpcgettp;
|
||||||
|
|
||||||
|
# _*
|
||||||
|
_authenticate;
|
||||||
|
_get_next_token;
|
||||||
|
_gss_authenticate;
|
||||||
|
_null_auth;
|
||||||
|
_rpc_dtablesize;
|
||||||
|
_seterr_reply;
|
||||||
|
_svcauth_none;
|
||||||
|
_svcauth_short;
|
||||||
|
_svcauth_unix;
|
||||||
|
_svcauth_gss;
|
||||||
|
|
||||||
|
# a*
|
||||||
|
authdes_create;
|
||||||
|
authdes_seccreate;
|
||||||
|
authgss_create;
|
||||||
|
authgss_create_default;
|
||||||
|
authgss_free_private_data;
|
||||||
|
authgss_get_private_data;
|
||||||
|
authgss_service;
|
||||||
|
authnone_create;
|
||||||
|
authunix_create;
|
||||||
|
authunix_create_default;
|
||||||
|
|
||||||
|
# b*
|
||||||
|
bindresvport;
|
||||||
|
bindresvport_sa;
|
||||||
|
|
||||||
|
# c*
|
||||||
|
callrpc;
|
||||||
|
cbc_crypt;
|
||||||
|
clnt_broadcast;
|
||||||
|
clnt_create;
|
||||||
|
clnt_create_timed;
|
||||||
|
clnt_create_vers;
|
||||||
|
clnt_create_vers_timed;
|
||||||
|
clnt_dg_create;
|
||||||
|
clnt_pcreateerror;
|
||||||
|
clnt_perrno;
|
||||||
|
clnt_perror;
|
||||||
|
clnt_raw_create;
|
||||||
|
clnt_spcreateerror;
|
||||||
|
clnt_sperrno;
|
||||||
|
clnt_sperror;
|
||||||
|
clnt_tli_create;
|
||||||
|
clnt_tp_create;
|
||||||
|
clnt_tp_create_timed;
|
||||||
|
clnt_vc_create;
|
||||||
|
clntraw_create;
|
||||||
|
clnttcp_create;
|
||||||
|
clntudp_bufcreate;
|
||||||
|
clntudp_create;
|
||||||
|
clntunix_create;
|
||||||
|
|
||||||
|
# e*
|
||||||
|
ecb_crypt;
|
||||||
|
endnetconfig;
|
||||||
|
endnetpath;
|
||||||
|
endrpcent;
|
||||||
|
|
||||||
|
# f*
|
||||||
|
freenetconfigent;
|
||||||
|
|
||||||
|
# g*
|
||||||
|
get_myaddress;
|
||||||
|
getnetconfig;
|
||||||
|
getnetconfigent;
|
||||||
|
getnetpath;
|
||||||
|
getrpcent;
|
||||||
|
getrpcbynumber;
|
||||||
|
getrpcbyname;
|
||||||
|
getrpcport;
|
||||||
|
gss_log_debug;
|
||||||
|
gss_log_hexdump;
|
||||||
|
gss_log_status;
|
||||||
|
|
||||||
|
# n*
|
||||||
|
nc_perror;
|
||||||
|
nc_sperror;
|
||||||
|
|
||||||
|
# p*
|
||||||
|
pmap_getmaps;
|
||||||
|
pmap_getport;
|
||||||
|
pmap_rmtcall;
|
||||||
|
pmap_set;
|
||||||
|
pmap_unset;
|
||||||
|
|
||||||
|
# r*
|
||||||
|
registerrpc;
|
||||||
|
rpc_broadcast;
|
||||||
|
rpc_broadcast_exp;
|
||||||
|
rpc_call;
|
||||||
|
rpc_control;
|
||||||
|
rpc_createerr;
|
||||||
|
rpc_gss_get_error;
|
||||||
|
rpc_gss_get_mech_info;
|
||||||
|
rpc_gss_get_mechanisms;
|
||||||
|
rpc_gss_get_principal_name;
|
||||||
|
rpc_gss_get_versions;
|
||||||
|
rpc_gss_getcred;
|
||||||
|
rpc_gss_is_installed;
|
||||||
|
rpc_gss_max_data_length;
|
||||||
|
rpc_gss_mech_to_oid;
|
||||||
|
rpc_gss_qop_to_num;
|
||||||
|
rpc_gss_seccreate;
|
||||||
|
rpc_gss_set_callback;
|
||||||
|
rpc_gss_set_defaults;
|
||||||
|
rpc_gss_set_svc_name;
|
||||||
|
rpc_gss_svc_max_data_length;
|
||||||
|
rpc_nullproc;
|
||||||
|
rpc_reg;
|
||||||
|
rpcb_getaddr;
|
||||||
|
rpcb_getmaps;
|
||||||
|
rpcb_gettime;
|
||||||
|
rpcb_rmtcall;
|
||||||
|
rpcb_set;
|
||||||
|
rpcb_taddr2uaddr;
|
||||||
|
rpcb_uaddr2taddr;
|
||||||
|
rpcb_unset;
|
||||||
|
|
||||||
|
# s*
|
||||||
|
setnetconfig;
|
||||||
|
setnetpath;
|
||||||
|
setrpcent;
|
||||||
|
svc_auth_reg;
|
||||||
|
svc_create;
|
||||||
|
svc_dg_create;
|
||||||
|
svc_dg_enablecache;
|
||||||
|
svc_exit;
|
||||||
|
svc_fd_create;
|
||||||
|
svc_fdset;
|
||||||
|
svc_getreq;
|
||||||
|
svc_getreq_common;
|
||||||
|
svc_getreq_poll;
|
||||||
|
svc_getreqset;
|
||||||
|
svc_maxfd;
|
||||||
|
svc_raw_create;
|
||||||
|
svc_reg;
|
||||||
|
svc_register;
|
||||||
|
svc_run;
|
||||||
|
svc_sendreply;
|
||||||
|
svc_tli_create;
|
||||||
|
svc_tp_create;
|
||||||
|
svc_unreg;
|
||||||
|
svc_unregister;
|
||||||
|
svc_vc_create;
|
||||||
|
svcerr_auth;
|
||||||
|
svcerr_decode;
|
||||||
|
svcerr_noproc;
|
||||||
|
svcerr_noprog;
|
||||||
|
svcerr_progvers;
|
||||||
|
svcerr_systemerr;
|
||||||
|
svcerr_weakauth;
|
||||||
|
svcfd_create;
|
||||||
|
svcraw_create;
|
||||||
|
svctcp_create;
|
||||||
|
svcudp_bufcreate;
|
||||||
|
svcudp_create;
|
||||||
|
svcunix_create;
|
||||||
|
svcunixfd_create;
|
||||||
|
|
||||||
|
# t*
|
||||||
|
taddr2uaddr;
|
||||||
|
|
||||||
|
# u*
|
||||||
|
uaddr2taddr;
|
||||||
|
|
||||||
|
# x*
|
||||||
|
xdr_accepted_reply;
|
||||||
|
xdr_array;
|
||||||
|
xdr_authdes_cred;
|
||||||
|
xdr_authdes_verf;
|
||||||
|
xdr_authunix_parms;
|
||||||
|
xdr_bool;
|
||||||
|
xdr_bytes;
|
||||||
|
xdr_callhdr; xdr_callmsg;
|
||||||
|
xdr_char;
|
||||||
|
xdr_des_block;
|
||||||
|
xdr_double;
|
||||||
|
xdr_enum;
|
||||||
|
xdr_float;
|
||||||
|
xdr_free;
|
||||||
|
xdr_hyper;
|
||||||
|
xdr_int16_t;
|
||||||
|
xdr_int32_t;
|
||||||
|
xdr_int64_t;
|
||||||
|
xdr_int8_t;
|
||||||
|
xdr_int;
|
||||||
|
xdr_long;
|
||||||
|
xdr_longlong_t;
|
||||||
|
xdr_netbuf;
|
||||||
|
xdr_netobj;
|
||||||
|
xdr_opaque;
|
||||||
|
xdr_opaque_auth;
|
||||||
|
xdr_pmap;
|
||||||
|
xdr_pmaplist;
|
||||||
|
xdr_pmaplist_ptr;
|
||||||
|
xdr_pointer;
|
||||||
|
xdr_quad_t;
|
||||||
|
xdr_reference;
|
||||||
|
xdr_rejected_reply;
|
||||||
|
xdr_replymsg;
|
||||||
|
xdr_rmtcall_args;
|
||||||
|
xdr_rmtcallres;
|
||||||
|
xdr_rpc_gss_cred;
|
||||||
|
xdr_rpc_gss_data;
|
||||||
|
xdr_rpc_gss_init_args;
|
||||||
|
xdr_rpc_gss_init_res;
|
||||||
|
xdr_rpcb;
|
||||||
|
xdr_rpcb_entry;
|
||||||
|
xdr_rpcb_entry_list_ptr;
|
||||||
|
xdr_rpcb_rmtcallargs;
|
||||||
|
xdr_rpcb_rmtcallres;
|
||||||
|
xdr_rpcb_stat;
|
||||||
|
xdr_rpcb_stat_byvers;
|
||||||
|
xdr_rpcblist;
|
||||||
|
xdr_rpcblist_ptr;
|
||||||
|
xdr_rpcbs_addrlist;
|
||||||
|
xdr_rpcbs_addrlist_ptr;
|
||||||
|
xdr_rpcbs_proc;
|
||||||
|
xdr_rpcbs_rmtcalllist;
|
||||||
|
xdr_rpcbs_rmtcalllist_ptr;
|
||||||
|
xdr_short;
|
||||||
|
xdr_string;
|
||||||
|
xdr_u_char;
|
||||||
|
xdr_u_hyper;
|
||||||
|
xdr_u_int16_t;
|
||||||
|
xdr_u_int32_t;
|
||||||
|
xdr_u_int64_t;
|
||||||
|
xdr_u_int8_t;
|
||||||
|
xdr_u_int;
|
||||||
|
xdr_u_long;
|
||||||
|
xdr_u_longlong_t;
|
||||||
|
xdr_u_quad_t;
|
||||||
|
xdr_u_short;
|
||||||
|
xdr_uint16_t;
|
||||||
|
xdr_uint32_t;
|
||||||
|
xdr_uint64_t;
|
||||||
|
xdr_uint8_t;
|
||||||
|
xdr_union;
|
||||||
|
xdr_vector;
|
||||||
|
xdr_void;
|
||||||
|
xdr_wrapstring;
|
||||||
|
xdrmem_create;
|
||||||
|
xdrrec_create;
|
||||||
|
xdrrec_endofrecord;
|
||||||
|
xdrrec_eof;
|
||||||
|
xdrrec_skiprecord;
|
||||||
|
xdrstdio_create;
|
||||||
|
xprt_register;
|
||||||
|
xprt_unregister;
|
||||||
|
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
||||||
|
|
||||||
|
TIRPC_0.3.1 {
|
||||||
|
svcauth_gss_get_principal;
|
||||||
|
svcauth_gss_set_svc_name;
|
||||||
|
} TIRPC_0.3.0;
|
||||||
|
|
||||||
|
TIRPC_0.3.2 {
|
||||||
|
getnetname;
|
||||||
|
getpublicandprivatekey;
|
||||||
|
getpublickey;
|
||||||
|
host2netname;
|
||||||
|
key_call_destroy;
|
||||||
|
key_decryptsession;
|
||||||
|
key_decryptsession_pk;
|
||||||
|
key_encryptsession;
|
||||||
|
key_encryptsession_pk;
|
||||||
|
key_gendes;
|
||||||
|
key_get_conv;
|
||||||
|
key_setsecret;
|
||||||
|
key_secretkey_is_set;
|
||||||
|
key_setnet;
|
||||||
|
netname2host;
|
||||||
|
netname2user;
|
||||||
|
rtime;
|
||||||
|
user2netname;
|
||||||
|
xdr_cryptkeyarg;
|
||||||
|
xdr_cryptkeyarg2;
|
||||||
|
xdr_cryptkeyres;
|
||||||
|
xdr_getcredres;
|
||||||
|
xdr_key_netstarg;
|
||||||
|
xdr_key_netstres;
|
||||||
|
xdr_keybuf;
|
||||||
|
xdr_keystatus;
|
||||||
|
xdr_netnamestr;
|
||||||
|
xdr_unixcred;
|
||||||
|
} TIRPC_0.3.1;
|
||||||
|
|
||||||
|
TIRPC_0.3.3 {
|
||||||
|
__getpublickey_LOCAL;
|
||||||
|
__key_decryptsession_pk_LOCAL;
|
||||||
|
__key_encryptsession_pk_LOCAL;
|
||||||
|
__key_gendes_LOCAL;
|
||||||
|
xdr_sizeof;
|
||||||
|
authdes_pk_create;
|
||||||
|
svc_pollfd;
|
||||||
|
svc_max_pollfd;
|
||||||
|
} TIRPC_0.3.2;
|
||||||
|
|
||||||
|
TIRPC_PRIVATE {
|
||||||
|
global:
|
||||||
|
__libc_clntudp_bufcreate;
|
||||||
|
# private, but used by rpcbind:
|
||||||
|
__svc_clean_idle; svc_auth_none; libtirpc_set_debug;
|
||||||
|
};
|
||||||
153
libtirpc-1.3.1/src/mt_misc.c
Normal file
153
libtirpc-1.3.1/src/mt_misc.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <reentrant.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* protects the services list (svc.c) */
|
||||||
|
pthread_rwlock_t svc_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects svc_fdset and the xports[] array */
|
||||||
|
pthread_rwlock_t svc_fd_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects the RPCBIND address cache */
|
||||||
|
pthread_rwlock_t rpcbaddr_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects authdes cache (svcauth_des.c) */
|
||||||
|
pthread_mutex_t authdes_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serializes authdes ops initializations */
|
||||||
|
pthread_mutex_t authdes_ops_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects des stats list */
|
||||||
|
pthread_mutex_t svcauthdesstats_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* auth_none.c serialization */
|
||||||
|
pthread_mutex_t authnone_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects the Auths list (svc_auth.c) */
|
||||||
|
pthread_mutex_t authsvc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects client-side fd lock array */
|
||||||
|
pthread_mutex_t clnt_fd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* clnt_raw.c serialization */
|
||||||
|
pthread_mutex_t clntraw_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* domainname and domain_fd (getdname.c) and default_domain (rpcdname.c) */
|
||||||
|
pthread_mutex_t dname_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* dupreq variables (svc_dg.c) */
|
||||||
|
pthread_mutex_t dupreq_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects first_time and hostname (key_call.c) */
|
||||||
|
pthread_mutex_t keyserv_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serializes rpc_trace() (rpc_trace.c) */
|
||||||
|
pthread_mutex_t libnsl_trace_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* loopnconf (rpcb_clnt.c) */
|
||||||
|
pthread_mutex_t loopnconf_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serializes ops initializations */
|
||||||
|
pthread_mutex_t ops_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects ``port'' static in bindresvport() */
|
||||||
|
pthread_mutex_t portnum_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects proglst list (svc_simple.c) */
|
||||||
|
pthread_mutex_t proglst_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serializes clnt_com_create() (rpc_soc.c) */
|
||||||
|
pthread_mutex_t rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* svc_raw.c serialization */
|
||||||
|
pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects TSD key creation */
|
||||||
|
pthread_mutex_t tsd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects RPCSEC GSS callback list */
|
||||||
|
pthread_mutex_t svcauth_cb_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serialize updates to AUTH ref count */
|
||||||
|
pthread_mutex_t auth_ref_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects RPCSEC GSS cache */
|
||||||
|
pthread_mutex_t svcauth_gss_cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* Library global tsd keys */
|
||||||
|
thread_key_t clnt_broadcast_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t rpc_call_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t tcp_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t udp_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t nc_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t rce_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t rg_key = KEY_INITIALIZER;
|
||||||
|
thread_key_t key_call_key = KEY_INITIALIZER;
|
||||||
|
|
||||||
|
/* xprtlist (svc_generic.c) */
|
||||||
|
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* serializes calls to public key routines */
|
||||||
|
pthread_mutex_t serialize_pkey = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects global variables ni and nc_file (getnetconfig.c) */
|
||||||
|
pthread_mutex_t nc_db_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects static port and startport (bindresvport.c) */
|
||||||
|
pthread_mutex_t port_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/* protects static disrupt (clnt_vc.c) */
|
||||||
|
pthread_mutex_t disrupt_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
#undef rpc_createerr
|
||||||
|
|
||||||
|
struct rpc_createerr rpc_createerr;
|
||||||
|
|
||||||
|
struct rpc_createerr *
|
||||||
|
__rpc_createerr()
|
||||||
|
{
|
||||||
|
struct rpc_createerr *rce_addr;
|
||||||
|
|
||||||
|
mutex_lock(&tsd_lock);
|
||||||
|
if (rce_key == KEY_INITIALIZER)
|
||||||
|
thr_keycreate(&rce_key, free);
|
||||||
|
mutex_unlock(&tsd_lock);
|
||||||
|
|
||||||
|
rce_addr = (struct rpc_createerr *)thr_getspecific(rce_key);
|
||||||
|
if (!rce_addr) {
|
||||||
|
rce_addr = (struct rpc_createerr *)
|
||||||
|
malloc(sizeof (struct rpc_createerr));
|
||||||
|
if (!rce_addr ||
|
||||||
|
thr_setspecific(rce_key, (void *) rce_addr) != 0) {
|
||||||
|
if (rce_addr)
|
||||||
|
free(rce_addr);
|
||||||
|
return (&rpc_createerr);
|
||||||
|
}
|
||||||
|
memset(rce_addr, 0, sizeof (struct rpc_createerr));
|
||||||
|
}
|
||||||
|
return (rce_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tsd_key_delete(void)
|
||||||
|
{
|
||||||
|
if (clnt_broadcast_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(clnt_broadcast_key);
|
||||||
|
if (rpc_call_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(rpc_call_key);
|
||||||
|
if (tcp_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(tcp_key);
|
||||||
|
if (udp_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(udp_key);
|
||||||
|
if (nc_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(nc_key);
|
||||||
|
if (rce_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(rce_key);
|
||||||
|
if (rg_key != KEY_INITIALIZER)
|
||||||
|
pthread_key_delete(rce_key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
143
libtirpc-1.3.1/src/netname.c
Normal file
143
libtirpc-1.3.1/src/netname.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* netname utility routines
|
||||||
|
* convert from unix names to network names and vice-versa
|
||||||
|
* This module is operating system dependent!
|
||||||
|
* What we define here will work with any unix system that has adopted
|
||||||
|
* the sun NIS domain architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
#ifdef YP
|
||||||
|
#include <rpcsvc/yp_prot.h>
|
||||||
|
#include <rpcsvc/ypclnt.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 256
|
||||||
|
#endif
|
||||||
|
#ifndef NGROUPS
|
||||||
|
#define NGROUPS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
|
||||||
|
|
||||||
|
#define TYPE_SIGNED(type) (((type) -1) < 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 302 / 1000 is log10(2.0) rounded up.
|
||||||
|
** Subtract one for the sign bit if the type is signed;
|
||||||
|
** add one for integer division truncation;
|
||||||
|
** add one more for a minus sign if the type is signed.
|
||||||
|
*/
|
||||||
|
#define INT_STRLEN_MAXIMUM(type) \
|
||||||
|
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
|
||||||
|
|
||||||
|
static char *OPSYS = "unix";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out my fully qualified network name
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
getnetname(name)
|
||||||
|
char name[MAXNETNAMELEN+1];
|
||||||
|
{
|
||||||
|
uid_t uid;
|
||||||
|
|
||||||
|
uid = geteuid();
|
||||||
|
if (uid == 0) {
|
||||||
|
return (host2netname(name, (char *) NULL, (char *) NULL));
|
||||||
|
} else {
|
||||||
|
return (user2netname(name, uid, (char *) NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert unix cred to network-name
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
user2netname(netname, uid, domain)
|
||||||
|
char netname[MAXNETNAMELEN + 1];
|
||||||
|
const uid_t uid;
|
||||||
|
const char *domain;
|
||||||
|
{
|
||||||
|
char *dfltdom;
|
||||||
|
|
||||||
|
if (domain == NULL) {
|
||||||
|
if (__rpc_get_default_domain(&dfltdom) != 0) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
domain = dfltdom;
|
||||||
|
}
|
||||||
|
if (strlen(domain) + 1 + INT_STRLEN_MAXIMUM(u_long) + 1 + strlen(OPSYS) > MAXNETNAMELEN) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
(void) sprintf(netname, "%s.%ld@%s", OPSYS, (u_long)uid, domain);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert host to network-name
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
host2netname(netname, host, domain)
|
||||||
|
char netname[MAXNETNAMELEN + 1];
|
||||||
|
const char *host;
|
||||||
|
const char *domain;
|
||||||
|
{
|
||||||
|
char *dfltdom;
|
||||||
|
char hostname[MAXHOSTNAMELEN+1];
|
||||||
|
|
||||||
|
if (domain == NULL) {
|
||||||
|
if (__rpc_get_default_domain(&dfltdom) != 0) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
domain = dfltdom;
|
||||||
|
}
|
||||||
|
if (host == NULL) {
|
||||||
|
(void) gethostname(hostname, sizeof(hostname));
|
||||||
|
host = hostname;
|
||||||
|
}
|
||||||
|
if (strlen(domain) + 1 + strlen(host) + 1 + strlen(OPSYS) > MAXNETNAMELEN) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
(void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
322
libtirpc-1.3.1/src/netnamer.c
Normal file
322
libtirpc-1.3.1/src/netnamer.c
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* netname utility routines convert from unix names to network names and
|
||||||
|
* vice-versa This module is operating system dependent! What we define here
|
||||||
|
* will work with any unix system that has adopted the sun NIS domain
|
||||||
|
* architecture.
|
||||||
|
*/
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <rpc/rpc.h>
|
||||||
|
#include "rpc_com.h"
|
||||||
|
#ifdef YP
|
||||||
|
#include <rpcsvc/yp_prot.h>
|
||||||
|
#include <rpcsvc/ypclnt.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static char *OPSYS = "unix";
|
||||||
|
#ifdef YP
|
||||||
|
static char *NETID = "netid.byname";
|
||||||
|
#endif
|
||||||
|
static char *NETIDFILE = "/etc/netid";
|
||||||
|
|
||||||
|
static int getnetid( char *, char * );
|
||||||
|
static int _getgroups( char *, gid_t * );
|
||||||
|
|
||||||
|
#ifndef NGROUPS
|
||||||
|
#define NGROUPS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert network-name into unix credential
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
netname2user(netname, uidp, gidp, gidlenp, gidlist)
|
||||||
|
char netname[MAXNETNAMELEN + 1];
|
||||||
|
uid_t *uidp;
|
||||||
|
gid_t *gidp;
|
||||||
|
int *gidlenp;
|
||||||
|
gid_t *gidlist;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
int gidlen;
|
||||||
|
uid_t uid;
|
||||||
|
long luid;
|
||||||
|
struct passwd *pwd;
|
||||||
|
char val[1024];
|
||||||
|
char *val1, *val2;
|
||||||
|
char *domain;
|
||||||
|
int vallen;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (getnetid(netname, val)) {
|
||||||
|
char *res = val;
|
||||||
|
|
||||||
|
p = strsep(&res, ":");
|
||||||
|
if (p == NULL)
|
||||||
|
return (0);
|
||||||
|
*uidp = (uid_t) atol(p);
|
||||||
|
p = strsep(&res, "\n,");
|
||||||
|
if (p == NULL) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
*gidp = (gid_t) atol(p);
|
||||||
|
gidlen = 0;
|
||||||
|
for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
|
||||||
|
p = strsep(&res, "\n,");
|
||||||
|
if (p == NULL)
|
||||||
|
break;
|
||||||
|
gidlist[gidlen] = (gid_t) atol(p);
|
||||||
|
}
|
||||||
|
*gidlenp = gidlen;
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
val1 = strchr(netname, '.');
|
||||||
|
if (val1 == NULL)
|
||||||
|
return (0);
|
||||||
|
if (strncmp(netname, OPSYS, (val1-netname)))
|
||||||
|
return (0);
|
||||||
|
val1++;
|
||||||
|
val2 = strchr(val1, '@');
|
||||||
|
if (val2 == NULL)
|
||||||
|
return (0);
|
||||||
|
vallen = val2 - val1;
|
||||||
|
if (vallen > (1024 - 1))
|
||||||
|
vallen = 1024 - 1;
|
||||||
|
(void) strncpy(val, val1, 1024);
|
||||||
|
val[vallen] = 0;
|
||||||
|
|
||||||
|
err = __rpc_get_default_domain(&domain); /* change to rpc */
|
||||||
|
if (err)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (strcmp(val2 + 1, domain))
|
||||||
|
return (0); /* wrong domain */
|
||||||
|
|
||||||
|
if (sscanf(val, "%ld", &luid) != 1)
|
||||||
|
return (0);
|
||||||
|
uid = luid;
|
||||||
|
|
||||||
|
/* use initgroups method */
|
||||||
|
pwd = getpwuid(uid);
|
||||||
|
if (pwd == NULL)
|
||||||
|
return (0);
|
||||||
|
*uidp = pwd->pw_uid;
|
||||||
|
*gidp = pwd->pw_gid;
|
||||||
|
*gidlenp = _getgroups(pwd->pw_name, gidlist);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initgroups
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
_getgroups(uname, groups)
|
||||||
|
char *uname;
|
||||||
|
gid_t groups[NGROUPS];
|
||||||
|
{
|
||||||
|
gid_t ngroups = 0;
|
||||||
|
struct group *grp;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int filter;
|
||||||
|
|
||||||
|
setgrent();
|
||||||
|
while ((grp = getgrent())) {
|
||||||
|
for (i = 0; grp->gr_mem[i]; i++)
|
||||||
|
if (!strcmp(grp->gr_mem[i], uname)) {
|
||||||
|
if (ngroups == NGROUPS) {
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("_getgroups: %s is in too many groups\n", uname));
|
||||||
|
goto toomany;
|
||||||
|
}
|
||||||
|
/* filter out duplicate group entries */
|
||||||
|
filter = 0;
|
||||||
|
for (j = 0; j < ngroups; j++)
|
||||||
|
if (groups[j] == grp->gr_gid) {
|
||||||
|
filter++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!filter)
|
||||||
|
groups[ngroups++] = grp->gr_gid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toomany:
|
||||||
|
endgrent();
|
||||||
|
return (ngroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert network-name to hostname
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
netname2host(netname, hostname, hostlen)
|
||||||
|
char netname[MAXNETNAMELEN + 1];
|
||||||
|
char *hostname;
|
||||||
|
int hostlen;
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char valbuf[1024];
|
||||||
|
char *val;
|
||||||
|
char *val2;
|
||||||
|
int vallen;
|
||||||
|
char *domain;
|
||||||
|
|
||||||
|
if (getnetid(netname, valbuf)) {
|
||||||
|
val = valbuf;
|
||||||
|
if ((*val == '0') && (val[1] == ':')) {
|
||||||
|
(void) strncpy(hostname, val + 2, hostlen);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = strchr(netname, '.');
|
||||||
|
if (val == NULL)
|
||||||
|
return (0);
|
||||||
|
if (strncmp(netname, OPSYS, (val - netname)))
|
||||||
|
return (0);
|
||||||
|
val++;
|
||||||
|
val2 = strchr(val, '@');
|
||||||
|
if (val2 == NULL)
|
||||||
|
return (0);
|
||||||
|
vallen = val2 - val;
|
||||||
|
if (vallen > (hostlen - 1))
|
||||||
|
vallen = hostlen - 1;
|
||||||
|
(void) strncpy(hostname, val, vallen);
|
||||||
|
hostname[vallen] = 0;
|
||||||
|
|
||||||
|
err = __rpc_get_default_domain(&domain); /* change to rpc */
|
||||||
|
if (err)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (strcmp(val2 + 1, domain))
|
||||||
|
return (0); /* wrong domain */
|
||||||
|
else
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reads the file /etc/netid looking for a + to optionally go to the
|
||||||
|
* network information service.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
getnetid(key, ret)
|
||||||
|
char *key, *ret;
|
||||||
|
{
|
||||||
|
char buf[1024]; /* big enough */
|
||||||
|
char *res;
|
||||||
|
char *mkey;
|
||||||
|
char *mval;
|
||||||
|
FILE *fd;
|
||||||
|
#ifdef YP
|
||||||
|
char *domain;
|
||||||
|
int err;
|
||||||
|
char *lookup;
|
||||||
|
int len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fd = fopen(NETIDFILE, "r");
|
||||||
|
if (fd == NULL) {
|
||||||
|
#ifdef YP
|
||||||
|
res = "+";
|
||||||
|
goto getnetidyp;
|
||||||
|
#else
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
if (fd == NULL)
|
||||||
|
return (0); /* getnetidyp brings us here */
|
||||||
|
res = fgets(buf, sizeof(buf), fd);
|
||||||
|
if (res == NULL) {
|
||||||
|
fclose(fd);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (res[0] == '#')
|
||||||
|
continue;
|
||||||
|
else if (res[0] == '+') {
|
||||||
|
#ifdef YP
|
||||||
|
getnetidyp:
|
||||||
|
err = yp_get_default_domain(&domain);
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lookup = NULL;
|
||||||
|
err = yp_match(domain, NETID, key,
|
||||||
|
strlen(key), &lookup, &len);
|
||||||
|
if (err) {
|
||||||
|
LIBTIRPC_DEBUG(1, ("getnetid: match failed error %d", err));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lookup[len] = 0;
|
||||||
|
strcpy(ret, lookup);
|
||||||
|
free(lookup);
|
||||||
|
if (fd != NULL)
|
||||||
|
fclose(fd);
|
||||||
|
return (2);
|
||||||
|
#else /* YP */
|
||||||
|
LIBTIRPC_DEBUG(1,
|
||||||
|
("Bad record in %s '+' -- NIS not supported in this library copy\n",
|
||||||
|
NETIDFILE));
|
||||||
|
continue;
|
||||||
|
#endif /* YP */
|
||||||
|
} else {
|
||||||
|
mkey = strsep(&res, "\t ");
|
||||||
|
if (mkey == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Bad record in %s -- %s", NETIDFILE, buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
mval = strsep(&res, " \t#\n");
|
||||||
|
} while (mval != NULL && !*mval);
|
||||||
|
if (mval == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Bad record in %s val problem - %s", NETIDFILE, buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(mkey, key) == 0) {
|
||||||
|
strcpy(ret, mval);
|
||||||
|
fclose(fd);
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user