Import rpc.ypxfrd.
This server impliments an RPC-based file transfer protocol that allows
an NIS slave server to copy a raw map database file from an NIS master.
The goal here is to speed up the transfer of very large maps. If you
have, for example, an NIS password database with 30,000 records in it,
it can take around 8 to 10 minutes to regenerate it (four hash databases
are created). As it stands now, ypxfr(8) transfers a map by sucking all
the records from ypserv(8) on the master using yp_all() and writing them
to a new database using the db(3) library. This adds up to another 8 to 10
minutes, per slave. With as the number of slaves increases, this latency
becomes prohibitive.
With rpc.ypxfrd, all the slave has to do is copy the already-built
hash database file from the master and move it into place. Even with a
multi-megabyte file, this reduces the master to slave transfer time
to well under a minute. (This is using TCP.)
Access restrictions are applied using the same mechanism as in ypserv:
you can control access using /var/yp/securenets, and the server will
not transmit the master.passwd.* maps unless the transfer request originates
on a reserved port.
Note: this server is based on my hastily contrived protocol and is _NOT_
compatible with Sun's protocol of the same name. It can't be compatible
for a couple of reasons. For one thing, Sun's protocol has not been published
anywhere that I know of. It is not included in any of the SunRPC source
distributions that I've been able to find. Second, Sun's NIS v2 code
uses old style ndbm maps while FreeBSD uses Berkeley DB. The file formats
are incompatible, so being able to transfer maps between FreeBSD and SunOS
hosts wouldn't do any good anyway. (You could always port the FreeBSD NIS
code to SunOS if you really wanted to do it. :)
(There's also the little fact that SunOS/SPARC is big-endian and FreeBSD/i386
is little-endian. Berkeley DB can handle byte ordering differences; ndbm
probably can't.)
1996-06-05 04:36:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1995, 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.
|
|
|
|
*
|
1997-04-28 14:22:31 +00:00
|
|
|
* $Id: ypxfrd_server.c,v 1.5 1997/04/10 13:48:59 wpaul Exp $
|
Import rpc.ypxfrd.
This server impliments an RPC-based file transfer protocol that allows
an NIS slave server to copy a raw map database file from an NIS master.
The goal here is to speed up the transfer of very large maps. If you
have, for example, an NIS password database with 30,000 records in it,
it can take around 8 to 10 minutes to regenerate it (four hash databases
are created). As it stands now, ypxfr(8) transfers a map by sucking all
the records from ypserv(8) on the master using yp_all() and writing them
to a new database using the db(3) library. This adds up to another 8 to 10
minutes, per slave. With as the number of slaves increases, this latency
becomes prohibitive.
With rpc.ypxfrd, all the slave has to do is copy the already-built
hash database file from the master and move it into place. Even with a
multi-megabyte file, this reduces the master to slave transfer time
to well under a minute. (This is using TCP.)
Access restrictions are applied using the same mechanism as in ypserv:
you can control access using /var/yp/securenets, and the server will
not transmit the master.passwd.* maps unless the transfer request originates
on a reserved port.
Note: this server is based on my hastily contrived protocol and is _NOT_
compatible with Sun's protocol of the same name. It can't be compatible
for a couple of reasons. For one thing, Sun's protocol has not been published
anywhere that I know of. It is not included in any of the SunRPC source
distributions that I've been able to find. Second, Sun's NIS v2 code
uses old style ndbm maps while FreeBSD uses Berkeley DB. The file formats
are incompatible, so being able to transfer maps between FreeBSD and SunOS
hosts wouldn't do any good anyway. (You could always port the FreeBSD NIS
code to SunOS if you really wanted to do it. :)
(There's also the little fact that SunOS/SPARC is big-endian and FreeBSD/i386
is little-endian. Berkeley DB can handle byte ordering differences; ndbm
probably can't.)
1996-06-05 04:36:55 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ypxfrd.h"
|
|
|
|
#ifndef lint
|
1997-04-28 14:22:31 +00:00
|
|
|
static const char rcsid[] = "$Id: ypxfrd_server.c,v 1.5 1997/04/10 13:48:59 wpaul Exp $";
|
Import rpc.ypxfrd.
This server impliments an RPC-based file transfer protocol that allows
an NIS slave server to copy a raw map database file from an NIS master.
The goal here is to speed up the transfer of very large maps. If you
have, for example, an NIS password database with 30,000 records in it,
it can take around 8 to 10 minutes to regenerate it (four hash databases
are created). As it stands now, ypxfr(8) transfers a map by sucking all
the records from ypserv(8) on the master using yp_all() and writing them
to a new database using the db(3) library. This adds up to another 8 to 10
minutes, per slave. With as the number of slaves increases, this latency
becomes prohibitive.
With rpc.ypxfrd, all the slave has to do is copy the already-built
hash database file from the master and move it into place. Even with a
multi-megabyte file, this reduces the master to slave transfer time
to well under a minute. (This is using TCP.)
Access restrictions are applied using the same mechanism as in ypserv:
you can control access using /var/yp/securenets, and the server will
not transmit the master.passwd.* maps unless the transfer request originates
on a reserved port.
Note: this server is based on my hastily contrived protocol and is _NOT_
compatible with Sun's protocol of the same name. It can't be compatible
for a couple of reasons. For one thing, Sun's protocol has not been published
anywhere that I know of. It is not included in any of the SunRPC source
distributions that I've been able to find. Second, Sun's NIS v2 code
uses old style ndbm maps while FreeBSD uses Berkeley DB. The file formats
are incompatible, so being able to transfer maps between FreeBSD and SunOS
hosts wouldn't do any good anyway. (You could always port the FreeBSD NIS
code to SunOS if you really wanted to do it. :)
(There's also the little fact that SunOS/SPARC is big-endian and FreeBSD/i386
is little-endian. Berkeley DB can handle byte ordering differences; ndbm
probably can't.)
1996-06-05 04:36:55 +00:00
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/uio.h>
|
|
|
|
#include <sys/fcntl.h>
|
1996-07-04 02:29:54 +00:00
|
|
|
#include <machine/endian.h>
|
Import rpc.ypxfrd.
This server impliments an RPC-based file transfer protocol that allows
an NIS slave server to copy a raw map database file from an NIS master.
The goal here is to speed up the transfer of very large maps. If you
have, for example, an NIS password database with 30,000 records in it,
it can take around 8 to 10 minutes to regenerate it (four hash databases
are created). As it stands now, ypxfr(8) transfers a map by sucking all
the records from ypserv(8) on the master using yp_all() and writing them
to a new database using the db(3) library. This adds up to another 8 to 10
minutes, per slave. With as the number of slaves increases, this latency
becomes prohibitive.
With rpc.ypxfrd, all the slave has to do is copy the already-built
hash database file from the master and move it into place. Even with a
multi-megabyte file, this reduces the master to slave transfer time
to well under a minute. (This is using TCP.)
Access restrictions are applied using the same mechanism as in ypserv:
you can control access using /var/yp/securenets, and the server will
not transmit the master.passwd.* maps unless the transfer request originates
on a reserved port.
Note: this server is based on my hastily contrived protocol and is _NOT_
compatible with Sun's protocol of the same name. It can't be compatible
for a couple of reasons. For one thing, Sun's protocol has not been published
anywhere that I know of. It is not included in any of the SunRPC source
distributions that I've been able to find. Second, Sun's NIS v2 code
uses old style ndbm maps while FreeBSD uses Berkeley DB. The file formats
are incompatible, so being able to transfer maps between FreeBSD and SunOS
hosts wouldn't do any good anyway. (You could always port the FreeBSD NIS
code to SunOS if you really wanted to do it. :)
(There's also the little fact that SunOS/SPARC is big-endian and FreeBSD/i386
is little-endian. Berkeley DB can handle byte ordering differences; ndbm
probably can't.)
1996-06-05 04:36:55 +00:00
|
|
|
#include "ypxfrd_extern.h"
|
|
|
|
|
|
|
|
int forked = 0;
|
|
|
|
int children = 0;
|
|
|
|
int fp = 0;
|
|
|
|
|
|
|
|
static bool_t
|
|
|
|
xdr_my_xfr(register XDR *xdrs, xfr *objp)
|
|
|
|
{
|
|
|
|
unsigned char buf[XFRBLOCKSIZE];
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
if ((objp->xfr_u.xfrblock_buf.xfrblock_buf_len =
|
|
|
|
read(fp, &buf, XFRBLOCKSIZE)) != -1) {
|
|
|
|
objp->ok = TRUE;
|
|
|
|
objp->xfr_u.xfrblock_buf.xfrblock_buf_val = (char *)&buf;
|
|
|
|
} else {
|
|
|
|
objp->ok = FALSE;
|
|
|
|
objp->xfr_u.xfrstat = XFR_READ_ERR;
|
|
|
|
yp_error("read error: %s", strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Serialize */
|
|
|
|
if (!xdr_xfr(xdrs, objp))
|
|
|
|
return(FALSE);
|
|
|
|
if (objp->ok == FALSE)
|
|
|
|
return(TRUE);
|
|
|
|
if (objp->xfr_u.xfrblock_buf.xfrblock_buf_len < XFRBLOCKSIZE) {
|
|
|
|
objp->ok = FALSE;
|
|
|
|
objp->xfr_u.xfrstat = XFR_DONE;
|
|
|
|
if (!xdr_xfr(xdrs, objp))
|
|
|
|
return(FALSE);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct xfr *
|
|
|
|
ypxfrd_getmap_1_svc(ypxfr_mapname *argp, struct svc_req *rqstp)
|
|
|
|
{
|
|
|
|
static struct xfr result;
|
|
|
|
char buf[MAXPATHLEN];
|
|
|
|
|
|
|
|
result.ok = FALSE;
|
|
|
|
result.xfr_u.xfrstat = XFR_DENIED;
|
|
|
|
|
|
|
|
if (yp_validdomain(argp->xfrdomain)) {
|
|
|
|
return(&result);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (yp_access(argp->xfrmap, (struct svc_req *)rqstp)) {
|
|
|
|
return(&result);
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf (buf, sizeof(buf), "%s/%s/%s", yp_dir, argp->xfrdomain,
|
|
|
|
argp->xfrmap);
|
|
|
|
if (access((char *)&buf, R_OK) == -1) {
|
|
|
|
result.xfr_u.xfrstat = XFR_ACCESS;
|
|
|
|
return(&result);
|
|
|
|
}
|
1996-07-04 02:29:54 +00:00
|
|
|
|
|
|
|
if (argp->xfr_db_type != XFR_DB_BSD_HASH &&
|
|
|
|
argp->xfr_db_type != XFR_DB_ANY) {
|
|
|
|
result.xfr_u.xfrstat = XFR_DB_TYPE_MISMATCH;
|
|
|
|
return(&result);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
|
|
|
if (argp->xfr_byte_order == XFR_ENDIAN_BIG) {
|
|
|
|
#else
|
|
|
|
if (argp->xfr_byte_order == XFR_ENDIAN_LITTLE) {
|
|
|
|
#endif
|
|
|
|
result.xfr_u.xfrstat = XFR_DB_ENDIAN_MISMATCH;
|
|
|
|
return(&result);
|
|
|
|
}
|
|
|
|
|
Import rpc.ypxfrd.
This server impliments an RPC-based file transfer protocol that allows
an NIS slave server to copy a raw map database file from an NIS master.
The goal here is to speed up the transfer of very large maps. If you
have, for example, an NIS password database with 30,000 records in it,
it can take around 8 to 10 minutes to regenerate it (four hash databases
are created). As it stands now, ypxfr(8) transfers a map by sucking all
the records from ypserv(8) on the master using yp_all() and writing them
to a new database using the db(3) library. This adds up to another 8 to 10
minutes, per slave. With as the number of slaves increases, this latency
becomes prohibitive.
With rpc.ypxfrd, all the slave has to do is copy the already-built
hash database file from the master and move it into place. Even with a
multi-megabyte file, this reduces the master to slave transfer time
to well under a minute. (This is using TCP.)
Access restrictions are applied using the same mechanism as in ypserv:
you can control access using /var/yp/securenets, and the server will
not transmit the master.passwd.* maps unless the transfer request originates
on a reserved port.
Note: this server is based on my hastily contrived protocol and is _NOT_
compatible with Sun's protocol of the same name. It can't be compatible
for a couple of reasons. For one thing, Sun's protocol has not been published
anywhere that I know of. It is not included in any of the SunRPC source
distributions that I've been able to find. Second, Sun's NIS v2 code
uses old style ndbm maps while FreeBSD uses Berkeley DB. The file formats
are incompatible, so being able to transfer maps between FreeBSD and SunOS
hosts wouldn't do any good anyway. (You could always port the FreeBSD NIS
code to SunOS if you really wanted to do it. :)
(There's also the little fact that SunOS/SPARC is big-endian and FreeBSD/i386
is little-endian. Berkeley DB can handle byte ordering differences; ndbm
probably can't.)
1996-06-05 04:36:55 +00:00
|
|
|
#ifndef DEBUG
|
|
|
|
if (children < MAX_CHILDREN && fork()) {
|
|
|
|
children++;
|
|
|
|
forked = 0;
|
|
|
|
return (NULL);
|
|
|
|
} else {
|
|
|
|
forked++;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if ((fp = open((char *)&buf, O_RDONLY)) == -1) {
|
|
|
|
result.xfr_u.xfrstat = XFR_READ_ERR;
|
|
|
|
return(&result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Start sending the file. */
|
|
|
|
|
|
|
|
svc_sendreply(rqstp->rq_xprt, xdr_my_xfr, (char *)&result);
|
|
|
|
|
|
|
|
close(fp);
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|