[删除] 解压后的源码包

This commit is contained in:
gaoyang3513
2023-10-16 19:03:18 +08:00
parent baab17d150
commit ef4ad4090c
610 changed files with 0 additions and 155521 deletions

View File

@ -1,52 +0,0 @@
# 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

View File

@ -1,3 +0,0 @@
Gilles Quillard <gilles.quillard@bull.net>
Antoine Fraticelli <antoine.fraticelli@bull.net>

View File

@ -1,25 +0,0 @@
/*
* 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.
*/

View File

@ -1,206 +0,0 @@
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.

View File

@ -1,2 +0,0 @@
Patches can be sent to libtirpc-devel@lists.sourceforge.net with a CC
to linux-nfs@vger.kernel.org

View File

@ -1,370 +0,0 @@
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.

View File

@ -1,52 +0,0 @@
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

View File

@ -1,3 +0,0 @@
New in 0.1:
* Portage from FreeBSD 5.2.1 (security part to be completed)
* Use autoconf/automake

View File

@ -1,44 +0,0 @@
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.

View File

@ -1,6 +0,0 @@
Thanks to for
Aurelien Charbon <aurelien.charbon@bull.net> TI-RPC portage from NetBSD
BSD Communauty TI-RPC improvement from Sun implementation

View File

@ -1,3 +0,0 @@
* Support of DES & other security part
* Provide tests
* rpcgen command missing

View File

@ -1,7 +0,0 @@
# This file is used by configure to get version information
#
PKG_MAJOR=0
PKG_MINOR=1
PKG_REVISION=11
PKG_BUILD=0

View File

@ -1,42 +0,0 @@
#!/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

View File

@ -1,12 +0,0 @@
[ -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*

View File

@ -1,103 +0,0 @@
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)

View File

@ -1,4 +0,0 @@
dist_sysconf_DATA = netconfig bindresvport.blacklist
CLEANFILES = cscope.* *~
DISTCLEANFILES = Makefile.in

View File

@ -1,14 +0,0 @@
#
# 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

View File

@ -1,19 +0,0 @@
#
# 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 - - -

View File

@ -1,12 +0,0 @@
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

View File

@ -1,30 +0,0 @@
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

View File

@ -1,102 +0,0 @@
.\" @(#)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

View File

@ -1,134 +0,0 @@
.\" @(#)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.

View File

@ -1,220 +0,0 @@
.\" @(#)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

View File

@ -1,168 +0,0 @@
.\" @(#)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

View File

@ -1,105 +0,0 @@
.\" @(#)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.

View File

@ -1,36 +0,0 @@
.\" @(#)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.

View File

@ -1,123 +0,0 @@
.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

View File

@ -1,52 +0,0 @@
.\" @(#)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 .

View File

@ -1,41 +0,0 @@
.\" @(#)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

View File

@ -1,515 +0,0 @@
.\" @(#)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

View File

@ -1,57 +0,0 @@
.\" @(#)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

View File

@ -1,96 +0,0 @@
.\" @(#)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

View File

@ -1,316 +0,0 @@
.\" @(#)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

View File

@ -1,514 +0,0 @@
.\" @(#)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

View File

@ -1,55 +0,0 @@
.\" 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 .

View File

@ -1,70 +0,0 @@
.\" 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 .

View File

@ -1,52 +0,0 @@
.\" 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 .

View File

@ -1,79 +0,0 @@
.\" 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 .

View File

@ -1,61 +0,0 @@
.\" 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 .

View File

@ -1,81 +0,0 @@
.\" 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 .

View File

@ -1,63 +0,0 @@
.\" 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 .

View File

@ -1,61 +0,0 @@
.\" 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 .

View File

@ -1,70 +0,0 @@
.\" 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 .

View File

@ -1,74 +0,0 @@
.\" 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 .

View File

@ -1,109 +0,0 @@
.\" 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 .

View File

@ -1,112 +0,0 @@
.\" 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).

View File

@ -1,67 +0,0 @@
.\" 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 .

View File

@ -1,84 +0,0 @@
.\" 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 .

View File

@ -1,61 +0,0 @@
.\" 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 .

View File

@ -1,295 +0,0 @@
.\" @(#)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

File diff suppressed because it is too large Load Diff

View File

@ -1,267 +0,0 @@
.\" @(#)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

View File

@ -1,337 +0,0 @@
.\" @(#)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

View File

@ -1,97 +0,0 @@
.\" @(#)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

View File

@ -1,183 +0,0 @@
.\" @(#)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

View File

@ -1,101 +0,0 @@
.\" @(#)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

View File

@ -1,194 +0,0 @@
.\" @(#)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

View File

@ -1,222 +0,0 @@
.\" 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 .

View File

@ -1,50 +0,0 @@
.\" @(#)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.

View File

@ -1,52 +0,0 @@
## 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

View File

@ -1,500 +0,0 @@
/*
* 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);
}

View File

@ -1,984 +0,0 @@
/*
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 = &num;
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;
}

View File

@ -1,182 +0,0 @@
/*
* 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);
}

View File

@ -1,495 +0,0 @@
/*
* 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);
}

View File

@ -1,424 +0,0 @@
/*
* 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);
}

View File

@ -1,85 +0,0 @@
/*
* 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);
}

View File

@ -1,371 +0,0 @@
/*
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");
}
}

View File

@ -1,65 +0,0 @@
/*
* 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);
}

View File

@ -1,139 +0,0 @@
/*
* 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;
}

View File

@ -1,336 +0,0 @@
/*
* 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

View File

@ -1,698 +0,0 @@
/*
* 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);
}

View File

@ -1,788 +0,0 @@
/*
* 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);
}

View File

@ -1,207 +0,0 @@
/*
* 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 */

View File

@ -1,434 +0,0 @@
/*
* 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);
}

View File

@ -1,335 +0,0 @@
/*
* 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);
}

View File

@ -1,305 +0,0 @@
/*
* 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);
}

View File

@ -1,178 +0,0 @@
/*
* 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);
}

View File

@ -1,777 +0,0 @@
/*
* 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, &ltmp, sizeof (ltmp));
break;
case CLSET_VERS:
memcpy(&ltmp, 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, &ltmp, sizeof (ltmp));
break;
case CLSET_PROG:
memcpy(&ltmp, 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);
}

View File

@ -1,99 +0,0 @@
/*
* 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);
}

View File

@ -1,73 +0,0 @@
/*
* 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);
}

View File

@ -1,59 +0,0 @@
/*
* 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 */

View File

@ -1,146 +0,0 @@
/*
* 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);
}

View File

@ -1,594 +0,0 @@
/* 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);
}

View File

@ -1,65 +0,0 @@
//#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++;
}
}

View File

@ -1,58 +0,0 @@
/*
* 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));
}

View File

@ -1,721 +0,0 @@
/*
* 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);
}

View File

@ -1,261 +0,0 @@
/*
* 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 */
}

View File

@ -1,51 +0,0 @@
/*
* 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);
}

View File

@ -1,170 +0,0 @@
/*
* 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));
}

View File

@ -1,332 +0,0 @@
/*
* 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

View File

@ -1,66 +0,0 @@
/*
* 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));
}

View File

@ -1,446 +0,0 @@
/*
* 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);
}
}

View File

@ -1,170 +0,0 @@
/*
* 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);
}

View File

@ -1,335 +0,0 @@
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;
};

View File

@ -1,153 +0,0 @@
#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;
}

View File

@ -1,143 +0,0 @@
/*
* 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);
}

View File

@ -1,322 +0,0 @@
/*
* 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);
}
}
}
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2010, Oracle America, Inc.
*
* 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.
*/
#ifndef _INTERNAL_NIS_H
#define _INTERNAL_NIS_H 1
/* This file only contains the definition of nis_server, to be
able to compile libtirpc without the need to have a glibc
with sunrpc or a libnsl already installed. */
#define NIS_PK_NONE 0
struct nis_attr {
char *zattr_ndx;
struct {
u_int zattr_val_len;
char *zattr_val_val;
} zattr_val;
};
typedef struct nis_attr nis_attr;
typedef char *nis_name;
struct endpoint {
char *uaddr;
char *family;
char *proto;
};
typedef struct endpoint endpoint;
struct nis_server {
nis_name name;
struct {
u_int ep_len;
endpoint *ep_val;
} ep;
uint32_t key_type;
netobj pkey;
};
typedef struct nis_server nis_server;
#endif /* ! _INTERNAL_NIS_H */

View File

@ -1,109 +0,0 @@
/*
* 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.
*/
/*
* pmap_clnt.c
* Client interface to pmap rpc service.
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#include <rpc/nettype.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include "rpc_com.h"
bool_t
pmap_set(u_long program, u_long version, int protocol, int port)
{
bool_t rslt;
struct netbuf *na;
struct netconfig *nconf;
char buf[32];
if ((protocol != IPPROTO_UDP) && (protocol != IPPROTO_TCP)) {
return (FALSE);
}
nconf = __rpc_getconfip(protocol == IPPROTO_UDP ? "udp" : "tcp");
if (nconf == NULL) {
return (FALSE);
}
snprintf(buf, sizeof buf, "0.0.0.0.%d.%d",
(((u_int32_t)port) >> 8) & 0xff, port & 0xff);
na = uaddr2taddr(nconf, buf);
if (na == NULL) {
freenetconfigent(nconf);
return (FALSE);
}
rslt = rpcb_set((rpcprog_t)program, (rpcvers_t)version, nconf, na);
free(na);
freenetconfigent(nconf);
return (rslt);
}
/*
* Remove the mapping between program, version and port.
* Calls the pmap service remotely to do the un-mapping.
*/
bool_t
pmap_unset(u_long program, u_long version)
{
struct netconfig *nconf;
bool_t udp_rslt = FALSE;
bool_t tcp_rslt = FALSE;
nconf = __rpc_getconfip("udp");
if (nconf != NULL) {
udp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
nconf);
freenetconfigent(nconf);
}
nconf = __rpc_getconfip("tcp");
if (nconf != NULL) {
tcp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
nconf);
freenetconfigent(nconf);
}
/*
* XXX: The call may still succeed even if only one of the
* calls succeeded. This was the best that could be
* done for backward compatibility.
*/
return (tcp_rslt || udp_rslt);
}

View File

@ -1,89 +0,0 @@
/*
* 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.
*/
/*
* pmap_getmap.c
* Client interface to pmap rpc service.
* contains pmap_getmaps, which is only tcp service involved
*
* Copyright (C) 1984, Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
//#include <clnt_soc.h>
#define NAMELEN 255
#define MAX_BROADCAST_SIZE 1400
/*
* Get a copy of the current port maps.
* Calls the pmap service remotely to do get the maps.
*/
struct pmaplist *
pmap_getmaps(address)
struct sockaddr_in *address;
{
struct pmaplist *head = NULL;
int sock = -1;
struct timeval minutetimeout;
CLIENT *client;
assert(address != NULL);
minutetimeout.tv_sec = 60;
minutetimeout.tv_usec = 0;
address->sin_port = htons(PMAPPORT);
client = clnttcp_create(address, PMAPPROG,
PMAPVERS, &sock, 50, 500);
if (client != NULL) {
if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP,
(xdrproc_t)xdr_void, NULL,
(xdrproc_t)xdr_pmaplist, &head, minutetimeout) !=
RPC_SUCCESS) {
clnt_perror(client, "pmap_getmaps rpc problem");
}
CLNT_DESTROY(client);
}
address->sin_port = 0;
return (head);
}

Some files were not shown because too many files have changed in this diff Show More