Add support for rpc.ypxfrd and document it in the man page.

Also generallize the yp_dbwrite functions a little: allow the caller
to specify certain flags. I need this mostly for some changes to
rpc.yppasswdd to allow in-place updates.

Also change Makefile a little to use the same format as ypserv.
This commit is contained in:
Bill Paul 1996-06-05 05:42:52 +00:00
parent 439a59dd6e
commit 16deb43a45
8 changed files with 230 additions and 40 deletions

View File

@ -2,25 +2,39 @@
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
yp_error.c ypxfr_misc.c ypxfr_main.c yp_dbwrite.c \
ypxfrd_xdr.c ypxfrd_getmap.c
.PATH: ${.CURDIR}/../../usr.sbin/ypserv
MAN8= ypxfr.8
CFLAGS+=-I.
CFLAGS+= -I.
LDADD+= -lrpcsvc
CLEANFILES= yp.h yp_clnt.c ypxfr_clnt.c
RPCSRC= ${.DESTDIR}/usr/include/rpcsvc/yp.x
RPCDIR= ${.CURDIR}/../../include/rpcsvc
RPCGEN= rpcgen -I -C
ypxfr_clnt.c: ${RPCSRC} yp.h
${RPCGEN} -DYPPUSH_ONLY -l -o ${.TARGET} ${RPCSRC}
ypxfr_clnt.c: ${RPCDIR}/yp.x yp.h
rm -f ${.TARGET}
${RPCGEN} -DYPPUSH_ONLY -l -o ${.TARGET} ${RPCDIR}/yp.x
yp_clnt.c: ${RPCSRC} yp.h
${RPCGEN} -DYPSERV_ONLY -l -o ${.TARGET} ${RPCSRC}
yp_clnt.c: ${RPCDIR}/yp.x yp.h
rm -f ${.TARGET}
${RPCGEN} -DYPSERV_ONLY -l -o ${.TARGET} ${RPCDIR}/yp.x
yp.h: ${RPCSRC}
${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
yp.h: ${RPCDIR}/yp.x
rm -f ${.TARGET}
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/yp.x
# ypxfrd_xdr.c: ${RPCDIR}/ypxfrd.x ypxfrd.h
# rm -f ${.TARGET}
# ${RPCGEN} -c -o ${.TARGET} ${RPCDIR}/ypxfrd.x
ypxfrd.h: ${RPCDIR}/ypxfrd.x
rm -f ${.TARGET}
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/ypxfrd.x
.include <bsd.prog.mk>

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: yp_dbwrite.c,v 1.9 1996/02/04 04:08:11 wpaul Exp wpaul $
* $Id: yp_dbwrite.c,v 1.10 1996/06/03 03:11:25 wpaul Exp $
*
*/
#include <stdio.h>
@ -46,7 +46,7 @@
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: yp_dbwrite.c,v 1.9 1996/02/04 04:08:11 wpaul Exp wpaul $";
static const char rcsid[] = "$Id: yp_dbwrite.c,v 1.10 1996/06/03 03:11:25 wpaul Exp $";
#endif
#define PERM_SECURE (S_IRUSR|S_IWUSR)
@ -54,9 +54,10 @@ static const char rcsid[] = "$Id: yp_dbwrite.c,v 1.9 1996/02/04 04:08:11 wpaul E
/*
* Open a DB database read/write
*/
DB *yp_open_db_rw(domain, map)
DB *yp_open_db_rw(domain, map, flags)
const char *domain;
const char *map;
const int flags;
{
DB *dbp;
char buf[1025];
@ -69,9 +70,10 @@ DB *yp_open_db_rw(domain, map)
return (NULL);
}
snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, domain, map);
#define FLAGS O_RDWR|O_EXLOCK|O_EXCL|O_CREAT
dbp = dbopen(buf,O_RDWR|O_EXLOCK|O_EXCL|O_CREAT, PERM_SECURE, DB_HASH, &openinfo);
snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, domain, map);
dbp = dbopen(buf,flags ? flags : FLAGS,PERM_SECURE,DB_HASH,&openinfo);
if (dbp == NULL) {
switch(errno) {
@ -90,14 +92,16 @@ DB *yp_open_db_rw(domain, map)
return (dbp);
}
int yp_put_record(dbp,key,data)
int yp_put_record(dbp,key,data,allow_overwrite)
DB *dbp;
DBT *key;
DBT *data;
int allow_overwrite;
{
int rval;
if ((rval = (dbp->put)(dbp,key,data,R_NOOVERWRITE))) {
if ((rval = (dbp->put)(dbp,key,data, allow_overwrite ? 0 :
R_NOOVERWRITE))) {
switch(rval) {
case 1:
return(YP_FALSE);

View File

@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: ypxfr.8,v 1.1.1.1 1995/12/25 03:07:13 wpaul Exp $
.\" $Id: ypxfr.8,v 1.3 1996/06/05 04:07:04 wpaul Exp $
.\"
.Dd February 5, 1995
.Dt YPXFR 8
@ -122,6 +122,30 @@ is invoked without a controlling terminal, e.g. from inside
it logs all its output using the
.Xr syslog 3
facility.
.Sh NOTES
The FreeBSD version of
.Nm ypxfr
has support for a special map transfer protocol which works in
conjunction with the FreeBSD
.Xr rpc.ypxfrd 8
server. This protocol allows it to transfer raw map database files from
the NIS master server and can be many times faster than the standard
transfer method, particularly for very large NIS maps. The
.Nm ypxfr
command will check to see if the
.Xr rpc.ypxfrd 8
server is registered on the NIS master server and attempt to use
it if it is present. If it isn't it will fall back to the standard
transfer method, copying the map contents from
.Xr ypserv 8
and creating new maps instead.
.Pp
Note that while the FreeBSD ypxfrd protocol is conceptually similar
to the SunOS ypxfrd protocol, FreeBSD's protocol is not compatible with
Sun's, therefore it will not work with Sun's ypxfrd server. FreeBSD
slave systems can still transfer maps from any non-FreeBSD NIS server,
however they will only be able to take advantage of the faster protocol
if the master server is also running FreeBSD.
.Sh OPTIONS
The following options and flags are supported by
.Nm ypxfr :

View File

@ -29,12 +29,15 @@
* 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 $
* $Id: ypxfr_extern.h,v 1.7 1996/06/03 03:10:42 wpaul Exp $
*/
#include <sys/types.h>
#include <limits.h>
#include <db.h>
#include <paths.h>
#include <db.h>
extern HASHINFO openinfo;
extern BTREEINFO openinfo_b;
#ifndef _PATH_YP
#define _PATH_YP "/var/yp/"
@ -42,16 +45,17 @@
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 DB *yp_open_db_rw __P(( const char *, const char *, const int));
extern void yp_init_dbs __P(( void ));
extern int yp_put_record __P(( DB *, DBT *, DBT * , int ));
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 ypxfrd_get_map __P(( char *, char *, char *, char *));
extern int callrpc __P(( char *, int, int, int, xdrproc_t, char *, xdrproc_t, char *));

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ypxfr_getmap.c,v 1.7 1996/02/03 23:09:28 wpaul Exp $
* $Id: ypxfr_getmap.c,v 1.8 1996/06/02 05:12:24 wpaul Exp $
*/
#include <stdio.h>
#include <sys/types.h>
@ -40,7 +40,7 @@
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_getmap.c,v 1.7 1996/02/03 23:09:28 wpaul Exp $";
static const char rcsid[] = "$Id: ypxfr_getmap.c,v 1.8 1996/06/02 05:12:24 wpaul Exp $";
#endif
extern bool_t xdr_ypresp_all_seq __P(( XDR *, unsigned long * ));
@ -75,7 +75,8 @@ int ypxfr_get_map(map, domain, host, callback)
/* 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_error("%s", clnt_spcreateerror("failed to \
create tcp handle"));
yp_errno = YPXFR_YPERR;
return(1);
}

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ypxfr_main.c,v 1.15 1996/01/10 17:41:55 wpaul Exp $
* $Id: ypxfr_main.c,v 1.17 1996/06/03 03:11:39 wpaul Exp $
*/
#include <stdio.h>
#include <stdlib.h>
@ -47,10 +47,11 @@
#include <rpcsvc/yp.h>
struct dom_binding {};
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/ypxfrd.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_main.c,v 1.15 1996/01/10 17:41:55 wpaul Exp $";
static const char rcsid[] = "$Id: ypxfr_main.c,v 1.17 1996/06/03 03:11:39 wpaul Exp $";
#endif
char *progname = "ypxfr";
@ -86,7 +87,8 @@ static void ypxfr_exit(retval, temp)
if ((clnt = clntudp_create(&ypxfr_callback_addr, ypxfr_prognum,
1, timeout, &sock)) == NULL) {
yp_error("%s", clnt_spcreateerror("failed to establish callback handle"));
yp_error("%s", clnt_spcreateerror("failed to \
establish callback handle"));
exit(1);
}
@ -136,7 +138,7 @@ int ypxfr_foreach(status, key, keylen, val, vallen, data)
dbval.data = val;
dbval.size = vallen;
if (yp_put_record(dbp, &dbkey, &dbval) != YP_TRUE)
if (yp_put_record(dbp, &dbkey, &dbval, 0) != YP_TRUE)
return(yp_errno);
return (0);
@ -374,8 +376,16 @@ the local domain name isn't set");
snprintf(ypxfr_temp_map, sizeof(ypxfr_temp_map), "%s/%s/%s", yp_dir,
ypxfr_dest_domain, tempmap);
if (getrpcport(ypxfr_master, YPXFRD_FREEBSD_PROG,
YPXFRD_FREEBSD_VERS, IPPROTO_TCP)) {
/* Try to send using ypxfrd. If it fails, use old method. */
if (!ypxfrd_get_map(ypxfr_master, ypxfr_mapname,
ypxfr_source_domain, ypxfr_temp_map))
goto leave;
}
/* Open the temporary map read/write. */
if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap)) == NULL) {
if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap, 0)) == NULL) {
yp_error("failed to open temporary map file");
ypxfr_exit(YPXFR_DBM,NULL);
}
@ -389,7 +399,7 @@ the local domain name isn't set");
data.data = buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
yp_error("failed to write order number to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
@ -399,7 +409,7 @@ the local domain name isn't set");
data.data = ypxfr_master;
data.size = strlen(ypxfr_master);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
yp_error("failed to write master name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
@ -409,7 +419,7 @@ the local domain name isn't set");
data.data = ypxfr_dest_domain;
data.size = strlen(ypxfr_dest_domain);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
yp_error("failed to write domain name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
@ -421,7 +431,7 @@ the local domain name isn't set");
data.data = &buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
yp_error("failed to write input name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
@ -435,7 +445,7 @@ the local domain name isn't set");
data.data = &buf;
data.size = strlen(buf);
if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
if (yp_put_record(dbp, &key, &data, 0) != YP_TRUE) {
yp_error("failed to write output name to database");
ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
}
@ -451,6 +461,11 @@ the local domain name isn't set");
(void)(dbp->close)(dbp);
dbp = NULL; /* <- yes, it seems this is necessary. */
leave:
snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
ypxfr_mapname);
/* Peek at the order number again and check for skew. */
if ((ypxfr_skew_check = ypxfr_get_order(ypxfr_source_domain,
ypxfr_mapname,
@ -466,8 +481,6 @@ the local domain name isn't set");
/*
* 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;

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ypxfr_misc.c,v 1.2 1996/02/04 05:18:44 wpaul Exp $
* $Id: ypxfr_misc.c,v 1.8 1996/06/02 05:12:00 wpaul Exp $
*/
#include <stdlib.h>
#include <unistd.h>
@ -41,7 +41,7 @@ struct dom_binding {};
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfr_misc.c,v 1.2 1996/02/04 05:18:44 wpaul Exp $";
static const char rcsid[] = "$Id: ypxfr_misc.c,v 1.8 1996/06/02 05:12:00 wpaul Exp $";
#endif
char *ypxfrerr_string(code)
@ -188,7 +188,7 @@ failed"));
return(NULL);
}
snprintf(mastername, sizeof(mastername), "%s", resp->peer);
/* xdr_free(xdr_ypresp_master, (char *)&resp); */
/* xdr_free(xdr_ypresp_master, (char *)&resp); */
return((char *)&mastername);
}
}

View File

@ -0,0 +1,130 @@
/*
* 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.
*
* $Id: ypxfrd_getmap.c,v 1.7 1996/06/02 19:51:33 wpaul Exp $
*/
#include <sys/types.h>
#include <time.h>
#include <rpcsvc/ypxfrd.h>
#include <rpcsvc/yp.h>
#include <rpc/rpc.h>
#include <sys/uio.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypxfrd_getmap.c,v 1.7 1996/06/02 19:51:33 wpaul Exp $";
#endif
int fp = 0;
static bool_t xdr_my_xfr(register XDR *xdrs, xfr *objp)
{
while(1) {
if (!xdr_xfr(xdrs, objp))
return(FALSE);
if (objp->ok == TRUE) {
if (write(fp, objp->xfr_u.xfrblock_buf.xfrblock_buf_val,
objp->xfr_u.xfrblock_buf.xfrblock_buf_len) == -1) {
yp_error("write failed: %s", strerror(errno));
return(FALSE);
}
}
xdr_free(xdr_xfr, (char *)objp);
if (objp->ok == FALSE) {
switch(objp->xfr_u.xfrstat) {
case(XFR_DONE):
return(TRUE);
break;
case(XFR_READ_ERR):
yp_error("got read error from rpc.ypxfrd");
return(FALSE);
break;
case(XFR_ACCESS):
yp_error("rpc.ypxfrd couldn't access the map");
return(FALSE);
break;
case(XFR_DENIED):
yp_error("access to map denied by rpc.ypxfrd");
return(FALSE);
break;
default:
yp_error("got unknown status from rpc.ypxfrd");
return(FALSE);
break;
}
}
}
}
#define PERM_SECURE (S_IRUSR|S_IWUSR)
int ypxfrd_get_map(host, map, domain, tmpname)
char *host;
char *map;
char *domain;
char *tmpname;
{
CLIENT *clnt;
struct ypxfr_mapname req;
struct xfr resp;
struct timeval timeout = { 0, 25 };
int status = 0;
req.xfrmap = map;
req.xfrdomain = domain;
bzero((char *)&resp, sizeof(resp));
if ((clnt = clnt_create(host, YPXFRD_FREEBSD_PROG,
YPXFRD_FREEBSD_VERS, "tcp")) == NULL) {
return(1);
}
if ((fp = open(tmpname, O_RDWR|O_CREAT, PERM_SECURE)) == -1) {
clnt_destroy(clnt);
yp_error("couldn't open %s: %s", tmpname, strerror(errno));
return(1);
}
if (clnt_call(clnt,YPXFRD_GETMAP,xdr_ypxfr_mapname,(char *)&req,
xdr_my_xfr, (char *)&resp, timeout) != RPC_SUCCESS) {
yp_error("%s", clnt_sperror(clnt,"call to rpc.ypxfrd failed"));
status++;
unlink(tmpname);
}
clnt_destroy(clnt);
close(fp);
return(status);
}