Import the new ypxfr, written by yours truly. Functionally equivalent

to the old one, except that it supports an additional option (-p path)
that lets you specify the top level path wiere your NIS maps live.
(ypserv allows you to specify a path like this, so it makes sense that
ypxfr should too. ypserv will automagically pass the -p flag to ypxfr
if you use a path other than /var/yp when you start it.)

This program uses client stub code generated by rpcgen as well as
the yp_dblookup.c module from ypserv.
This commit is contained in:
Bill Paul 1995-12-25 03:07:13 +00:00
parent 1c16e9536e
commit 665823d011
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/WPAUL/dist/; revision=13007
7 changed files with 1224 additions and 0 deletions

26
libexec/ypxfr/Makefile Normal file
View file

@ -0,0 +1,26 @@
# $Id: Makefile,v 1.6 1995/12/16 04:03:02 wpaul Exp $
PROG= ypxfr
SRCS= ypxfr_clnt.c yp_clnt.c ypxfr_getmap.c yp_dblookup.c \
yp_error.c ypxfr_misc.c ypxfr_main.c yp_dbwrite.c
.PATH: ${.CURDIR}/../../usr.sbin/ypserv
MAN8= ypxfr.8
CFLAGS+=-I.
CLEANFILES= yp.h yp_clnt.c ypxfr_clnt.c
RPCSRC= ${.DESTDIR}/usr/include/rpcsvc/yp.x
RPCGEN= rpcgen -I -C
ypxfr_clnt.c: ${RPCSRC} yp.h
${RPCGEN} -DYPPUSH_ONLY -l -o ${.TARGET} ${RPCSRC}
yp_clnt.c: ${RPCSRC} yp.h
${RPCGEN} -DYPSERV_ONLY -l -o ${.TARGET} ${RPCSRC}
yp.h: ${RPCSRC}
${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
.include <bsd.prog.mk>

105
libexec/ypxfr/yp_dbwrite.c Normal file
View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 1995
* 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.
*
* $Id: yp_dbwrite.c,v 1.7 1995/12/24 04:40:58 wpaul Exp $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <db.h>
#include <sys/stat.h>
#include <errno.h>
#include <paths.h>
#include "yp.h"
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: yp_dbwrite.c,v 1.7 1995/12/24 04:40:58 wpaul Exp $";
#endif
#define PERM_SECURE (S_IRUSR|S_IWUSR)
/*
* Open a DB database read/write
*/
DB *yp_open_db_rw(domain, map)
const char *domain;
const char *map;
{
DB *dbp;
char buf[1025];
yp_errno = YP_TRUE;
if (map[0] == '.' || strchr(map, '/')) {
yp_errno = YP_BADARGS;
return (NULL);
}
snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, domain, map);
dbp = dbopen(buf,O_RDWR|O_EXCL|O_CREAT, PERM_SECURE, DB_HASH, &openinfo);
if (dbp == NULL) {
switch(errno) {
case ENOENT:
yp_errno = YP_NOMAP;
break;
case EFTYPE:
yp_errno = YP_BADDB;
break;
default:
yp_errno = YP_YPERR;
break;
}
}
return (dbp);
}
int yp_put_record(dbp,key,data)
DB *dbp;
DBT *key;
DBT *data;
{
if ((dbp->put)(dbp,key,data,0)) {
(void)(dbp->close)(dbp);
return(YP_BADDB);
}
return(YP_TRUE);
}

207
libexec/ypxfr/ypxfr.8 Normal file
View file

@ -0,0 +1,207 @@
.\" Copyright (c) 1995
.\" 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 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 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.
.\"
.\" $Id: ypxfr.8,v 1.2 1995/12/25 02:54:39 wpaul Exp $
.\"
.Dd February 5, 1995
.Dt YPXFR 8
.Os
.Sh NAME
.Nm ypxfr
.Nd "transfer NIS database from remote server to local host"
.Sh SYNOPSIS
.Nm ypxfr
.Op Fl f
.Op Fl c
.Op Fl d Ar target domain
.Op Fl h Ar source host
.Op Fl s Ar source domain
.Op Fl p Ar path
.Op Fl C Ar taskid program-number ipaddr port
.Ar mapname
.Sh DESCRIPTION
.Nm ypxfr
copies an NIS database (or
.Pa map )
from one NIS server to another using NIS services. In FreeBSD,
.Nm ypxfr
is generally invoked by
.Xr ypserv 8
when it receives a map transfer request from
.Xr yppush 8 .
.Nm ypxfr
is used primarily in environments where several NIS servers
are in use in a single domain. One server, the NIS master, maintains
the canonical copies of all NIS maps, and all the other servers,
the NIS slaves, copy new versions of the maps from the master whenever
any updates are made (i.e. when a user updates their password via
.Xr yppasswd 1
).
.Pp
When run,
.Nm ypxfr
creates a temporary database file in
.Pa /var/yp/[domainmame] ,
and fills it with the contents of
.Ar mapname
as supplied by the specified
.Ar source host .
When the entire map has been transfered,
.Nm ypxfr
deletes the original copy of
.Ar mapname
and moves the temporary copy into its place. When the transfer is
complete,
.Nm ypxfr
will attempt to send a 'clear current map' request to the local
.Xr ypserv 8
process to clear any possible references it may still have to the
stale map.
.Pp
Note that all files created by
.Nm ypxfr
are owner readable and writable only for security reasons. Since the
NIS maps and the directory in which they reside are normally owned by
root, this prevents non-privleged users from making unauthorized
modifications.
.Pp
In order to maintain consistency across all NIS servers,
.Nm ypxfr
can be run periodically in a
.Xr cron 8
job. Maps which change infrequently
need only be updated once a day (preferably late at night when system
usage is lowest), whereas those that are subject to frequent changes
(such a
.Pa passwd.byname
and
.Pa passwd.byuid )
should be updated perhaps once every hour. Using
.Xr cron 8
to automatically
update the NIS maps is not strictly mandatory since all updates should
be propagated by
.Xr yppush 8
when
.Pa /var/yp/Makefile
is run on the NIS master server, however it is good practice
on large networks where possible outages could cause NIS servers to
fall out of sync with each other.
.Pp
When
.Nm ypxfr
is invoked without a controlling terminal, e.g. from inside
.Xr ypserv 8 ,
it logs all its output using the
.Xr syslog 3
facility.
.Sh OPTIONS
The following options and flags are supported by
.Nm ypxfr :
.Bl -tag -width flag
.It Fl f
Force a map transfer. Normally,
.Nm ypxfr
will not transfer a map if it determines that the NIS master's copy
is not newer than the existing copy already on the local host: the
.Fl f
flag forces a transfer regardless of which server's version is more recent.
.It Fl c
Do not send a 'clear current map' request to the
.Xr ypserv 8
process running on the local host. This flag is normally used when
invoking
.Nm ypxfr
manually on a machine that is not yet running
.Xr ypserv 8 .
Without this flag, failure to contact the local NIS server will cause
.Nm ypxfr
to abort the transfer.
.It Fl d Ar target domain
Specify a target domain other than the current NIS domain.
.It Fl h Ar source host
Specify the name of the host from which to copy the NIS maps. This option
is used to insure that
.Nm ypxfr
only copies maps from the NIS master server.
.It Fl s Ar source domain
Specify the domain from which to transfer a map, in the event that
the transfer is being done across two different NIS domains.
.It Fl p Ar path
Specify the top level directory containing the NIS maps. By
default, this path is
.Pa /var/yp .
The
.Fl p
flag allows you to specify an alternate path should you wish to
store your NIS maps in a different part of the filesystem. The
NIS server,
.Xr ypserv 8 ,
passes this flag to
.Nm ypxfr
if it too has been told to use an alternate path.
.It Fl C Ar taskid program-number ipaddr port
These options are used only when
.Nm ypxfr
is invoked by
.Xr ypserv 8
in response to a map transfer request initiated by
.Xr yppush 8 .
In this instance,
.Nm ypxfr
needs to 'callback' to the
.Xr yppush 8
process and interact with it, so
.Xr yppush 8
passes to it an IP address
.Ar ipaddr ,
port number
.Ar port ,
registered program number
.Ar program-number
and a transaction ID
.Ar taskid
that it can use to contact the waiting
.Xr yppush 8
process on the master server.
.It Ar mapname
The name of the map to transfer.
.El
.Sh FILES
.Bl -tag -width Pa -compact
.It Pa /var/yp/[domainname]/[maps]
The NIS maps for a particular NIS domain.
.El
.Sh SEE ALSO
.Xr ypserv 8 ,
.Xr yppush 8 ,
.Xr yp 4
.Sh AUTHOR
Bill Paul <wpaul@ctr.columbia.edu>

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1995
* 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.
*
* $Id: ypxfr_extern.h,v 1.5 1995/12/24 04:37:22 wpaul Exp $
*/
#include <sys/types.h>
#include <limits.h>
#include <db.h>
#include <paths.h>
#ifndef _PATH_YP
#define _PATH_YP "/var/yp/"
#endif
extern char *yp_dir;
extern int debug;
extern HASHINFO openinfo;
extern int yp_errno;
extern void yp_error __P(( const char *, ... ));
extern int _yp_check __P(( char ** ));
extern char *ypxfrerr_string __P(( ypxfrstat ));
extern DB *yp_open_db_rw __P(( const char *, const char *));
extern int yp_put_record __P(( DB *, DBT *, DBT * ));
extern int yp_get_record __P(( const char *, const char *, const DBT *, DBT *, int ));
extern int ypxfr_get_map __P(( char *, char *, char *, int (*)() ));
extern char *ypxfr_get_master __P(( char *, char *, char *, const int ));
extern unsigned long ypxfr_get_order __P(( char *, char *, char *, const int ));
extern char *ypxfxerr_string __P(( ypxfrstat ));
extern int callrpc __P(( char *, int, int, int, xdrproc_t, char *, xdrproc_t, char *));

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 1995
* 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.
*
* $Id: ypxfr_getmap.c,v 1.6 1995/12/24 04:39:04 wpaul Exp $
*/
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <rpcsvc/yp.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_getmap.c,v 1.6 1995/12/24 04:39:04 wpaul Exp $";
#endif
extern bool_t xdr_ypresp_all_seq __P(( XDR *, unsigned long * ));
int (*ypresp_allfn)();
void *ypresp_data;
extern DB *specdbp;
extern int yp_errno;
/*
* This is largely the same as yp_all() except we do the transfer
* from a specific server without the aid of ypbind(8). We need to
* be able to specify the source host explicitly since ypxfr may
* only transfer maps from the NIS master server for any given domain.
* However, if we use the libc version of yp_all(), we could end up
* talking to one of the slaves instead. We do need to dig into libc
* a little though, since it contains the magic XDR function we need.
*/
int ypxfr_get_map(map, domain, host, callback)
char *map;
char *domain;
char *host;
int (*callback)();
{
CLIENT *clnt;
ypreq_nokey req;
unsigned long status;
struct timeval timeout;
timeout.tv_usec = 0;
timeout.tv_sec = 10;
/* YPPROC_ALL is a TCP service */
if ((clnt = clnt_create(host, YPPROG, YPVERS, "tcp")) == NULL) {
yp_error("%s", clnt_spcreateerror("failed to tcp handle"));
yp_errno = YPXFR_YPERR;
return(1);
}
req.domain = domain;
req.map = map;
ypresp_allfn = callback;
ypresp_data = NULL;
(void)clnt_call(clnt, YPPROC_ALL, xdr_ypreq_nokey, &req,
xdr_ypresp_all_seq, &status, timeout);
clnt_destroy(clnt);
if (status != YP_TRUE) {
yp_errno = YPXFR_YPERR;
return(1);
}
return(0);
}

490
libexec/ypxfr/ypxfr_main.c Normal file
View file

@ -0,0 +1,490 @@
/*
* Copyright (c) 1995
* 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.
*
* $Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
struct dom_binding {};
#include <rpcsvc/ypclnt.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $";
#endif
char *progname = "ypxfr";
char *yp_dir = _PATH_YP;
int _rpcpmstart = 0;
int ypxfr_use_yplib = 0; /* Assume the worst. */
int ypxfr_clear = 1;
int ypxfr_prognum = 0;
struct sockaddr_in ypxfr_callback_addr;
struct yppushresp_xfr ypxfr_resp;
DB *dbp;
static void ypxfr_exit(retval, temp)
ypxfrstat retval;
char *temp;
{
CLIENT *clnt;
int sock = RPC_ANYSOCK;
struct timeval timeout;
/* Clean up no matter what happened previously. */
if (temp != NULL) {
(void)(dbp->close)(dbp);
if (unlink(temp) == -1) {
yp_error("failed to unlink %s",strerror(errno));
}
}
if (_rpcpmstart) {
timeout.tv_sec = 20;
timeout.tv_usec = 0;
if ((clnt = clntudp_create(&ypxfr_callback_addr, ypxfr_prognum,
1, timeout, &sock)) == NULL) {
yp_error("%s", clnt_spcreateerror("failed to establish callback handle"));
exit(1);
}
ypxfr_resp.status = retval;
if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
yp_error("%s", clnt_sperror(clnt, "callback failed"));
clnt_destroy(clnt);
exit(1);
}
clnt_destroy(clnt);
} else {
yp_error("Exiting: %s", ypxfrerr_string(retval));
}
exit(0);
}
static void usage()
{
if (_rpcpmstart) {
ypxfr_exit(YPXFR_BADARGS,NULL);
} else {
fprintf(stderr,"usage: %s [-f] [-c] [-d target domain] \
[-h source host] [-s source domain]\n", progname);
fprintf(stderr,"\t [-p path] [-C taskid program-number \
ipaddr port] mapname\n");
exit(1);
}
}
int ypxfr_foreach(status, key, keylen, val, vallen, data)
int status;
char *key;
int keylen;
char *val;
int vallen;
char *data;
{
DBT dbkey, dbval;
if (status != YP_TRUE)
return (status);
dbkey.data = key;
dbkey.size = keylen;
dbval.data = val;
dbval.size = vallen;
if (yp_put_record(dbp, &dbkey, &dbval) != YP_TRUE)
return(yp_errno);
return (0);
}
main(argc,argv)
int argc;
char *argv[];
{
int ch;
int ypxfr_force = 0;
char *ypxfr_dest_domain = NULL;
char *ypxfr_source_host = NULL;
char *ypxfr_source_domain = NULL;
char *ypxfr_local_domain = NULL;
char *ypxfr_master = NULL;
unsigned long ypxfr_order = -1, ypxfr_skew_check = -1;
char *ypxfr_mapname = NULL;
int ypxfr_args = 0;
char ypxfr_temp_map[MAXPATHLEN + 2];
char tempmap[MAXPATHLEN + 2];
char buf[MAXPATHLEN + 2];
DBT key, data;
debug = 1;
if (!isatty(fileno(stderr))) {
openlog(progname, LOG_PID, LOG_DAEMON);
_rpcpmstart = 1;
}
if (argc < 2)
usage();
while ((ch = getopt(argc, argv, "fcd:h:s:p:C:")) != EOF) {
int my_optind;
switch(ch) {
case 'f':
ypxfr_force++;
ypxfr_args++;
break;
case 'c':
ypxfr_clear = 0;
ypxfr_args++;
break;
case 'd':
ypxfr_dest_domain = optarg;
ypxfr_args += 2;
break;
case 'h':
ypxfr_source_host = optarg;
ypxfr_args += 2;
break;
case 's':
ypxfr_source_domain = optarg;
ypxfr_args += 2;
break;
case 'p':
yp_dir = optarg;
ypxfr_args += 2;
break;
case 'C':
/*
* Whoever decided that the -C flag should take
* four arguments is a twit.
*/
my_optind = optind - 1;
if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
yp_error("transaction ID not specified");
usage();
}
ypxfr_resp.transid = atol(argv[my_optind]);
my_optind++;
if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
yp_error("RPC program number not specified");
usage();
}
ypxfr_prognum = atol(argv[my_optind]);
my_optind++;
if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
yp_error("address not specified");
usage();
}
if (!inet_aton(argv[my_optind], &ypxfr_callback_addr.sin_addr)) {
yp_error("failed to convert '%s' to IP addr",
argv[my_optind]);
exit(1);
}
my_optind++;
if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
yp_error("port not specified");
usage();
}
ypxfr_callback_addr.sin_port = htons((u_short)atoi(argv[my_optind]));
ypxfr_args += 5;
break;
default:
usage();
break;
}
}
ypxfr_mapname = argv[ypxfr_args + 1];
if (ypxfr_mapname == NULL) {
yp_error("no map name specified");
usage();
}
/* Always the case. */
ypxfr_callback_addr.sin_family = AF_INET;
/* Determine if local NIS client facilities are turned on. */
if (!yp_get_default_domain(&ypxfr_local_domain) &&
_yp_check(&ypxfr_local_domain))
ypxfr_use_yplib = 1;
/*
* If no destination domain is specified, assume that the
* local default domain is to be used and try to obtain it.
* Fails if NIS client facilities are turned off.
*/
if (ypxfr_dest_domain == NULL) {
if (ypxfr_use_yplib) {
yp_get_default_domain(&ypxfr_dest_domain);
} else {
yp_error("no destination domain specified and \
the local domain name isn't set");
ypxfr_exit(YPXFR_BADARGS,NULL);
}
}
/*
* If a source domain is not specified, assume it to
* be the same as the destination domain.
*/
if (ypxfr_source_domain == NULL) {
ypxfr_source_domain = ypxfr_dest_domain;
}
/*
* If the source host is not specified, assume it to be the
* master for the specified map. If local NIS client facilities
* are turned on, we can figure this out using yp_master().
* If not, we have to see if a local copy of the map exists
* and extract its YP_MASTER_NAME record. If _that_ fails,
* we are stuck and must ask the user for more information.
*/
if (ypxfr_source_host == NULL) {
if (!ypxfr_use_yplib) {
/*
* Double whammy: NIS isn't turned on and the user
* didn't specify a source host.
*/
char *dptr;
key.data = "YP_MASTER_NAME";
key.size = sizeof("YP_MASTER_NAME") - 1;
if (yp_get_record(ypxfr_dest_domain, ypxfr_mapname,
&key, &data, 1) != YP_TRUE) {
yp_error("no source host specified");
ypxfr_exit(YPXFR_BADARGS,NULL);
}
dptr = data.data;
dptr[data.size] = '\0';
ypxfr_master = ypxfr_source_host = strdup(dptr);
}
} else {
if (ypxfr_use_yplib)
ypxfr_use_yplib = 0;
}
if (ypxfr_master == NULL) {
if ((ypxfr_master = ypxfr_get_master(ypxfr_source_domain,
ypxfr_mapname,
ypxfr_source_host,
ypxfr_use_yplib)) == NULL) {
yp_error("failed to find master of %s in domain %s",
ypxfr_mapname, ypxfr_source_domain);
ypxfr_exit(YPXFR_MADDR,NULL);
}
}
/*
* If we got here and ypxfr_source_host is still undefined,
* it means we had to resort to using yp_master() to find the
* master server for the map. The source host and master should
* be identical.
*/
if (ypxfr_source_host == NULL)
ypxfr_source_host = ypxfr_master;
if ((ypxfr_order = ypxfr_get_order(ypxfr_source_domain,
ypxfr_mapname,
ypxfr_master, 0)) == 0) {
yp_error("failed to get order number of %s",
ypxfr_mapname);
ypxfr_exit(YPXFR_YPERR,NULL);
}
key.data = "YP_LAST_MODIFIED";
key.size = sizeof("YP_LAST_MODIFIED") - 1;
/* The order number is immaterial when the 'force' flag is set. */
if (!ypxfr_force) {
int ignore = 0;
if (yp_get_record(ypxfr_dest_domain,ypxfr_mapname,&key,&data,1) != YP_TRUE) {
switch(yp_errno) {
case YP_NOKEY:
ypxfr_exit(YPXFR_FORCE,NULL);
break;
case YP_NOMAP:
/*
* If the map doesn't exist, we're
* creating it. Ignore the error.
*/
ignore++;
break;
case YP_BADDB:
default:
ypxfr_exit(YPXFR_DBM,NULL);
break;
}
}
if (!ignore && ypxfr_order <= atoi(data.data))
ypxfr_exit(YPXFR_AGE, NULL);
}
/* Construct a temporary map file name */
snprintf(tempmap, sizeof(tempmap), "%s.%d",ypxfr_mapname, getpid());
snprintf(ypxfr_temp_map, sizeof(ypxfr_temp_map), "%s/%s/%s", yp_dir,
ypxfr_dest_domain, tempmap);
/* Open the temporary map read/write. */
if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap)) == NULL) {
yp_error("failed to open temporary map file");
ypxfr_exit(YPXFR_DBM,NULL);
}
/*
* Fill in the keys we already know, such as the order number,
* master name, input file name (we actually make up a bogus
* name for that) and output file name.
*/
snprintf(buf, sizeof(buf), "%d", ypxfr_order);
data.data = buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
yp_error("failed to write order number to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
key.data = "YP_MASTER_NAME";
key.size = sizeof("YP_MASTER_NAME") - 1;
data.data = ypxfr_master;
data.size = strlen(ypxfr_master);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
yp_error("failed to write master name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
key.data = "YP_DOMAIN_NAME";
key.size = sizeof("YP_DOMAIN_NAME") - 1;
data.data = ypxfr_dest_domain;
data.size = strlen(ypxfr_dest_domain);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
yp_error("failed to write domain name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
snprintf (buf, sizeof(buf), "%s:%s", ypxfr_source_host, ypxfr_mapname);
key.data = "YP_INPUT_NAME";
key.size = sizeof("YP_INPUT_NAME") - 1;
data.data = &buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
yp_error("failed to write input name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
ypxfr_mapname);
key.data = "YP_OUTPUT_NAME";
key.size = sizeof("YP_OUTPUT_NAME") - 1;
data.data = &buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
yp_error("failed to write output name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
/* Now suck over the contents of the map from the master. */
if (ypxfr_get_map(ypxfr_mapname,ypxfr_source_domain,
ypxfr_source_host, ypxfr_foreach)){
yp_error("failed to retrieve map from source host");
ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
}
(void)(dbp->close)(dbp);
/* Peek at the order number again and check for skew. */
if ((ypxfr_skew_check = ypxfr_get_order(ypxfr_source_domain,
ypxfr_mapname,
ypxfr_master, 0)) == 0) {
yp_error("failed to get order number of %s",
ypxfr_mapname);
ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
}
if (ypxfr_order != ypxfr_skew_check)
ypxfr_exit(YPXFR_SKEW,&ypxfr_temp_map);
/*
* Send a YPPROC_CLEAR to the local ypserv.
* The FreeBSD ypserv doesn't really need this, but we send it
* here anyway for the sake of consistency.
*/
if (!ypxfr_clear) {
char in = 0;
char *out = NULL;
if (callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR, xdr_void,
(void *)&in, xdr_void, (void *)out) == NULL) {
yp_error("failed to send 'clear' to local ypserv");
ypxfr_exit(YPXFR_YPERR, &ypxfr_temp_map);
}
}
if (unlink(buf) == -1 && errno != ENOENT) {
yp_error("unlink(%s) failed: %s", buf, strerror(errno));
ypxfr_exit(YPXFR_FILE,NULL);
}
if (rename(ypxfr_temp_map, buf) == -1) {
yp_error("rename(%s,%s) failed: %s", ypxfr_temp_map, buf,
strerror(errno));
ypxfr_exit(YPXFR_FILE,NULL);
}
ypxfr_exit(YPXFR_SUCC,NULL);
return(1);
}

240
libexec/ypxfr/ypxfr_misc.c Normal file
View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 1995
* 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.
*
* $Id: ypxfr_misc.c,v 1.6 1995/12/24 04:39:55 wpaul Exp $
*/
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
struct dom_binding {};
#include <rpcsvc/ypclnt.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_misc.c,v 1.6 1995/12/24 04:39:55 wpaul Exp $";
#endif
char *ypxfrerr_string(code)
ypxfrstat code;
{
switch(code) {
case YPXFR_SUCC:
return ("Map successfully transfered");
break;
case YPXFR_AGE:
return ("Master's version not newer");
break;
case YPXFR_NOMAP:
return ("No such map in server's domain");
break;
case YPXFR_NODOM:
return ("Domain not supported by server");
break;
case YPXFR_RSRC:
return ("Local resource allocation failure");
break;
case YPXFR_RPC:
return ("RPC failure talking to server");
break;
case YPXFR_MADDR:
return ("Could not get master server address");
break;
case YPXFR_YPERR:
return ("NIS server/map database error");
break;
case YPXFR_BADARGS:
return ("Request arguments bad");
break;
case YPXFR_DBM:
return ("Local database operation failed");
break;
case YPXFR_FILE:
return ("Local file I/O operation failed");
break;
case YPXFR_SKEW:
return ("Map version skew during transfer");
break;
case YPXFR_CLEAR:
return ("Couldn't send \"clear\" request to local ypserv");
break;
case YPXFR_FORCE:
return ("No local order number in map -- use -f flag");
break;
case YPXFR_XFRERR:
return ("General ypxfr error");
break;
case YPXFR_REFUSED:
return ("Transfer request refused by ypserv");
break;
default:
return ("Unknown error code");
break;
}
}
/*
* These are wrappers for the usual yp_master() and yp_order() functions.
* They can use either local yplib functions (the real yp_master() and
* yp_order()) or do direct RPCs to a specified server. The latter is
* necessary if ypxfr is run on a machine that isn't configured as an
* NIS client (this can happen very easily: a given machine need not be
* an NIS client in order to be an NIS server).
*/
char *ypxfr_get_master(domain,map,source,yplib)
char *domain;
char *map;
char *source;
const int yplib;
{
if (yplib) {
int res;
char *master;
if ((res = yp_master(domain, map, &master))) {
switch (res) {
case YPERR_DOMAIN:
yp_errno = YPXFR_NODOM;
break;
case YPERR_MAP:
yp_errno = YPXFR_NOMAP;
break;
case YPERR_YPERR:
default:
yp_errno = YPXFR_YPERR;
break;
}
return(NULL);
} else
return(master);
} else {
CLIENT *clnt;
ypresp_master *resp;
ypreq_nokey req;
if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
yp_error("%s",clnt_spcreateerror("failed to \
create udp handle to ypserv"));
yp_errno = YPXFR_RPC;
return(NULL);
}
req.map = map;
req.domain = domain;
if ((resp = ypproc_master_2(&req, clnt)) == NULL) {
yp_error("%s",clnt_sperror(clnt,"YPPROC_MASTER \
failed"));
clnt_destroy(clnt);
yp_errno = YPXFR_RPC;
return(NULL);
}
clnt_destroy(clnt);
if (resp->stat != YP_TRUE) {
switch (resp->stat) {
case YP_NODOM:
yp_errno = YPXFR_NODOM;
break;
case YP_NOMAP:
yp_errno = YPXFR_NOMAP;
break;
case YP_YPERR:
default:
yp_errno = YPXFR_YPERR;
break;
}
return(NULL);
}
return(resp->peer);
}
}
unsigned long ypxfr_get_order(domain, map, source, yplib)
char *domain;
char *map;
char *source;
const int yplib;
{
if (yplib) {
unsigned long order;
int res;
if ((res = yp_order(domain, map, (int *)&order))) {
switch (res) {
case (YPERR_DOMAIN):
yp_errno = YPXFR_NODOM;
break;
case (YPERR_MAP):
yp_errno = YPXFR_NOMAP;
break;
case (YPERR_YPERR):
default:
yp_errno = YPXFR_YPERR;
break;
}
return(0);
} else
return(order);
} else {
CLIENT *clnt;
ypresp_order *resp;
ypreq_nokey req;
if ((clnt = clnt_create(source,YPPROG,YPVERS,"udp")) == NULL) {
yp_error("%s",clnt_spcreateerror("couldn't create \
udp handle to ypserv"));
yp_errno = YPXFR_RPC;
return(0);
}
req.map = map;
req.domain = domain;
if ((resp = ypproc_order_2(&req, clnt)) == NULL) {
yp_error("%s", clnt_sperror(clnt, "YPPROC_ORDER \
failed"));
clnt_destroy(clnt);
yp_errno = YPXFR_RPC;
return(0);
}
clnt_destroy(clnt);
if (resp->stat != YP_TRUE) {
switch (resp->stat) {
case (YP_NODOM):
yp_errno = YPXFR_NODOM;
break;
case (YP_NOMAP):
yp_errno = YPXFR_NOMAP;
break;
case (YP_YPERR):
default:
yp_errno = YPXFR_YPERR;
break;
}
return(0);
}
return(resp->ordernum);
}
}